目录
什么是视图
视图是在数据库中定义的虚拟表。它是一个基于一个或多个实际表的查询结果集,可以像实际表一样被查询和操作。视图可以看作是一个动态生成的数据表,其内容是从其他表中选择、过滤和计算得到的。
视图通过使用SQL查询语句来定义,这些查询语句可以包括与一个或多个表的连接、条件过滤、列计算、聚合函数等操作。在视图定义中,我们可以指定要在视图中包含的列和行,以及对这些列进行何种计算和处理。
视图用途
- 简化复杂查询:通过将复杂的查询逻辑封装到视图中,可以简化应用程序中的查询操作。
- 数据安全性:视图可以限制用户对底层表的访问权限,从而提供更高的数据安全性和隐私保护。
- 数据抽象和封装:通过视图,可以将多个表的数据抽象为一个虚拟表,简化数据模型和应用程序开发。
- 性能优化:视图可以预先计算和存储结果集,以提高查询性能,并避免重复执行复杂查询。
视图的优点
数据的抽象和简化:视图是一个虚拟表,它可以根据特定的查询语句从一个或多个表中选择、过滤和计算数据。通过使用视图,可以将复杂的查询逻辑和多表连接操作封装为一个简化的视图查询,提供了更简洁、更易于理解的数据模型。
数据安全性:视图可以限制用户对底层表的访问权限。通过给用户授予对视图的访问权限,可以隐藏底层表的结构和敏感数据,只允许用户在特定条件下查看和操作数据。这为数据库提供了更高的安全性和数据保护。
逻辑数据分离和模块化:通过视图,可以将数据逻辑分离为不同的模块。这使得数据库的维护和管理更加灵活,可以根据需要对各个模块进行独立的修改和优化,而无需影响其他模块。
提高查询性能:视图可以预先计算和存储查询结果,从而提高查询性能。当使用视图进行查询时,MySQL 可以利用预先计算的结果,而不需要重新执行复杂的查询操作。这对于频繁执行相同查询的场景非常有用。
简化应用开发:通过将复杂的查询逻辑封装为视图,应用程序开发人员可以更快速、更轻松地构建应用程序。他们只需要简单地查询视图,而无需关心视图背后的复杂查询逻辑和表结构。
视图缺点
性能影响:视图查询可能在执行时产生额外的性能开销。因为视图是根据查询语句动态生成的,每次查询时都需要重新计算视图的结果。对于复杂的视图和大型数据集,这可能导致查询较慢,影响数据库性能。
更新限制:默认情况下,MySQL 不允许对包含特定条件的视图进行更新操作。这些条件包括使用聚合函数、DISTINCT、GROUP BY 和 HAVING 等的视图。因此,如果你使用的视图有这些限制条件,你将无法对其进行直接的插入、更新或删除操作。
数据一致性:视图查询的结果是根据底层表的数据动态生成的,而不是存储实际的数据副本。这意味着如果底层表的数据发生了变化,但视图查询结果没有及时更新,可能导致数据一致性的问题。
限制和复杂性:视图的使用是受到一些限制的,特别是在涉及复杂的查询和多表连接时。一些复杂的查询逻辑和操作可能无法在视图中实现,这可能需要使用其他技术或重新设计查询。
管理复杂性:随着数据库中视图的数量增加,管理和维护视图变得更加困难。复杂的视图层次结构和依赖关系可能会导致维护和调试问题的增加
创建视图
Create [or replace 替换 ] [algroithm 视图选择的算法 ={undefined|merge |temptable}] view 视图名 [(column_list)] as select_statement [with[cascaded|local]check option]
[algroithm 视图选择的算法 ={undefined|merge |temptable}] Undefined :不常用。 merge :表示将使用 的视图语句与视图定义合并起来,使视图定义的某一部分取代语句对应的部分 temptable :表示将视图 的结果存入临时表,然后用临时表来执行语句
with[cascaded|local] Cascaded :默认为cascaded,表示更新视图时,满足所有相关视图和表的条件
Local :表示更新视图时,满足该视图本身定义的条件即可
创建单表视图
mysql> create table t(quantity int, price int);
Query OK, 0 rows affected (0.02 sec)
mysql> insert into t values (3,50);
Query OK, 1 row affected (0.04 sec)
mysql> create view view_t as select quantity,price,quantity*price from t;
Query OK, 0 rows affected (0.00 sec)
查看
mysql> select * from view_t;
+----------+-------+----------------+
| quantity | price | quantity*price |
+----------+-------+----------------+
| 3 | 50 | 150 |
+----------+-------+----------------+
1 row in set (0.00 sec)
mysql> CREATE VIEW view_t2(qty,price,total) AS SELECT quantity,price,quantity*price FROM t;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from view_t2;
+------+-------+-------+
| qty | price | total |
+------+-------+-------+
| 3 | 50 | 150 |
+------+-------+-------+
1 row in set (0.00 sec)
创建多表视图
mysql> create table student
-> (
-> s_id int(3) primary key,
-> s_name varchar(30),
-> s_age int(3),
-> s_sex varchar(8)
-> );
Query OK, 0 rows affected (0.00 sec)
mysql> create table stu_info
-> (
-> s_id int(3),
-> class varchar(50),
-> addr varchar(100)
-> );
Query OK, 0 rows affected (0.01 sec)
mysql> insert into stu_info
-> (s_id,class,addr)
-> values
-> (1,'erban','anhui'),
-> (2,'sanban','chongqing'),
-> (3,'yiban','shandong');
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> CREATE VIEW stu_class(id,name,class) AS SELECT
-> student.s_id,student.s_name,stu_info.class
-> from student,stu_info WHERE student.s_id=stu_info.s_id;
Query OK, 0 rows affected (0.00 sec)
查看视图
Describe 视图名
mysql> desc stu_class;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(3) | NO | | NULL | |
| name | varchar(30) | YES | | NULL | |
| class | varchar(50) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
基本信息
Show table status like ‘视图名’\G;
mysql> show table status like 'stu_class'\G
*************************** 1. row ***************************
Name: stu_class
Engine: NULL
Version: NULL
Row_format: NULL
Rows: NULL
Avg_row_length: NULL
Data_length: NULL
Max_data_length: NULL
Index_length: NULL
Data_free: NULL
Auto_increment: NULL
Create_time: NULL
Update_time: NULL
Check_time: NULL
Collation: NULL
Checksum: NULL
Create_options: NULL
Comment: VIEW
1 row in set (0.00 sec)
详细信息
Show create view 视图名;或show create view 视图名\G
mysql> SHOW CREATE VIEW view_t\G
*************************** 1. row ***************************
View: view_t
Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `view_t` AS select `t`.`quantity` AS `quantity`,`t`.`price` AS `price`,(`t`.`quantity` * `t`.`price`) AS `quantity*price` from `t`
character_set_client: utf8
collation_connection: utf8_general_ci
1 row in set (0.00 sec)
mysql>
views查询
在mysql 中, information schema 数据库下的 views 表中存储了所有视图的定义。通过对 views 表的查询,可以查 看数据库中所有视图的详细信息。
mysql> select * from information_schema.views\G
*************************** 1. row ***************************
TABLE_CATALOG: def
TABLE_SCHEMA: li
TABLE_NAME: stu_class
VIEW_DEFINITION: select `li`.`student`.`s_id` AS `id`,`li`.`student`.`s_name` AS `name`,`li`.`stu_info`.`class` AS `class` from `li`.`student` join `li`.`stu_info` where (`li`.`student`.`s_id` = `li`.`stu_info`.`s_id`)
CHECK_OPTION: NONE
IS_UPDATABLE: YES
DEFINER: root@localhost
SECURITY_TYPE: DEFINER
CHARACTER_SET_CLIENT: utf8
COLLATION_CONNECTION: utf8_general_ci
*************************** 2. row ***************************
TABLE_CATALOG: def
TABLE_SCHEMA: li
TABLE_NAME: view_t
VIEW_DEFINITION: select `li`.`t`.`quantity` AS `quantity`,`li`.`t`.`price` AS `price`,(`li`.`t`.`quantity` * `li`.`t`.`price`) AS `quantity*price` from `li`.`t`
CHECK_OPTION: NONE
IS_UPDATABLE: YES
DEFINER: root@localhost
SECURITY_TYPE: DEFINER
CHARACTER_SET_CLIENT: utf8
COLLATION_CONNECTION: utf8_general_ci
*************************** 3. row ***************************
TABLE_CATALOG: def
TABLE_SCHEMA: li
TABLE_NAME: view_t2
VIEW_DEFINITION: select `li`.`t`.`quantity` AS `qty`,`li`.`t`.`price` AS `price`,(`li`.`t`.`quantity` * `li`.`t`.`price`) AS `total` from `li`.`t`
CHECK_OPTION: NONE
IS_UPDATABLE: YES
DEFINER: root@localhost
SECURITY_TYPE: DEFINER
CHARACTER_SET_CLIENT: utf8
COLLATION_CONNECTION: utf8_general_ci
*************************** 4. row ***************************
TABLE_CATALOG: def
TABLE_SCHEMA: sys
TABLE_NAME: host_summary
VIEW_DEFINITION: select if(isnull(`performance_schema`.`accounts`.`HOST`),'background',`performance_schema`.`accounts`.`HOST`) AS `host`,sum(`stmt`.`total`) AS `statements`,`sys`.`format_time`(sum(`stmt`.`total_latency`)) AS `statement_latency`,`sys`.`format_time`(ifnull((sum(`stmt`.`total_latency`) / nullif(sum(`stmt`.`total`),0)),0)) AS `statement_avg_latency`,sum(`stmt`.`full_scans`) AS `table_scans`,sum(`io`.`ios`) AS `file_ios`,`sys`.`format_time`(sum(`io`.`io_latency`)) AS `file_io_latency`,sum(`performance_schema`.`accounts`.`CURRENT_CONNECTIONS`) AS `current_connections`,sum(`performance_schema`.`accounts`.`TOTAL_CONNECTIONS`) AS `total_connections`,count(distinct `performance_schema`.`accounts`.`USER`) AS `unique_users`,`sys`.`format_bytes`(sum(`mem`.`current_allocated`)) AS `current_memory`,`sys`.`format_bytes`(sum(`mem`.`total_allocated`)) AS `total_memory_allocated` from (((`performance_schema`.`accounts` join `sys`.`x$host_summary_by_statement_latency` `stmt` on((`performance_schema`.`accounts`.`HOST` = `stmt`.`host`))) join `sys`.`x$host_summary_by_file_io` `io` on((`performance_schema`.`accounts`.`HOST` = `io`.`host`))) join `sys`.`x$memory_by_host_by_current_bytes` `mem` on((`performance_schema`.`accounts`.`HOST` = `mem`.`host`))) group by if(isnull(`performance_schema`.`accounts`.`HOST`),'background',`performance_schema`.`accounts`.`HOST`)
CHECK_OPTION: NONE
IS_UPDATABLE: NO
DEFINER: mysql.sys@localhost
SECURITY_TYPE: INVOKER
CHARACTER_SET_CLIENT: utf8
COLLATION_CONNECTION: utf8_general_ci
*************************** 5. row ***************************
TABLE_CATALOG: def
TABLE_SCHEMA: sys
TABLE_NAME: host_summary_by_file_io
VIEW_DEFINITION: select if(isnull(`performance_schema`.`events_waits_summary_by_host_by_event_name`.`HOST`),'background',`performance_schema`.`events_waits_summary_by_host_by_event_name`.`HOST`) AS `host`,sum(`performance_schema`.`events_waits_summary_by_host_by_event_name`.`COUNT_STAR`) AS `ios`,`sys`.`format_time`(sum(`performance_schema`.`events_waits_summary_by_host_by_event_name`.`SUM_TIMER_WAIT`)) AS `io_latency` from `performance_schema`.`events_waits_summary_by_host_by_event_name` where (`performance_schema`.`events_waits_summary_by_host_by_event_name`.`EVENT_NAME` like 'wait/io/file/%') group by if(isnull(`performance_schema`.`events_waits_summary_by_host_by_event_name`.`HOST`),'background',`performance_schema`.`events_waits_summary_by_host_by_event_name`.`HOST`) order by sum(`performance_schema`.`events_waits_summary_by_host_by_event_name`.`SUM_TIMER_WAIT`) desc
CHECK_OPTION: NONE
IS_UPDATABLE: NO
DEFINER: mysql.sys@localhost
SECURITY_TYPE: INVOKER
CHARACTER_SET_CLIENT: utf8
COLLATION_CONNECTION: utf8_general_ci
*************************** 6. row ***************************
TABLE_CATALOG: def
修改视图
Create or replace view
mysql> CREATE OR REPLACE VIEW view_t AS SELECT * FROM t;
Query OK, 0 rows affected (0.00 sec)
mysql> DESC view_t;
+----------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+-------+
| quantity | int(11) | YES | | NULL | |
| price | int(11) | YES | | NULL | |
+----------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)
Alter 修改视图
mysql> ALTER VIEW view_t AS SELECT quantity FROM t ;
Query OK, 0 rows affected (0.01 sec)
mysql> DESC view_t;
+----------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+-------+
| quantity | int(11) | YES | | NULL | |
+----------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)
更新视图
mysql> select * from t;
+----------+-------+
| quantity | price |
+----------+-------+
| 3 | 50 |
+----------+-------+
1 row in set (0.00 sec)
mysql> select * from view_t;
+----------+
| quantity |
+----------+
| 3 |
+----------+
1 row in set (0.01 sec)
mysql> UPDATE view_t SET quantity=5;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from view_t;
+----------+
| quantity |
+----------+
| 5 |
+----------+
1 row in set (0.00 sec)
mysql> select * from t;
+----------+-------+
| quantity | price |
+----------+-------+
| 5 | 50 |
+----------+-------+
1 row in set (0.00 sec)
mysql> INSERT INTO t VALUES(3,5);
Query OK, 1 row affected (0.01 sec)
mysql> select * from t;
+----------+-------+
| quantity | price |
+----------+-------+
| 5 | 50 |
| 3 | 5 |
+----------+-------+
2 rows in set (0.00 sec)
mysql> select * from view_t2;
+------+-------+-------+
| qty | price | total |
+------+-------+-------+
| 5 | 50 | 250 |
| 3 | 5 | 15 |
+------+-------+-------+
2 rows in set (0.00 sec)
mysql> select * from view_t2;
+------+-------+-------+
| qty | price | total |
+------+-------+-------+
| 5 | 50 | 250 |
| 3 | 5 | 15 |
+------+-------+-------+
2 rows in set (0.00 sec)
mysql> DELETE FROM view_t2 WHERE price=5;
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM view_t2;
+------+-------+-------+
| qty | price | total |
+------+-------+-------+
| 5 | 50 | 250 |
+------+-------+-------+
1 row in set (0.00 sec)
mysql>
视图存在一下情况时,更新操作无法执行 1 视图中不包含基表中被定义为非空的列 2 在定义视图的 select 语句后 的字段列表中使用了数学表达式 3 在定义视图的 select 语句后字段列表中使用了聚合函数时不接受更新操作 4select中,使用了 union \top \group by 或 having 无法接受
删除视图
Drop view [IF EXISTS]视图名1,视图名2 ……
mysql> DROP VIEW IF EXISTS stu_class;
Query OK, 0 rows affected (0.00 sec)
mysql> DROP VIEW IF EXISTS stu_class;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> show warnings;
+-------+------+------------------------------+
| Level | Code | Message |
+-------+------+------------------------------+
| Note | 1051 | Unknown table 'li.stu_class' |
+-------+------+------------------------------+
1 row in set (0.00 sec)
mysql> SHOW CREATE VIEW stu_class;
ERROR 1146 (42S02): Table 'li.stu_class' doesn't exist
mysql>