CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}] VIEW view_name [(column_list)] AS select_statement [WITH [CASCADED | LOCAL] CHECK OPTION] 該語句能建立新的檢視,如果給定了OR REPLACE子句,該語句還能替換已有的檢視。select_statement是一種SELECT語句,它給出了檢視的定義。該語句可從基表或其他檢視進行選擇。 該語句要求具有針對檢視的CREATE VIEW許可權,以及針對由SELECT語句選擇的每一列上的某些許可權。對於在SELECT語句中其他地方使用的列,必須具有SELECT許可權。如果還有OR REPLACE子句,必須在檢視上具有DROP許可權。 檢視屬於資料庫。在預設情況下,將在當前資料庫建立新檢視。要想在給定資料庫中明確建立檢視,建立時,應將名稱指定為db_name.view_name。 mysql> CREATE VIEW test.v AS SELECT * FROM t; 表和檢視共享資料庫中相同的名稱空間,因此,資料庫不能包含具有相同名稱的表和檢視。 檢視必須具有唯一的列名,不得有重複,就像基表那樣。預設情況下,由SELECT語句檢索的列名將用作檢視列名。要想為檢視列定義明確的名稱,可使用可選的column_list子句,列出由逗號隔開的ID。column_list中的名稱數目必須等於SELECT語句檢索的列數。 SELECT語句檢索的列可以是對錶列的簡單引用。也可以是使用函式、常量值、運算子等的表示式。 對於SELECT語句中不合格的表或檢視,將根據預設的資料庫進行解釋。透過用恰當的資料庫名稱限定表或檢視名,檢視能夠引用表或其他資料庫中的檢視。 能夠使用多種SELECT語句建立檢視。檢視能夠引用基表或其他檢視。它能使用聯合、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 |+------+-------+-------+ 檢視定義服從下述限制: · SELECT語句不能包含FROM子句中的子查詢。 · SELECT語句不能引用系統或使用者變數。 · SELECT語句不能引用預處理語句引數。 · 在儲存子程式內,定義不能引用子程式引數或區域性變數。 · 在定義中引用的表或檢視必須存在。但是,建立了檢視後,能夠捨棄定義引用的表或檢視。要想檢查檢視定義是否存在這類問題,可使用CHECK TABLE語句。 · 在定義中不能引用TEMPORARY表,不能建立TEMPORARY檢視。 · 在檢視定義中命名的表必須已存在。 · 不能將觸發程式與檢視關聯在一起。 在檢視定義中允許使用ORDER BY,但是,如果從特定檢視進行了選擇,而該檢視使用了具有自己ORDER BY的語句,它將被忽略。 對於定義中的其他選項或子句,它們將被增加到引用檢視的語句的選項或子句中,但效果未定義。例如,如果在檢視定義中包含LIMIT子句,而且從特定檢視進行了選擇,而該檢視使用了具有自己LIMIT子句的語句,那麼對使用哪個LIMIT未作定義。相同的原理也適用於其他選項,如跟在SELECT關鍵字後的ALL、DISTINCT或SQL_SMALL_RESULT,並適用於其他子句,如INTO、FOR UPDATE、LOCK IN SHARE MODE、以及PROCEDURE。 如果建立了檢視,並透過更改系統變數更改了查詢處理環境,會影響從檢視獲得的結果: mysql> CREATE VIEW v AS SELECT CHARSET(CHAR(65)), COLLATION(CHAR(65));Query OK, 0 rows affected (0.00 sec) mysql> SET NAMES "latin1";Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM v;+-------------------+---------------------+| CHARSET(CHAR(65)) | COLLATION(CHAR(65)) |+-------------------+---------------------+| latin1 | latin1_swedish_ci |+-------------------+---------------------+1 row in set (0.00 sec) mysql> SET NAMES "utf8";Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM v;+-------------------+---------------------+| CHARSET(CHAR(65)) | COLLATION(CHAR(65)) |+-------------------+---------------------+| utf8 | utf8_general_ci |+-------------------+---------------------+1 row in set (0.00 sec) 可選的ALGORITHM子句是對標準SQL的MySQL擴充套件。ALGORITHM可取三個值:MERGE、TEMPTABLE或UNDEFINED。如果沒有ALGORITHM子句,預設演算法是UNDEFINED(未定義的)。演算法會影響MySQL處理檢視的方式。 對於MERGE,會將引用檢視的語句的文字與檢視定義合併起來,使得檢視定義的某一部分取代語句的對應部分。 對於TEMPTABLE,檢視的結果將被置於臨時表中,然後使用它執行語句。 對於UNDEFINED,MySQL將選擇所要使用的演算法。如果可能,它傾向於MERGE而不是TEMPTABLE,這是因為MERGE通常更有效,而且如果使用了臨時表,檢視是不可更新的。 明確選擇TEMPTABLE的1個原因在於,建立臨時表之後、並在完成語句處理之前,能夠釋放基表上的鎖定。與MERGE演算法相比,鎖定釋放的速度更快,這樣,使用檢視的其他客戶端不會被遮蔽過長時間。 檢視演算法可以是UNDEFINED,有三種方式: · 在CREATE VIEW語句中沒有ALGORITHM子句。 · CREATE VIEW語句有1個顯式ALGORITHM = UNDEFINED子句。 · 為僅能用臨時表處理的檢視指定ALGORITHM = MERGE。在這種情況下,MySQL將生成告警,並將演算法設定為UNDEFINED。 正如前面所介紹的那樣,透過將檢視定義中的對應部分合併到引用檢視的語句中,對MERGE進行處理。在下面的示例中,簡要介紹了MERGE的工作方式。在該示例中,假定有1個具有下述定義的檢視v_merge: CREATE ALGORITHM = MERGE VIEW v_merge (vc1, vc2) ASSELECT c1, c2 FROM t WHERE c3 > 100; 示例1:假定發出了下述語句: SELECT * FROM v_merge; MySQL以下述方式處理語句: · v_merge成為t · *成為vc1、vc2,與c1、c2對應 · 增加檢視WHERE子句 所產生的將執行的語句為: SELECT c1, c2 FROM t WHERE c3 > 100; 示例2:假定發出了下述語句: SELECT * FROM v_merge WHERE vc1 100) AND (c1
CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}] VIEW view_name [(column_list)] AS select_statement [WITH [CASCADED | LOCAL] CHECK OPTION] 該語句能建立新的檢視,如果給定了OR REPLACE子句,該語句還能替換已有的檢視。select_statement是一種SELECT語句,它給出了檢視的定義。該語句可從基表或其他檢視進行選擇。 該語句要求具有針對檢視的CREATE VIEW許可權,以及針對由SELECT語句選擇的每一列上的某些許可權。對於在SELECT語句中其他地方使用的列,必須具有SELECT許可權。如果還有OR REPLACE子句,必須在檢視上具有DROP許可權。 檢視屬於資料庫。在預設情況下,將在當前資料庫建立新檢視。要想在給定資料庫中明確建立檢視,建立時,應將名稱指定為db_name.view_name。 mysql> CREATE VIEW test.v AS SELECT * FROM t; 表和檢視共享資料庫中相同的名稱空間,因此,資料庫不能包含具有相同名稱的表和檢視。 檢視必須具有唯一的列名,不得有重複,就像基表那樣。預設情況下,由SELECT語句檢索的列名將用作檢視列名。要想為檢視列定義明確的名稱,可使用可選的column_list子句,列出由逗號隔開的ID。column_list中的名稱數目必須等於SELECT語句檢索的列數。 SELECT語句檢索的列可以是對錶列的簡單引用。也可以是使用函式、常量值、運算子等的表示式。 對於SELECT語句中不合格的表或檢視,將根據預設的資料庫進行解釋。透過用恰當的資料庫名稱限定表或檢視名,檢視能夠引用表或其他資料庫中的檢視。 能夠使用多種SELECT語句建立檢視。檢視能夠引用基表或其他檢視。它能使用聯合、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 |+------+-------+-------+ 檢視定義服從下述限制: · SELECT語句不能包含FROM子句中的子查詢。 · SELECT語句不能引用系統或使用者變數。 · SELECT語句不能引用預處理語句引數。 · 在儲存子程式內,定義不能引用子程式引數或區域性變數。 · 在定義中引用的表或檢視必須存在。但是,建立了檢視後,能夠捨棄定義引用的表或檢視。要想檢查檢視定義是否存在這類問題,可使用CHECK TABLE語句。 · 在定義中不能引用TEMPORARY表,不能建立TEMPORARY檢視。 · 在檢視定義中命名的表必須已存在。 · 不能將觸發程式與檢視關聯在一起。 在檢視定義中允許使用ORDER BY,但是,如果從特定檢視進行了選擇,而該檢視使用了具有自己ORDER BY的語句,它將被忽略。 對於定義中的其他選項或子句,它們將被增加到引用檢視的語句的選項或子句中,但效果未定義。例如,如果在檢視定義中包含LIMIT子句,而且從特定檢視進行了選擇,而該檢視使用了具有自己LIMIT子句的語句,那麼對使用哪個LIMIT未作定義。相同的原理也適用於其他選項,如跟在SELECT關鍵字後的ALL、DISTINCT或SQL_SMALL_RESULT,並適用於其他子句,如INTO、FOR UPDATE、LOCK IN SHARE MODE、以及PROCEDURE。 如果建立了檢視,並透過更改系統變數更改了查詢處理環境,會影響從檢視獲得的結果: mysql> CREATE VIEW v AS SELECT CHARSET(CHAR(65)), COLLATION(CHAR(65));Query OK, 0 rows affected (0.00 sec) mysql> SET NAMES "latin1";Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM v;+-------------------+---------------------+| CHARSET(CHAR(65)) | COLLATION(CHAR(65)) |+-------------------+---------------------+| latin1 | latin1_swedish_ci |+-------------------+---------------------+1 row in set (0.00 sec) mysql> SET NAMES "utf8";Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM v;+-------------------+---------------------+| CHARSET(CHAR(65)) | COLLATION(CHAR(65)) |+-------------------+---------------------+| utf8 | utf8_general_ci |+-------------------+---------------------+1 row in set (0.00 sec) 可選的ALGORITHM子句是對標準SQL的MySQL擴充套件。ALGORITHM可取三個值:MERGE、TEMPTABLE或UNDEFINED。如果沒有ALGORITHM子句,預設演算法是UNDEFINED(未定義的)。演算法會影響MySQL處理檢視的方式。 對於MERGE,會將引用檢視的語句的文字與檢視定義合併起來,使得檢視定義的某一部分取代語句的對應部分。 對於TEMPTABLE,檢視的結果將被置於臨時表中,然後使用它執行語句。 對於UNDEFINED,MySQL將選擇所要使用的演算法。如果可能,它傾向於MERGE而不是TEMPTABLE,這是因為MERGE通常更有效,而且如果使用了臨時表,檢視是不可更新的。 明確選擇TEMPTABLE的1個原因在於,建立臨時表之後、並在完成語句處理之前,能夠釋放基表上的鎖定。與MERGE演算法相比,鎖定釋放的速度更快,這樣,使用檢視的其他客戶端不會被遮蔽過長時間。 檢視演算法可以是UNDEFINED,有三種方式: · 在CREATE VIEW語句中沒有ALGORITHM子句。 · CREATE VIEW語句有1個顯式ALGORITHM = UNDEFINED子句。 · 為僅能用臨時表處理的檢視指定ALGORITHM = MERGE。在這種情況下,MySQL將生成告警,並將演算法設定為UNDEFINED。 正如前面所介紹的那樣,透過將檢視定義中的對應部分合併到引用檢視的語句中,對MERGE進行處理。在下面的示例中,簡要介紹了MERGE的工作方式。在該示例中,假定有1個具有下述定義的檢視v_merge: CREATE ALGORITHM = MERGE VIEW v_merge (vc1, vc2) ASSELECT c1, c2 FROM t WHERE c3 > 100; 示例1:假定發出了下述語句: SELECT * FROM v_merge; MySQL以下述方式處理語句: · v_merge成為t · *成為vc1、vc2,與c1、c2對應 · 增加檢視WHERE子句 所產生的將執行的語句為: SELECT c1, c2 FROM t WHERE c3 > 100; 示例2:假定發出了下述語句: SELECT * FROM v_merge WHERE vc1 100) AND (c1