参数说明

参数 说明
view_name 视图的名称
SELECT statement 要打包到视图中的 SQL 语句。可以是一个或多个表的 SELECT 语句

第 24.1 节:创建视图

权限

CREATE VIEW 语句需要对视图具有 CREATE VIEW 权限,并对 SELECT 语句中选择的每一列具有某些权限。对于 SELECT 语句中其他地方使用的列,必须具有 SELECT 权限。如果存在 OR REPLACE 子句,则还必须对视图具有 DROP 权限。根据本文后面描述的 DEFINER 值,CREATE VIEW 可能还需要 SUPER 权限。

当引用视图时,会发生权限检查。

视图属于一个数据库。默认情况下,新视图在默认数据库中创建。要显式地在给定数据库中创建视图,请使用完全限定的名称:

db_name.view_name

示例:

mysql> CREATE VIEW test.v AS SELECT * FROM t;

注意:在数据库中,基表和视图共享相同的命名空间,因此基表和视图不能同名。

一个视图可以:

  • 从多种 SELECT 语句创建
  • 引用基表或其他视图
  • 使用连接(JOIN)、UNION 和子查询
  • SELECT 甚至不需要引用任何表

另一个示例

以下示例定义了一个视图,从另一个表中选择两列以及从这些列计算出的表达式:

mysql> CREATE TABLE t (qty INT, price INT);
mysql> INSERT INTO t VALUES (3, 50);
mysql> CREATE VIEW v AS SELECT qty, price, qty*price AS value FROM t;
mysql> SELECT * FROM v;

结果:

+-----+-------+-------+
| qty | price | value |
+-----+-------+-------+
|   3 |    50 |   150 |
+-----+-------+-------+

限制

  • 在 MySQL 5.7.7 之前,SELECT 语句不能在 FROM 子句中包含子查询。
  • SELECT 语句不能引用系统变量或用户定义变量。
  • 在存储程序中,SELECT 语句不能引用程序参数或局部变量。
  • SELECT 语句不能引用预处理语句参数。
  • 定义中引用的任何表或视图必须存在。创建视图后,可以删除定义引用的表或视图。在这种情况下,使用视图会导致错误。要检查视图定义是否存在此类问题,请使用 CHECK TABLE 语句。
  • 定义不能引用 TEMPORARY 表,也不能创建 TEMPORARY 视图。
  • 不能将触发器与视图关联。
  • SELECT 语句中列名的别名将根据最大列长度 64 个字符进行检查(而不是最大别名长度 256 个字符)。
  • 视图的优化效果可能不如等效的 SELECT 语句。它不太可能优化得更好。

第 24.2 节:来自两个表的视图

当视图可用于从多个表中提取数据时,它最为有用。

CREATE VIEW myview AS
SELECT a.*, b.extra_data
FROM main_table a
LEFT OUTER JOIN other_table b ON a.id = b.id;

在 MySQL 中,视图不会被物化。如果你现在执行简单的查询 SELECT * FROM myview,MySQL 实际上会在幕后执行 LEFT JOIN。

视图一旦创建,就可以与其他视图或表连接。

第 24.3 节:删除视图

在当前数据库中创建和删除视图:

CREATE VIEW few_rows_from_t1 AS SELECT * FROM t1 LIMIT 10;
DROP VIEW few_rows_from_t1;

创建和删除引用不同数据库中表的视图:

CREATE VIEW table_from_other_db AS SELECT x FROM db1.foo WHERE x IS NOT NULL;
DROP VIEW table_from_other_db;

第 24.4 节:通过视图更新表

视图的行为非常像表。虽然你可以 UPDATE 表,但你可能不一定能够更新该表上的视图。一般来说,如果视图中的 SELECT 足够复杂以至于需要临时表,则不允许 UPDATE。

诸如 GROUP BY、UNION、HAVING、DISTINCT 以及某些子查询等操作会阻止视图可更新。详细信息请参阅参考手册。