MySQL的视图

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL的视图相关的知识,希望对你有一定的参考价值。

   mysql同其它数据库一样都有视图-VIEW,VIEW并不是真实存在的表,它其实是通过SELECT查询出来的投影(结果)来当成表来查询,在VIEW中存储的其实都是事先写好的SELECT语句,这样在平时就可以直接查询VIEW中的内容而查询到相应数据,在这里就用简单的2张表来演示下,建表的SQL如下附件,而在MySQL中创建删除VIEW也很简单:

创建:
     CREATE VIEW 视图名 AS SELECT语句
修改:
      ALTER VIEW 视图名 AS SELECT语句
删除:
      DROP VIEW 视图名

而在MySQL中创建好的视图是当成MySQL中没有任何属性的表存在于数据库中Comment信息是VIEW的表,可以通过查看表的状态信息得知,创建好的VIEW物理文件则是在datadir下的数据文件夹中仅有一个MyISAM引擎的表结构文件,类似于MySQL的性能信息库performance_schema一样,其实performance_schema就是视图

mysql> SHOW TABLES;
mysql> SHOW TABLE STATUS\G

技术分享

总的来说VIEW一般用于以下几个场景中:

    1、简化子查询

在经常查询SQL中有子查询,如:

mysql> use my_test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> SELECT
    ->     *
    -> FROM
    ->     (
    ->         SELECT
    ->             *
    ->         FROM
    ->             book_tbl t
    ->         WHERE
    ->             t.storage_date REGEXP ‘^2017.*$‘
    ->     ) tmp
    -> WHERE
    ->     tmp.book_name REGEXP ‘^C‘;
+---------+-----------+--------------+
| book_id | book_name | storage_date |
+---------+-----------+--------------+
|       5 | C         | 2017-04-05   |
+---------+-----------+--------------+
1 row in set (0.00 sec)

在这种情况下就可以创建视图,平时只要直接查询视图即可获取到数据

CREATE VIEW v_book_c_2017 AS SELECT
    *
FROM
    (
        SELECT
            *
        FROM
            book_tbl t
        WHERE
            t.storage_date REGEXP ‘^2017.*$‘
    ) tmp
WHERE
    tmp.book_name REGEXP ‘^C‘;
#建议用客户端工具中写SQL创建
mysql> SELECT * FROM v_book_c_2017;
+---------+-----------+--------------+
| book_id | book_name | storage_date |
+---------+-----------+--------------+
|       5 | C         | 2017-04-05   |
+---------+-----------+--------------+
1 row in set (0.01 sec)

    2、表的权限控制

如果一张重要的信息表,如用户表在某一些MySQL用户下不能让其看到所有字段信息时也可以使用视图,当然直接使用GRANTS授权相应字段也可以,但是这样用户在DESCRIBE tablename时还是可以看见表结构的,所以使用GRANTS授权相应字段也不是真正不泄露相应表结构信息的,此时就可以创建VIEW后直接把VIEW授权给用户即可,还是刚才book_tbl表的例子,某个用户仅能查询book_tbl前2个字段内的信息表时,创建相应的VIEW时:

mysql> CREATE VIEW v_book_name AS SELECT
    -> t.book_id,
    -> t.book_name
    -> FROM
    -> book_tbl t;
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT * FROM v_book_name;
+---------+-----------+
| book_id | book_name |
+---------+-----------+
|       1 | php       |
|       2 | MySQL     |
|       3 | Java      |
|       4 | Python    |
|       5 | C         |
|       6 | Shell     |
+---------+-----------+
6 rows in set (0.00 sec)

    3、大数据表分表

在一张数据量极大的表中平时有大量的查询部分信息,此时在创建VIEW的时候写好SELECT的查询条件后,创建的VIEW就可以当成分表来查询使用,这样就可以不加条件SELECT * FROM 视图名 查询相应的数据信息,如在book_tbl表中需要查询2017年入库的图书信息,即可以以下方式创建VIEW:

mysql> CREATE VIEW v_book_2017 AS SELECT
    -> *
    -> FROM
    -> book_tbl t
    -> WHERE
    -> t.storage_date REGEXP ‘^2017.*$‘;
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT * FROM v_book_2017;
+---------+-----------+--------------+
| book_id | book_name | storage_date |
+---------+-----------+--------------+
|       1 | PHP       | 2017-04-12   |
|       2 | MySQL     | 2017-04-12   |
|       5 | C         | 2017-04-05   |
|       6 | Shell     | 2017-09-03   |
+---------+-----------+--------------+
4 rows in set (0.00 sec)

    4、查询多张表关联信息

在平时的时候需要经常查询多张表的聚合信息时就可以创建好VIEW已简化平时写的大量SQL,这样多张表的聚合或者是关联信息就可以当成表来查询,从而可以简化相应的建立工作,如在book_tbl表和book_price表中找出已经有价格上市的书籍,如下:

mysql> CREATE VIEW v_listed_book AS SELECT
    -> a.book_id,
    -> a.book_name,
    -> b.book_price
    -> FROM
    -> book_tbl a
    -> JOIN book_price b ON a.book_name = b.book_name;
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT * FROM v_listed_book;
+---------+-----------+------------+
| book_id | book_name | book_price |
+---------+-----------+------------+
|       1 | PHP       |     10.000 |
|       2 | MySQL     |     22.000 |
|       3 | Java      |      9.500 |
|       6 | Shell     |     20.000 |
+---------+-----------+------------+
4 rows in set (0.00 sec)

当然在使用MySQL的VIEW的过程中需要注意的几点是:一、MySQL自身并不是很擅长子查询,在MySQL做子查询查询时,需要对子查询启别名当成临时表来查询,在Oracle或者SqlServer中因为有另行封装开发过是不需要的,这一点比较重要,不然在MySQL的子查询或报1093错误;二、MySQL无法做到真正的物化视图,当然通过建立真实表利用触发器也可以实现,但是都不是MySQL自身就有物化视图,所以MySQL的视图也仅能用于查询,且不能写注释,而且建议平时不要使用大量的物化视图,以免导致在创建时不当反而导致性能下降且移植性降低;三、在VIEW中是可以建立视图的视图的,即在VIEW的基础上再建立VIEW,但是建议平时不要这么使用,以免当前一者VIEW因为删除导致在关联VIEW的视图失效,在日常生产环境中需要避免这样使用。四、VIEW中存储的是写好的SELECT语句,所以在视图中查出来的数据都是真实表的投影数据,当VIEW关联的真实表发生改变则VIEW的数据也会改变,且当真实表改名或者删除时VIEW也会失效,所以在使用视图VIEW时需要在日常真实表改变时修改或删除。

本文出自 “Jim的技术随笔” 博客,谢绝转载!

以上是关于MySQL的视图的主要内容,如果未能解决你的问题,请参考以下文章

从mysql的片段中加载ListView

回收站视图未显示在片段中

如何从片段内的列表视图打开链接网址?

如何使列表视图出现在片段中?

如何从活动中更改片段中视图的可见性

片段中的网格视图