数据更新
所有文档
menu
没有找到结果,请重新输入

PALO

数据更新

Doris 中存储的数据都是以追加(Append)的方式进入系统,这意味着所有已写入的数据是不可变更的。

所以 Doris 采用标记的方式来实现数据更新的目的。即在一批更新数据中,将之前的数据标记为删除,并写入新的数据。

在读取过程中,Doris 会自动处理这些标记数据(Merge-on-Read),保证用户读取到的是最新的数据。同时,Doris 后台的数据合并(Compaction)线程也会不断的对数据进行合并,消除标记数据,以减少在读取过程中需要进行的合并操作,加速查询。

大部分对数据修改的场景仅适用于 Unique Key 数据模型,因为只有该模型可以保证主键的唯一性,从而支持按主键对数据进行更新。

本文档主要介绍如何使用 Unique Key 数据模型来进行数据更新操作。

数据更新

关于 UNIQUE KEY 的说明,请参阅相关文档。这里不再赘述。下面仅举例说明。

  1. 创建一张 UNIQUE KEY 模型的表

    CREATE TABLE order_table
    (
        order_id BIGINT,
        order_type VARCHAR(8),
        order_status VARCHAR(32)
    )
    UNIQUE KEY(order_id)
    DISTRIBUTED BY HASH(order_id) BUCKETS 8;
  2. 导入第一批数据

    1000, TYPE#1, PAID
    1001, TYPE#2, PENDING
    1002, TYPE#3, PAID
  3. 将 ID 为 1001 的订单条目的 order_status 字段修改为 PAID,则需导入以下数据:

    1001, TYPE#2, PAID

    Doris 会根据主键 1001,则读取或者后台合并过程中,将这个条目的 order_status 字段替换为 PAID。

更新部分字段

在上一个例子中,我们仅需要更新 order_status 字段,但是导入的数据中却需要包含 order_type 字段。

在某些场景下,用户无法获取全列数据,仅知道主键和部分要更新的字段的值。在这种情况下,我们可以通过 REPLACE_IF_NOT_NULL 这种聚合方式来实现。

REPLACE_IF_NOT_NULL 表示,当遇到 null 值则不更新。举例如下:

  1. 创建一张 AGGREGATE KEY 模型的表,使用 REPLACE_IF_NOT_NULL 方式。

    CREATE TABLE order_table
    (
        order_id BIGINT,
        order_type VARCHAR(8) REPLACE_IF_NOT_NULL,
        order_status VARCHAR(32) REPLACE_IF_NOT_NULL
    )
    AGGREGATE KEY(order_id)
    DISTRIBUTED BY HASH(order_id) BUCKETS 8;

    注意这里我们需要使用 AGGREGATE KEY 数据模型,并且将所有 Value 列的聚合方式设置为 REPLACE_IF_NOT_NULL

  2. 导入第一批数据

    1000, TYPE#1, PAID
    1001, TYPE#2, PENDING
    1002, TYPE#3, PAID
  3. 将 ID 为 1001 的订单条目的 order_status 字段修改为 PAID,则需导入以下数据:

    1001, \N, PAID

    原始数据中的 \N 即表示 null。Doris 会根据主键 1001,则读取或者后台合并过程中,将这个条目的 order_status 字段替换为 PAID。并且因为 order_type 字段为 null,所以该字段不会被替换。

更新顺序

Doris 内部仅能够保证两个批次的导入数据中,后一批次的数据覆盖更新前一批次的数据。但是如果在同一批次数据中,如果出现主键相同的多行记录,Doris 是无法识别哪一条才是最终生效数据的。

假设某一批次的导入数据如下:

1000, TYPE#1, PENDING
1001, TYPE#2, PENDING
1000, TYPE#3, PAID

注意第一行和第三行主键相同,因此无法确定哪一条会生效,用户最终查询 1000 这个订单的状态,可能为 PENDING,也可能为 PAID

要解决这个问题,需要业务侧保证在同一批次数据中,没有主键相同的行。或者需参考 Sequence Column 对数据进行适配。

数据导入数据删除