数据更新

          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 对数据进行适配。

          上一篇
          数据导入
          下一篇
          数据删除