Kudu 自动生成的键列
Kudu auto generated key column
我正在尝试在 Kudu 中制作自定义自动 generated/incremented 键,它将不断增加其值 - 从默认为零的起始种子开始。
遍历所有记录并递增计数器以获得行计数是非常低效的。
Kudu 是否提供开箱即用的行数?
如果没有,最好的获取方式是什么?
Apache Kudu 目前不支持 AUTO_INCREMENT
列。 Kudu 网站上有一个 FAQ entry 提到了这一点。
Kudu 是一个分布式存储引擎,专注于成为良好的分析存储 (OLAP),而不是成为良好的事务性存储 (OLTP),它体现在我们目前优先考虑的功能中。这是一个很好的例子。
因为我们不想成为一个 OLTP 存储,Kudu 还没有实现多行或多节点事务,所以一个简单的递增主键计数器目前很难正确实现 - - 特别是当 table 在主键上进行散列分区时。我们需要一个当前不存在的中央事务协调器。
要回答你的第二个问题,在 Kudu 中获取行计数目前有点昂贵,因为它涉及扫描每个 tablet 上的索引列并求和总计数。如果您执行 SELECT COUNT(*) from kudu_table
,Apache Impala / Apache Spark SQL 将透明地为您执行此操作,但我目前不会依赖它来分配新 ID,因为 Impala 目前允许从稍微陈旧的 Kudu 副本进行扫描,因此可能会在行数上关闭。
现在最好的办法是依靠一些外部机制来分配行 ID。
资料来源:我是 Apache Kudu 上的 PMC 成员。
有几种方法可以解决这个问题。
使用impala的uuid()函数生成一个唯一的id。
将 uuid() 转换为 BIGINT(通过散列等)
使用 impala 的 unix_timestamp 生成一个 BIGINT 值,表示当前日期和时间作为 Unix 纪元的增量(这可能会导致一些冲突,所以更好如果您要将其用作主键,请添加另一列。
除了@JoeyVanHalens 的回答,还有另一个选项也有解释。您可以使用 row_numer()
创建一个类似于计数器的 ID,但如果您只想要一个类似于 counter
的列,则不会强制您进行一些繁琐的嵌套或其他操作。
直截了当,看起来像这样:
SELECT
row_number() OVER (PARTITION BY "dummy" ORDER BY "dummy") as incremented_id
FROM some_table
row_number()
在分区上创建一个递增的数字。与 rank()
不同,row_number()
确保即使您的分区包含重复项也能获得增量。
PARTITION BY "dummy"
将运行时的临时 "dummy"
列解释为整个 table 的一个分区。因此,增量发生在所有记录上。
ORDER BY
遵循相同的 "dummy"
-逻辑。
当然,您也可以将 "dummy"
替换为您的 table-逻辑所需的任何列。
结果如下:
-- ID = incremented_id
| ID | some_content |
|-------|--------------|
| 1 | "a" |
| 2 | "b" |
| 3 | "c" |
| 4 | "d" |
|-------|--------------|
我正在尝试在 Kudu 中制作自定义自动 generated/incremented 键,它将不断增加其值 - 从默认为零的起始种子开始。
遍历所有记录并递增计数器以获得行计数是非常低效的。
Kudu 是否提供开箱即用的行数? 如果没有,最好的获取方式是什么?
Apache Kudu 目前不支持 AUTO_INCREMENT
列。 Kudu 网站上有一个 FAQ entry 提到了这一点。
Kudu 是一个分布式存储引擎,专注于成为良好的分析存储 (OLAP),而不是成为良好的事务性存储 (OLTP),它体现在我们目前优先考虑的功能中。这是一个很好的例子。
因为我们不想成为一个 OLTP 存储,Kudu 还没有实现多行或多节点事务,所以一个简单的递增主键计数器目前很难正确实现 - - 特别是当 table 在主键上进行散列分区时。我们需要一个当前不存在的中央事务协调器。
要回答你的第二个问题,在 Kudu 中获取行计数目前有点昂贵,因为它涉及扫描每个 tablet 上的索引列并求和总计数。如果您执行 SELECT COUNT(*) from kudu_table
,Apache Impala / Apache Spark SQL 将透明地为您执行此操作,但我目前不会依赖它来分配新 ID,因为 Impala 目前允许从稍微陈旧的 Kudu 副本进行扫描,因此可能会在行数上关闭。
现在最好的办法是依靠一些外部机制来分配行 ID。
资料来源:我是 Apache Kudu 上的 PMC 成员。
有几种方法可以解决这个问题。
使用impala的uuid()函数生成一个唯一的id。
将 uuid() 转换为 BIGINT(通过散列等)
使用 impala 的 unix_timestamp 生成一个 BIGINT 值,表示当前日期和时间作为 Unix 纪元的增量(这可能会导致一些冲突,所以更好如果您要将其用作主键,请添加另一列。
除了@JoeyVanHalens 的回答,还有另一个选项也有解释row_numer()
创建一个类似于计数器的 ID,但如果您只想要一个类似于 counter
的列,则不会强制您进行一些繁琐的嵌套或其他操作。
直截了当,看起来像这样:
SELECT
row_number() OVER (PARTITION BY "dummy" ORDER BY "dummy") as incremented_id
FROM some_table
row_number()
在分区上创建一个递增的数字。与rank()
不同,row_number()
确保即使您的分区包含重复项也能获得增量。PARTITION BY "dummy"
将运行时的临时"dummy"
列解释为整个 table 的一个分区。因此,增量发生在所有记录上。ORDER BY
遵循相同的"dummy"
-逻辑。
当然,您也可以将 "dummy"
替换为您的 table-逻辑所需的任何列。
结果如下:
-- ID = incremented_id
| ID | some_content |
|-------|--------------|
| 1 | "a" |
| 2 | "b" |
| 3 | "c" |
| 4 | "d" |
|-------|--------------|