本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
ALTER TABLE APPEND
會從現有來源資料表移出資料,將資料列附加到目標資料表。來源資料表中的資料會移至目標資料表中相符的資料欄。資料欄的順序並不重要。資料成功附加至目標資料表後,來源資料表就會是空的。因為是移動而不是複製資料,ALTER TABLE APPEND 通常比類似的 CREATE TABLE AS 或 INSERT INTO 操作更快。
注意
ALTER TABLE APPEND 會在來源資料表和目標資料表之間移動資料區塊。為了提升效能,ALTER TABLE APPEND 不會在附加操作的過程中精簡儲存空間。因此,儲存空間的使用量會暫時增加。若要回收空間,請執行 VACUUM 操作。
同名的資料欄也必須有一模一樣的資料欄屬性。若來源資料表或目標資料表包含對方所沒有的資料欄,請使用 IGNOREEXTRA 或 FILLTARGET 參數指定管理額外資料欄的方式。
您無法附加身分資料欄。若兩個資料表都包含身分資料欄,命令就會失敗。若只有一個資料表擁有身分資料欄,請包含 FILLTARGET 或 IGNOREEXTRA 參數。如需詳細資訊,請參閱 ALTER TABLE APPEND 使用須知。
您可以附加 GENERATED BY DEFAULT AS IDENTITY 欄。您可以利用您提供的值,更新定義為 GENERATED BY DEFAULT AS IDENTITY 的資料欄。如需詳細資訊,請參閱 ALTER TABLE APPEND 使用須知。
目標資料表必須是永久資料表。不過,來源可以是永久資料表,也可以是為串流擷取設定的具體化視觀表。兩個物件必須使用相同的分佈樣式和分佈索引鍵 (如有定義的話)。若物件經過排序,則兩個物件必須使用相同的排序樣式,並且定義相同的資料欄做為排序索引鍵。
ALTER TABLE APPEND 命令會在操作完成時立即自動遞交。此命令無法轉返。您無法在交易區塊 (BEGIN ... END) 內執行 ALTER TABLE APPEND。如需交易的相關資訊,請參閱 可序列化隔離。
所需權限
根據 ALTER TABLE APPEND 命令的不同,使用者可能需要下列其中一項權限:
超級使用者
具 ALTER TABLE 系統權限的使用者
在來源資料表上具有 DELETE 和 SELECT 權限,以及在目標資料表上具有 INSERT 權限的使用者
語法
ALTER TABLE target_table_name APPEND FROM [ source_table_name | source_materialized_view_name ] [ IGNOREEXTRA | FILLTARGET ]
從具體化視觀表附加只有在為 串流擷取至具體化視觀表 設定具體化視觀表的情況下才有作用。
參數
- target_table_name
-
要附加資料列的資料表名稱。僅指定資料表的名稱,或使用格式 schema_name.table_name 來使用專屬結構描述。目標資料表必須是現有的永久資料表。
- FROM source_table_name
-
提供要附加之資料列的資料表名稱。僅指定資料表的名稱,或使用格式 schema_name.table_name 來使用專屬結構描述。來源資料表必須是現有的永久資料表。
- FROM source_materialized_view_name
-
提供要附加之資料列的具體化視觀表名稱。從具體化視觀表附加只有在為 串流擷取至具體化視觀表 設定具體化視觀表的情況下才有作用。來源具體化視觀表必須已存在。
- IGNOREEXTRA
-
此關鍵字會指定,若來源資料表包含了目標資料表中沒有的資料欄,則應捨棄額外資料欄中的資料。您無法搭配 FILLTARGET 使用 IGNOREEXTRA。
- FILLTARGET
-
此關鍵字會指定,若目標資料表包含了來源資料表中沒有的資料欄,則應在這些資料欄中填入 DEFAULT 資料欄值 (如有定義的話) 或 NULL。您無法搭配 FILLTARGET 使用 IGNOREEXTRA。
ALTER TABLE APPEND 使用須知
ALTER TABLE APPEND 只會移動來源資料表與目標資料表中完全相同的資料欄。資料欄的順序並不重要。
若來源資料表或目標資料表包含額外的資料欄,請根據下列規則使用 FILLTARGET 或 IGNOREEXTRA:
-
如果來源資料表包含了目標資料表中沒有的資料欄,則要包括 IGNOREEXTRA。此命令會略過來源資料表中額外的資料欄。
-
如果目標資料表包含了來源資料表中沒有的資料欄,則要包括 FILLTARGET。此命令會以預設資料欄值或 IDENTITY 值 (如有定義的話) 或 NULL 填入目標資料表中額外的資料欄。
-
如果來源資料表和目標資料表都包含額外的資料欄,則命令會失敗。您無法同時使用 FILLTARGET 和 IGNOREEXTRA。
如果兩個資料表中包含的資料欄名稱相同但屬性不同,則命令會失敗。名稱類似的資料欄必須都有下列屬性:
-
資料類型
-
資料欄大小
-
壓縮編碼
-
非 null
-
排序樣式
-
排序索引鍵資料欄
-
分佈樣式
-
分佈索引鍵資料欄
您無法附加身分資料欄。如果來源資料表和目標資料表都有身分資料欄,則命令會失敗。若只有來源資料表擁有身分資料欄,請包含 IGNOREEXTRA 參數以便略過身分資料欄。若只有目標資料表擁有身分資料欄,請包含 FILLTARGET 參數,以便根據為資料表定義的 IDENTITY 子句填入身分資料欄。如需詳細資訊,請參閱 DEFAULT。
您可以利用 ALTER TABLE APPEND 陳述式來附加預設身分資料欄。如需詳細資訊,請參閱 CREATE TABLE。
ALTER TABLE APPEND 範例
假設您的組織有資料表 SALES_MONTHLY,用來擷取目前的銷售交易。您想要每個月將交易資料表中的資料移至 SALES 資料表。
您可以使用以下 INSERT INTO 和 TRUNCATE 命令完成這項任務。
insert into sales (select * from sales_monthly); truncate sales_monthly;
不過,使用 ALTER TABLE APPEND 命令能夠更有效率地執行相同的操作。
首先,查詢 PG_TABLE_DEF 系統目錄資料表以確認兩個資料表擁有相同的資料欄,且資料欄的屬性相同。
select trim(tablename) as table, "column", trim(type) as type, encoding, distkey, sortkey, "notnull" from pg_table_def where tablename like 'sales%'; table | column | type | encoding | distkey | sortkey | notnull -----------+------------+-----------------------------+----------+---------+---------+-------- sales | salesid | integer | lzo | false | 0 | true sales | listid | integer | none | true | 1 | true sales | sellerid | integer | none | false | 2 | true sales | buyerid | integer | lzo | false | 0 | true sales | eventid | integer | mostly16 | false | 0 | true sales | dateid | smallint | lzo | false | 0 | true sales | qtysold | smallint | mostly8 | false | 0 | true sales | pricepaid | numeric(8,2) | delta32k | false | 0 | false sales | commission | numeric(8,2) | delta32k | false | 0 | false sales | saletime | timestamp without time zone | lzo | false | 0 | false salesmonth | salesid | integer | lzo | false | 0 | true salesmonth | listid | integer | none | true | 1 | true salesmonth | sellerid | integer | none | false | 2 | true salesmonth | buyerid | integer | lzo | false | 0 | true salesmonth | eventid | integer | mostly16 | false | 0 | true salesmonth | dateid | smallint | lzo | false | 0 | true salesmonth | qtysold | smallint | mostly8 | false | 0 | true salesmonth | pricepaid | numeric(8,2) | delta32k | false | 0 | false salesmonth | commission | numeric(8,2) | delta32k | false | 0 | false salesmonth | saletime | timestamp without time zone | lzo | false | 0 | false
接著查看各資料表的大小。
select count(*) from sales_monthly; count ------- 2000 (1 row) select count(*) from sales; count ------- 412,214 (1 row)
現在執行以下 ALTER TABLE APPEND 命令。
alter table sales append from sales_monthly;
再次查看各資料表的大小。SALES_MONTHLY 資料表現在擁有 0 個資料列,而 SALES 資料表增加了 2000 個資料列。
select count(*) from sales_monthly; count ------- 0 (1 row) select count(*) from sales; count ------- 414214 (1 row)
如果來源資料表的資料欄比目標資料表多,請指定 IGNOREEXTRA 參數。以下範例使用 IGNOREEXTRA 參數在附加至 SALES 資料表時,略過 SALES_LISTING 資料表中額外的資料欄。
alter table sales append from sales_listing ignoreextra;
如果目標資料表的資料欄比來源資料表多,請指定 FILLTARGET 參數。以下範例使用 FILLTARGET 參數來填入 SALES_REPORT 資料表中 SALES_MONTH 資料表沒有的資料欄。
alter table sales_report append from sales_month filltarget;
下列範例顯示如何以具體化視觀表作為來源來使用 ALTER TABLE APPEND 的範例。
ALTER TABLE target_tbl APPEND FROM my_streaming_materialized_view;
此範例中的資料表和具體化視觀表名稱為範例。從具體化視觀表附加只有在為 串流擷取至具體化視觀表 設定具體化視觀表的情況下才有作用。這會將來源具體化視觀表中的所有記錄移至與具體化視觀表具有相同結構描述的目標資料表,並使具體化視觀表保持不變。這與資料來源為資料表時的行為相同。