部分列更新

当前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