本教學通過範例和清楚的說明幫助,了解WITH CHECK OPTION
子句中LOCAL
和CASCADED
之間的差異。
在進行本教學之前,應該熟悉WITH CHECK OPTION
子句。如果不是這樣,可以參閱WITH CHECK OPTION子句教學來遵循確保檢視的一致性。
當使用WITH CHECK OPTION
子句建立檢視時,MySQL會通過檢視檢查正在更改的每個行,例如插入,更新,刪除,以使其符合檢視的定義。因為MySQL允許基於另一個檢視建立檢視,它還會檢查依賴檢視中的規則以保持一致性。
為了確定檢查的範圍,MySQL提供了兩個選項:LOCAL
和CASCADED
。如果您沒有在WITH CHECK OPTION
子句中顯式指定關鍵字,則MySQL預設使用CASCADED
。
要了解使用CASCADED CHECK OPTION
的效果,請參閱下面的例子。
首先,建立一個名為t1
的表,其中只有一個名稱為:c
的列,它的資料型別為int
。
USE testdb;
CREATE TABLE t1 (
c INT
);
接下來,基於t1
表建立一個名為v1
的檢視,以選擇值大於10
的行記錄。
CREATE OR REPLACE VIEW v1
AS
SELECT
c
FROM
t1
WHERE
c > 10;
因為沒有指定WITH CHECK OPTION
,所以以下語句即使不符合v1
檢視的定義也可以工作。
INSERT INTO v1(c) VALUES (5);
然後,基於v1
檢視建立v2
檢視。在v2
檢視中新增一個WITH CASCADED CHECK OPTION
子句。
CREATE OR REPLACE VIEW v2
AS
SELECT
c
FROM
v1
WITH CASCADED CHECK OPTION;
現在,通過v2
檢視在t1
表中插入一個值為5
的行。
INSERT INTO v2(c) VALUES (5);
MySQL發出以下錯誤訊息:
Error Code: 1369. CHECK OPTION failed 'testdb.v2'
它失敗了,因為它建立一個不符合v2
檢視定義的新行。
之後,我們再建立一個基於v2
的名為v3
的新檢視。
CREATE OR REPLACE VIEW v3
AS
SELECT
c
FROM
v2
WHERE
c < 20;
我們通過v3
檢視插入一個新行到t1
表中,值為8
。
INSERT INTO v3(c) VALUES (8);
MySQL發出以下錯誤資訊:
Error Code: 1369. CHECK OPTION failed 'testdb.v3'
上面插入語句看起來符合v3
檢視的定義,insert語句仍然執行失敗。
這是為什麼呢?
因為v3
檢視取決於v2
檢視,v2
檢視具有WITH CASCADED CHECK OPTION
。
但是,以下插入語句能正常工作。
INSERT INTO v3(c) VALUES (30);
因為v3
檢視沒有使用WITH CHECK OPTION
定義,並且該語句符合v2
檢視的定義。
所以,總而言之:
當檢視使用WITH CASCADED CHECK OPTION
時,MySQL會迴圈檢查檢視的規則以及底層檢視的規則。
下面將演示使用 WITH LOCAL CHECK OPTION
選項,使用上面相同的範例來檢視差異。
首先,將v2
檢視更改為使用WITH LOCAL CHECK OPTIONS
替代。
ALTER VIEW v2 AS
SELECT
c
FROM
v1
WITH LOCAL CHECK OPTION;
其次,插入與上述範例相同的行。
INSERT INTO v2(c) VALUES (5);
它是可以成功執行的。
因為v2
檢視沒有任何規則。 v2
檢視取決於v1
檢視。 但是,v1
檢視沒有指定檢查選項,因此MySQL跳過檢查v1
檢視中的規則。
請注意,在使用
WITH CASCADED CHECK OPTION
建立的v2
檢視中,此語句失敗。
第三,通過v3
檢視將相同的行插入t1
表。
INSERT INTO v3(c) VALUES (8);
在這種情況下可以執行成功,因為MySQL檢視中的WITH LOCAL CHECK OPTIONS
選項沒有檢查v1
檢視的規則。
另外,請注意,在使用WITH CASCADED CHECK OPTION
建立的v2
檢視範例中,此語句執行失敗。
因此,如果檢視使用WITH LOCAL CHECK OPTION
,MySQL會檢查WITH LOCAL CHECK OPTION
和WITH CASCADED CHECK OPTION
選項的檢視規則。
與使用WITH CASCADED CHECK OPTION
的檢視不同,MySQL檢查所有依賴檢視的規則。
請注意,在MySQL 5.7.6之前,如果您使用帶有
WITH LOCAL CHECK OPTION
的檢視,MySQL只會檢查當前檢視的規則,並且不會檢查底層檢視的規則。