当前Delta Table支持对部分列进行更新。即对表执行插入或更新操作时,只需要在SQL中指定您想修改的目标列及其新数据,而无需包含表中的所有列。插入数据时,未被赋值的列会自动被填充为NULL;更新数据时,未被赋值的列保持不变。在多数场景下可大幅提升执行效率,节省存储成本。本文用具体示例为您展示如何在Delta Table中插入或更新部分列的数据。
例如某些典型的数仓业务中包含一些星型模式的数据表,表主键相同,需要将所有数据表按照主键合并为一张大宽表,用于后续的计算和统计,不同的数据表完全可以单独并发写入与其相关的列,互不影响,读取大宽表时再将其合并成完整的数据行进行输出,相比只能写入所有列的用法,部分列更新可以极大地提升写入和读取的性能,也能节省存储成本。
注意事项
表类型必须为Delta Table。
支持分区表和非分区表。
执行前您需要打开支持部分列更新的开关
SET odps.sql.upsertable.table.enable=true;
,默认已开启。
SQL示例
示例数据
创建Delta Table表delta_target
:
CREATE TABLE delta_target
(
key BIGINT NOT NULL PRIMARY KEY,
b STRING,
c BIGINT
)
TBLPROPERTIES ("acid.partial.fields.update.enable" = "true","transactional" = "true")
;
INSERT OVERWRITE/INSERT INTO
此处以示例数据为例,为您展示在Delta Table中,如何使用INSERT OVERWRITE/INSERT INTO插入部分列数据。
缺省
c
列,c
列自动补充为NULL。INSERT INTO TABLE delta_target(key, b) VALUES(1, '1'); SELECT * FROM delta_target;
返回结果:
+------------+------------+------------+ | key | b | c | +------------+------------+------------+ | 1 | 1 | NULL | +------------+------------+------------+
缺省
b
列,插入相同主键数据,相当于更新当前数据。INSERT INTO TABLE delta_target(key, c) VALUES(1, 1); SELECT * FROM delta_target;
返回结果:
+------------+------------+------------+ | key | b | c | +------------+------------+------------+ | 1 | 1 | 1 | +------------+------------+------------+
缺省
c
列,插入相同主键数据,相当于更新当前数据。INSERT INTO TABLE delta_target(key, b) VALUES(1, '11'); SELECT * FROM delta_target;
返回结果:
+------------+------------+------------+ | key | b | c | +------------+------------+------------+ | 1 | 11 | 1 | +------------+------------+------------+
不缺省,插入数据与当前主键不同,即新增一条数据。
INSERT INTO TABLE delta_target VALUES(2, '2', 2); SELECT * FROM delta_target;
返回结果:
+------------+------------+------------+ | key | b | c | +------------+------------+------------+ | 2 | 2 | 2 | | 1 | 11 | 1 | +------------+------------+------------+
更多关于INSERT OVERWRITE/INSERT INTO的信息请参见插入或覆写数据(INSERT INTO | INSERT OVERWRITE)。
UPDATE/DELETE
本文在INSERT OVERWRITE/INSERT INTO示例的基础上,为您展示如何使用UPDATE/DELETE更新部分列数据。
缺省
c
列,更新key=1的数据行。UPDATE delta_target SET b='111' WHERE key=1; SELECT * FROM delta_target;
返回结果:
+------------+------------+------------+ | key | b | c | +------------+------------+------------+ | 2 | 2 | 2 | | 1 | 111 | 1 | +------------+------------+------------+
缺省
c
列,更新key=2的数据行。UPDATE delta_target SET b='222' WHERE key=2; SELECT * FROM delta_target;
返回结果:
+------------+------------+------------+ | key | b | c | +------------+------------+------------+ | 2 | 222 | 2 | | 1 | 111 | 1 | +------------+------------+------------+
更多关于UPDATE/DELETE的信息请参见更新或删除数据(UPDATE | DELETE)。
MERGE INTO
本文在UPDATE/DELETE示例的基础上,为您展示如何使用MERGE INTO合并数据。
-- 创建acid2_dml_pu_source表
CREATE TABLE acid2_dml_pu_source AS
SELECT
key,b,c
FROM VALUES
(1,'10',10),
(2,'20',20),
(3,'30',30),
(4,'40',40),
(5,'50',50),
(6,'60',60) t (key,b,c);
-- 执行合并操作
MERGE INTO delta_target AS t USING acid2_dml_pu_source AS s ON s.key = t.key WHEN matched THEN UPDATE SET t.b = s.b WHEN NOT matched THEN INSERT (key, b) VALUES(s.key, s.b);
返回结果:
+------------+------------+------------+
| key | b | c |
+------------+------------+------------+
| 3 | 30 | NULL |
| 4 | 40 | NULL |
| 5 | 50 | NULL |
| 6 | 60 | NULL |
| 2 | 20 | 2 |
| 1 | 10 | 1 |
+------------+------------+------------+
更多关于MERGE INTO的信息请参见MERGE INTO。