在数据库中,数据更新将添加,删除或修改数据。及时的数据更新是高质量数据服务的重要组成部分。
从技术上讲,数据更新有两种类型:您要么更新整个行( ROW UPDATE ),要么只是更新部分列(部分列更新) 。许多数据库都支持这两个数据库,但以不同的方式支持。这篇文章是关于其中之一的,这在执行方面很简单,并且在数据质量保证方面有效。
作为一个开源分析数据库,Apache Doris用一个数据模型支持行更新和部分列更新:唯一的密钥模型。这是您放置不需要汇总的数据的地方。在唯一的密钥模型中,您可以指定一列或几个列的组合作为唯一键(又称主键)。对于一个唯一的密钥,总会有一排数据:新摄入的数据记录取代了旧数据。这就是数据更新的工作方式。
这个想法很简单,但是在现实生活实现中,最新数据不会到达最后一个或根本没有写成,因此我将向您展示Apache Doris如何实现数据更新并避免使用其独特的关键模型。
行更新
对于数据编写为唯一关键模型的数据,Apache Doris采用 UpSert 语义,这意味着更新或插入。如果新数据记录包括表中已经存在的唯一密钥,则新记录将替换旧记录。如果它包含一个全新的独特键,则将插入整个桌子。 UPSERT操作可以提供高吞吐量并保证数据可靠性。
示例:
在下表中,唯一键是三列的组合:user_id, date, group_id
。
mysql> desc test_table;
+-------------+--------------+------+-------+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-------+---------+-------+
| user_id | BIGINT | Yes | true | NULL | |
| date | DATE | Yes | true | NULL | |
| group_id | BIGINT | Yes | true | NULL | |
| modify_date | DATE | Yes | false | NULL | NONE |
| keyword | VARCHAR(128) | Yes | false | NULL | NONE |
+-------------+--------------+------+-------+---------+-------+
执行insert into
在数据记录中写入。由于表是空的,因此通过UpSert语义,这意味着在表中添加新的行。
mysql> insert into test_table values (1, "2023-04-28", 2, "2023-04-28", "foo");
Query OK, 1 row affected (0.05 sec)
{'label':'insert_2fb45d1833db4348_b612b8791c97b467', 'status':'VISIBLE', 'txnId':'343'}
mysql> select * from test_table;
+---------+------------+----------+-------------+---------+
| user_id | date | group_id | modify_date | keyword |
+---------+------------+----------+-------------+---------+
| 1 | 2023-04-28 | 2 | 2023-04-28 | foo |
+---------+------------+----------+-------------+---------+
然后插入另外两个数据记录,其中一个具有与先前插入的行相同的唯一键。现在,通过UPSERT语义,这意味着用新的行替换新的行,并插入新的独特键的记录。
mysql> insert into test_table values (1, "2023-04-28", 2, "2023-04-29", "foo"), (2, "2023-04-29", 2, "2023-04-29", "bar");
Query OK, 2 rows affected (0.04 sec)
{'label':'insert_7dd3954468aa4ac1_a63a3852e3573b4c', 'status':'VISIBLE', 'txnId':'344'}
mysql> select * from test_table;
+---------+------------+----------+-------------+---------+
| user_id | date | group_id | modify_date | keyword |
+---------+------------+----------+-------------+---------+
| 2 | 2023-04-29 | 2 | 2023-04-29 | bar |
| 1 | 2023-04-28 | 2 | 2023-04-29 | foo |
+---------+------------+----------+-------------+---------+
部分列更新
除了行更新外,在许多情况下,数据分析师还需要部分列更新的便利性。例如,在用户肖像中,他们想实时更新用户的某些维度。或者,如果他们需要维护来自各种源表的数据制成的平桌,那么与复杂的加入操作相比,他们更喜欢部分columm更新,以作为数据更新的方式。
apache doris支持使用更新语句的部分列更新。它过滤了需要修改的行,读取它们,更改几个值,然后将行写回表。
示例:
假设有一个顺序表,其中订单ID是唯一的密钥。
+----------+--------------+-----------------+
| order_id | order_amount | order_status |
+----------+--------------+-----------------+
| 1 | 100 | Payment Pending |
+----------+--------------+-----------------+
1 row in set (0.01 sec)
买方完成付款时,Apache Doris应将订单ID的订单状态1从“付款”中更改为“待交付”。这是更新命令发挥作用的时候。
mysql> UPDATE test_order SET order_status = 'Delivery Pending' WHERE order_id = 1;
Query OK, 1 row affected (0.11 sec)
{'label':'update_20ae22daf0354fe0-b5aceeaaddc666c5', 'status':'VISIBLE', 'txnId':'33', 'queryId':'20ae22daf0354fe0-b5aceeaaddc666c5'}
这是更新后的表。
+----------+--------------+------------------+
| order_id | order_amount | order_status |
+----------+--------------+------------------+
| 1 | 100 | Delivery Pending |
+----------+--------------+------------------+
1 row in set (0.01 sec)
更新命令的执行包括系统中的三个步骤:
- 第一步:读取顺序ID = 1(1,100,'付款待定') 的行
- 第二步:将订单状态从“付款”中修改为“待交付”(1,100,'交货未决')
- 第三步:将新行插入表格
该表位于唯一的密钥模型中,这意味着对于同一唯一键的行,只有最后一个插入的键将被保留,因此这是表最终的样子:
数据更新顺序
到目前为止,这听起来很简单,但是在现实世界中,数据更新可能由于诸如数据格式错误之类的原因而失败,从而弄乱了数据编写顺序。数据更新的顺序比您想象的更重要。例如,在金融交易中,混乱的数据编写顺序可能导致交易数据丢失,错误或重复,这进一步导致了更大的问题。
Apache Doris为用户提供了两个选项,以确保其数据以正确的顺序更新:
1。通过交易顺序提交
更新在Apache Doris中,每个数据摄入任务都是事务。每个成功摄入的任务将获得一个数据版本,并且数据版本的数量严格增加。如果摄入量失败,则交易将回滚,不会生成新的数据版本。
默认情况下,UPSERT语义遵循交易的顺序。如果有两个涉及相同唯一密钥的数据摄入任务,则第一个任务生成数据版本2和第二个数据版本3,则根据事务提交订单,数据版本3将替换数据版本2。
2。通过用户定义的订单更新
在实时数据分析中,数据更新通常以高并发性发生。可能有多个更新同一行的数据摄入任务,但是这些任务以未知顺序进行,因此最后保存的更新也是未知的。
例如,这是两个数据更新,分别为“ 2023-04-30”和“ 2023-05-01”为modify_data
。如果它们同时写入系统,但是“ 2023-05-01”一个是成功提交的,而另一个则是稍后的,则“ 2023-04-30”记录将由于其较高的数据版本编号而保存,但是我们知道这不是最新的。
mysql> insert into test_table values (2, "2023-04-29", 2, "2023-05-01", "bbb");
Query OK, 1 row affected (0.04 sec)
{'label':'insert_e2daf8cea5524ee1_94e5c87e7bb74d67', 'status':'VISIBLE', 'txnId':'345'}
mysql> insert into test_table values (2, "2023-04-29", 2, "2023-04-30", "aaa");
Query OK, 1 row affected (0.03 sec)
{'label':'insert_ef906f685a7049d0_b135b6cfee49fb98', 'status':'VISIBLE', 'txnId':'346'}
mysql> select * from test_table;
+---------+------------+----------+-------------+---------+
| user_id | date | group_id | modify_date | keyword |
+---------+------------+----------+-------------+---------+
| 2 | 2023-04-29 | 2 | 2023-04-30 | aaa |
| 1 | 2023-04-28 | 2 | 2023-04-29 | foo |
+---------+------------+----------+-------------+---------+
这就是为什么在高电流方案中,Apache Doris允许以用户定义的顺序更新数据。用户可以将列指定为序列列。通过这种方式,系统将根据序列列中的值来标识最新数据版。
示例:
您可以通过在表创建时指定function_column.sequence_col
属性来指定序列列。
CREATE TABLE test.test_table
(
user_id bigint,
date date,
group_id bigint,
modify_date date,
keyword VARCHAR(128)
)
UNIQUE KEY(user_id, date, group_id)
DISTRIBUTED BY HASH (user_id) BUCKETS 32
PROPERTIES(
"function_column.sequence_col" = 'modify_date',
"replication_num" = "1",
"in_memory" = "false"
);
然后检查并查看,将保存序列列中具有最高值的数据记录:
mysql> insert into test_table values (2, "2023-04-29", 2, "2023-05-01", "bbb");
Query OK, 1 row affected (0.03 sec)
{'label':'insert_3aac37ae95bc4b5d_b3839b49a4d1ad6f', 'status':'VISIBLE', 'txnId':'349'}
mysql> insert into test_table values (2, "2023-04-29", 2, "2023-04-30", "aaa");
Query OK, 1 row affected (0.03 sec)
{'label':'insert_419d4008768d45f3_a6912e584cf1b500', 'status':'VISIBLE', 'txnId':'350'}
mysql> select * from test_table;
+---------+------------+----------+-------------+---------+
| user_id | date | group_id | modify_date | keyword |
+---------+------------+----------+-------------+---------+
| 2 | 2023-04-29 | 2 | 2023-05-01 | bbb |
| 1 | 2023-04-28 | 2 | 2023-04-29 | foo |
+---------+------------+----------+-------------+---------+
结论
恭喜。现在,您已经概述了如何在Apache Doris中实现数据更新。有了这些知识,您基本上可以保证数据更新的效率和准确性。但是等等,还有很多。由于Apache Doris 2.0将提供更强大的部分列更新功能,并改善了更新语句的执行以及对更复杂的多桌联接查询的支持,我将向您展示如何在我的关注范围中详细介绍它们。上著作。 We正在不断更新我们的数据更新!