針對產生式欄位,允許的 ALTER TABLE
操作有 ADD
、MODIFY
和 CHANGE
。
可以新增產生式欄位。
CREATE TABLE t1 (c1 INT); ALTER TABLE t1 ADD COLUMN c2 INT GENERATED ALWAYS AS (c1 + 1) STORED;
可以修改產生式欄位的資料類型和運算式。
CREATE TABLE t1 (c1 INT, c2 INT GENERATED ALWAYS AS (c1 + 1) STORED); ALTER TABLE t1 MODIFY COLUMN c2 TINYINT GENERATED ALWAYS AS (c1 + 5) STORED;
可以重新命名或刪除產生式欄位,前提是沒有其他欄位參考它們。
CREATE TABLE t1 (c1 INT, c2 INT GENERATED ALWAYS AS (c1 + 1) STORED); ALTER TABLE t1 CHANGE c2 c3 INT GENERATED ALWAYS AS (c1 + 1) STORED; ALTER TABLE t1 DROP COLUMN c3;
虛擬產生式欄位無法變更為儲存產生式欄位,反之亦然。要解決這個問題,請先刪除該欄位,然後使用新的定義新增它。
CREATE TABLE t1 (c1 INT, c2 INT GENERATED ALWAYS AS (c1 + 1) VIRTUAL); ALTER TABLE t1 DROP COLUMN c2; ALTER TABLE t1 ADD COLUMN c2 INT GENERATED ALWAYS AS (c1 + 1) STORED;
非產生式欄位可以變更為儲存產生式欄位,但不能變更為虛擬產生式欄位。
CREATE TABLE t1 (c1 INT, c2 INT); ALTER TABLE t1 MODIFY COLUMN c2 INT GENERATED ALWAYS AS (c1 + 1) STORED;
儲存產生式欄位(而非虛擬產生式欄位)可以變更為非產生式欄位。儲存的產生值將成為非產生式欄位的值。
CREATE TABLE t1 (c1 INT, c2 INT GENERATED ALWAYS AS (c1 + 1) STORED); ALTER TABLE t1 MODIFY COLUMN c2 INT;
對於儲存欄位,
ADD COLUMN
並非就地操作(不使用暫存表格完成),因為必須由伺服器評估運算式。對於儲存欄位,索引變更會就地完成,而運算式變更則不會就地完成。欄位註解的變更會就地完成。對於非分割表格,
ADD COLUMN
和DROP COLUMN
對於虛擬欄位是就地操作。然而,新增或刪除虛擬欄位不能與其他ALTER TABLE
操作結合在一起就地執行。對於分割表格,
ADD COLUMN
和DROP COLUMN
對於虛擬欄位不是就地操作。InnoDB
支援虛擬產生式欄位的次要索引。在虛擬產生式欄位上新增或刪除次要索引是就地操作。有關更多資訊,請參閱第 15.1.20.9 節「次要索引與產生式欄位」。當
VIRTUAL
產生式欄位新增到表格或修改時,並不保證由產生式欄位運算式計算的資料沒有超出該欄位的範圍。這可能導致傳回不一致的資料,以及意外失敗的陳述式。為了允許控制是否對此類欄位進行驗證,ALTER TABLE
支援WITHOUT VALIDATION
和WITH VALIDATION
子句。使用
WITHOUT VALIDATION
(如果未指定任一子句,則為預設值),會執行就地操作(如果可能的話),不檢查資料完整性,且陳述式完成速度更快。然而,如果值超出範圍,稍後從表格讀取資料可能會針對該欄位報告警告或錯誤。使用
WITH VALIDATION
,ALTER TABLE
會複製表格。如果發生超出範圍或其他任何錯誤,則陳述式會失敗。由於執行表格複製,因此陳述式會花費較長的時間。
WITHOUT VALIDATION
和WITH VALIDATION
僅允許用於ADD COLUMN
、CHANGE COLUMN
和MODIFY COLUMN
操作。否則,會發生ER_WRONG_USAGE
錯誤。如果運算式評估導致截斷或為函數提供不正確的輸入,則
ALTER TABLE
陳述式會終止並出現錯誤,且 DDL 操作會遭到拒絕。變更欄位
col_name
的預設值的ALTER TABLE
陳述式,也可能變更使用col_name
參考該欄位的產生式欄位運算式的值,這可能會變更使用DEFAULT(
參考該欄位的產生式欄位運算式的值。因此,如果任何產生式欄位運算式使用col_name
)DEFAULT()
,則變更欄位定義的ALTER TABLE
操作會導致表格重建。