Apache Doris 如何基于自增列满足高效字典编码等典型场景需求

doris:自增列 阅读详情

自增列(auto_increment)是数据库中常见的一项功能,它提供一种方便高效的方式为行分配唯一标识符,极大简化数据管理的复杂性。当新行插入到表中时,数据库系统会自动选取自增序列中的下一个可用值,并将其分配给指定的列,无需用户手动干预。这种自动化的机制不仅简化了数据管理的流程,更确保了标识符的唯一性,让数据库维护变得更加便捷和可靠。

自增列在多种场景中发挥着重要的作用:

  • 字典编码: 在常见场景中,UserID 和订单 ID 通常被存储为 String 字符串类型,当需要进行精确去重查询时,直接对字符串去重可能效率不高。为了极致性能,常见的做法是先对字符串进行字典编码后构建 Bitmap 进行聚合运算。而自增列可以提高字典编码的效率,从而提高字符串精确去重以及查询的性能。
  • 主键生成: 由于主键是唯一的,且不允许为空,因此自增列经常被用作表的主键。自增列可以确保每次插入新记录时自动生成唯一的标识符,有助于简化数据的管理和查询。
  • 明细更新: 使用自增列为每条入库的记录分配了唯一 ID 作为主键之后,即可基于这些主键进行更新。从而解决了明细表不支持更新的问题。
  • 高效分页: 在数据展示时,分页是一种常见的需求。传统的分页通常利用 SQL 中的 limit, offset + order by 进行查询。当进行深分页(Offset 很大)时,该方式需对全量数据读取并排序,效率极低。而自增列可以为每行数据生成唯一标识,当进行分页查询时,可以记录上一页最大唯一标识,并将其作为下一页的查询条件。这样可以有效过滤大量非必需数据,显著减轻数据库压力,为用户提供高效的分页机制。
  • …

在分布式数据库中,由于自增序列的可用值分配涉及全局事务,这使自增列的实现存在一定难度。然而, Apache Doris 在 2.1 版本中实现了高效的自增列功能,提供了创新性的自增序列预分配方案。当用户开启自增列之后,自增序列值分配所带来的写入损耗可以忽略不计。其次,为了实现最佳的写入效率,我们在自增列功能的设计上进行了调整,例如自增序列只保证唯一性,而不保证严格连续和递增等特性,以保证数据的高效写入。(我们将在后文“使用限制”一节进行详细介绍)

本文将从基本语法、使用示例、ID 预分配方案基本原理、使用限制等几个方面对自增列进行详尽的介绍,以帮助用户更好地理解和应用自增列功能。

自增列语法及使用介绍

在使用自增列时,需要在建表 CREATE-TABLE 时为对应的列添加AUTO_INCREMENT属性。 若要手动指定自增列起始值,可以在建表时通过AUTO_INCREMENT(start_value)语句指定,若未指定,则默认起始值为 1。

创建一个 Dupliciate 模型表,其中一个 Key 列为自增列

CREATE TABLE `demo`.`tbl` (
      `id` BIGINT NOT NULL AUTO_INCREMENT,
      `value` BIGINT NOT NULL
) ENGINE=OLAP
DUPLICATE KEY(`id`)
DISTRIBUTED BY HASH(`id`) BUCKETS 10
PROPERTIES (
"replication_allocation" = "tag.location.default: 3"
);

自增列也可以用于 Value 列,下方语句示例创建 Dupliciate 模型表,其中一个 Value 列是自增列

CREATE TABLE `demo`.`tbl` (
      `uid` BIGINT NOT NULL,
      `name` BIGINT NOT NULL,
      `id` BIGINT NOT NULL AUTO_INCREMENT,
      `value` BIGINT NOT NULL
) ENGINE=OLAP
DUPLICATE KEY(`uid`, `name`)
DISTRIBUTED BY HASH(`uid`) BUCKETS 10
PROPERTIES (
"replication_allocation" = "tag.location.default: 3"
);

自增列支持 Duplicate Key 和 Unique Key 两种模型,Unique Key 模型的使用与 Duplicate Key 模型类似,在此不再赘述。

接下来,我们以下表为例,介绍自增列功能的具体使用:

CREATE TABLE `demo`.`tbl` (
    `id` BIGINT NOT NULL AUTO_INCREMENT,
    `name` varchar(65533) NOT NULL,
    `value` int(11) NOT NULL
) ENGINE=OLAP
UNIQUE KEY(`id`)
DISTRIBUTED BY HASH(`id`) BUCKETS 10
PROPERTIES (
"replication_allocation" = "tag.location.default: 3"
);

当使用 Insert Into 语句导入文件,并且不指定自增列id时,id列会被自动填充生成的值。

mysql> insert into tbl(name, value) values("Bob", 10), ("Alice", 20), ("Jack", 30);
Query OK, 3 rows affected (0.09 sec)
{'label':'label_183babcb84ad4023_a2d6266ab73fb5aa', 'status':'VISIBLE', 'txnId':'7'}

mysql> select * from tbl order by id;
+------+-------+-------+
| id   | name  | value |
+------+-------+-------+
|    1 | Bob   |    10 |
|    2 | Alice |    20 |
|    3 | Jack  |    30 |
+------+-------+-------+
3 rows in set (0.05 sec)

类似地,当使用 Stream Load 导入文件 test.csv ,并且不指定自增列id时,id列会被自动填充生成的值。

test.csv:
Tom,40
John,50
curl --location-trusted -u user:passwd -H "columns:name,value" -H "column_separator:," -T ./test.csv http://{host}:{port}/api/{db}/tbl/_stream_load
select * from tbl order by id;
+------+-------+-------+
| id   | name  | value |
+------+-------+-------+
|    1 | Bob   |    10 |
|    2 | Alice |    20 |
|    3 | Jack  |    30 |
|    4 | Tom   |    40 |
|    5 | John  |    50 |
+------+-------+-------+
5 rows in set (0.04 sec)

自增列在典型场景的应用

01 字典编码

在 Doris 中, 通常采用 RoaringBitmap 实现 Bitmap 类型及相关聚合运算,如果字典编码后的值越稠密,RoaringBitmap 性能则越好。前文已提到,自增列功能在提升字典编码效率方面表现出色。为进一步展示这一功能在实际场景中的应用效果,我们以用户画像场景为例进行深入探讨。

我们以离线 PV 、UV 分析为例进行展示,首先使用以下用户行为表存放明细数据:

CREATE TABLE `demo`.`dwd_dup_tbl` (
    `user_id` varchar(50) NOT NULL,
    `dim1` varchar(50) NOT NULL,
    `dim2` varchar(50) NOT NULL,
    `dim3` varchar(50) NOT NULL,
    `dim4` varchar(50) NOT NULL,
    `dim5` varchar(50) NOT NULL,
    `visit_time` DATE NOT NULL
) ENGINE=OLAP
DUPLICATE KEY(`user_id`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 32
PROPERTIES (
"replication_allocation" = "tag.location.default: 3"
);

利用自增列创建如下字典表

CREATE TABLE `demo`.`dictionary_tbl` (
    `user_id` varchar(50) NOT NULL,
    `aid` BIGINT NOT NULL AUTO_INCREMENT
) ENGINE=OLAP
UNIQUE KEY(`user_id`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 32
PROPERTIES (
"replication_allocation" = "tag.location.default: 3"
);

将存量数据中的user_id导入字典表,并建立user_id到整数值的编码映射

insert into dictionary_tbl(user_id)
select user_id from dwd_dup_tbl group by user_id;

或者使用如下方式仅将增量数据中的user_id导入到字典表中。在实际场景中,也可以使用 Flink Connector 将数据写入到 Doris。

insert into dictionary_tbl(user_id)
select dwd_dup_tbl.user_id from dwd_dup_tbl left join dictionary_tbl
on dwd_dup_tbl.user_id = dictionary_tbl.user_id where dwd_dup_tbl.visit_time  '2023-12-10' and dictionary_tbl.user_id is NULL;

假设统计维度为dim1, dim3, dim5,创建聚合表来存放聚合结果

CREATE TABLE `demo`.`dws_agg_tbl` (
    `dim1` varchar(50) NOT NULL,
    `dim3` varchar(50) NOT NULL,
    `dim5` varchar(50) NOT NULL,
    `user_id_bitmap` BITMAP BITMAP_UNION NOT NULL,
    `pv` BIGINT SUM NOT NULL 
) ENGINE=OLAP
AGGREGATE KEY(`dim1`,`dim3`,`dim5`)
DISTRIBUTED BY HASH(`dim1`) BUCKETS 32
PROPERTIES (
"replication_allocation" = "tag.location.default: 3"
);

将数据聚合运算后的结果存放至聚合结果表中

insert into dws_agg_tbl
select dwd_dup_tbl.dim1, dwd_dup_tbl.dim3, dwd_dup_tbl.dim5, BITMAP_UNION(TO_BITMAP(dictionary_tbl.aid)), COUNT(1)
from dwd_dup_tbl INNER JOIN dictionary_tbl on dwd_dup_tbl.user_id = dictionary_tbl.user_id
group by dwd_dup_tbl.dim1, dwd_dup_tbl.dim3, dwd_dup_tbl.dim5;

使用以下语句进行 UV、PV 查询

select dim1, dim3, dim5, bitmap_count(user_id_bitmap) as uv, pv from dws_agg_tbl;

02 明细更新

在 Doris 中,Unique Key 模型适用于具备明确主键、数据频繁更新的场景;Duplicate Key 模型适用于明细数据存储、不支持数据更新的场景。

在实际应用中,用户有时也需要对明细数据进行更新操作,但这些明细数据可能并没有能保证唯一性的主键列,也不方便将这些明细数据转存到 Unique Key 表进行更新。而使用自增列作为主键来存储明细数据,可以完美的解决明细数据更新的问题。

我们以金融场景用户借款数据为例,展示如何使用自增列支持明细数据的更新。例如用户有如下的 Duplicate Key 表来记录用户的借款行为,一个用户可能存在多条借款记录。

CREATE TABLE loan_records (
    `user_id` VARCHAR(20) DEFAULT NULL COMMENT '用户ID',
    `loan_amount` DECIMAL(10, 2) DEFAULT NULL COMMENT '借款金额',
    `interest_rate` DECIMAL(10, 2) DEFAULT NULL COMMENT '借款利率',
    `loan_start_date` DATE DEFAULT NULL COMMENT '借款开始日期',
    `loan_end_date` DATE DEFAULT NULL COMMENT '借款结束日期',
    `total_debt` DECIMAL(10, 2) DEFAULT NULL COMMENT '欠款总额'
) DUPLICATE KEY(`user_id`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 10
PROPERTIES (
    "replication_allocation" = "tag.location.default: 3"
);

假设该金融机构正在举办一个优惠活动,老用户的利率打 9 折,并希望更新表中的interest_rate字段和total_debt字段值,但由于 Duplicate Key 表不支持更新,无法进行该操作。

要解决该问题,用户可以使用支持更新的 Unique Key 表,并将自增 ID 设为主键:

CREATE TABLE loan_records (
    `auto_id` BIGINT NOT NULL AUTO_INCREMENT,
    `user_id` VARCHAR(20) DEFAULT NULL COMMENT '用户ID',
    `loan_amount` DECIMAL(10, 2) DEFAULT NULL COMMENT '借款金额',
    `interest_rate` DECIMAL(10, 2) DEFAULT NULL COMMENT '借款利率',
    `loan_start_date` DATE DEFAULT NULL COMMENT '借款开始日期',
    `loan_end_date` DATE DEFAULT NULL COMMENT '借款结束日期',
    `total_debt` DECIMAL(10, 2) DEFAULT NULL COMMENT '欠款总额'
) UNIQUE KEY(`auto_id`)
DISTRIBUTED BY HASH(`auto_id`) BUCKETS 10
PROPERTIES (
    "replication_allocation" = "tag.location.default: 3"
);

我们向该表导入几条贷款记录数据,如下是示例 SQL 语句(注意这里不需要写入 auto_id 字段)

INSERT INTO loan_records (user_id, loan_amount, interest_rate, loan_start_date, loan_end_date, total_debt) VALUES
('10001', 5000.00, 5.00, '2024-03-01', '2024-03-31', 5020.55),
('10002', 10000.00, 5.00, '2024-03-01', '2024-05-01', 10082.56),
('10003', 2000.00, 5.00, '2024-03-01', '2024-03-15', 2003.84),
('10004', 7500.00, 5.00, '2024-03-01', '2024-04-15', 7546.23),
('10005', 3000.00, 5.00, '2024-03-01', '2024-03-21', 3008.22),
('10002', 8000.00, 5.00, '2024-03-01', '2024-06-01', 8100.82),
('10007', 6000.00, 5.00, '2024-03-01', '2024-04-10', 6032.88),
('10008', 4000.00, 5.00, '2024-03-01', '2024-03-26', 4013.70),
('10001', 5500.00, 5.00, '2024-03-01', '2024-04-05', 5526.37),
('10010', 9000.00, 5.00, '2024-03-01', '2024-05-10', 9086.30);

使用select * from loan_records 查询可以看到已经为每条记录分配了一个唯一ID:

mysql> select * from loan_records;
+---------+---------+-------------+---------------+-----------------+---------------+------------+
| auto_id | user_id | loan_amount | interest_rate | loan_start_date | loan_end_date | total_debt |
+---------+---------+-------------+---------------+-----------------+---------------+------------+
|       1 | 10001   |     5000.00 |          5.00 | 2024-03-01      | 2024-03-31    |    5020.55 |
|       4 | 10004   |     7500.00 |          5.00 | 2024-03-01      | 2024-04-15    |    7546.23 |
|       2 | 10002   |    10000.00 |          5.00 | 2024-03-01      | 2024-05-01    |   10082.56 |
|       3 | 10003   |     2000.00 |          5.00 | 2024-03-01      | 2024-03-15    |    2003.84 |
|       6 | 10002   |     8000.00 |          5.00 | 2024-03-01      | 2024-06-01    |    8100.82 |
|       8 | 10008   |     4000.00 |          5.00 | 2024-03-01      | 2024-03-26    |    4013.70 |
|       7 | 10007   |     6000.00 |          5.00 | 2024-03-01      | 2024-04-10    |    6032.88 |
|       9 | 10001   |     5500.00 |          5.00 | 2024-03-01      | 2024-04-05    |    5526.37 |
|       5 | 10005   |     3000.00 |          5.00 | 2024-03-01      | 2024-03-21    |    3008.22 |
|      10 | 10010   |     9000.00 |          5.00 | 2024-03-01      | 2024-05-10    |    9086.30 |
+---------+---------+-------------+---------------+-----------------+---------------+------------+
10 rows in set (0.01 sec)

接下来我们执行如下两条 SQL 来分别更新老用户的优惠利率和贷款余额

update loan_records set interest_rate = interest_rate * 0.9 where user_id <= 10005;
update loan_records set total_debt = loan_amount + (loan_amount * (interest_rate / 100) * DATEDIFF(loan_end_date, loan_start_date) / 365);

再次查询,可以看到数据顺利的实现更新

mysql> select * from loan_records order by auto_id;
+---------+---------+-------------+---------------+-----------------+---------------+------------+
| auto_id | user_id | loan_amount | interest_rate | loan_start_date | loan_end_date | total_debt |
+---------+---------+-------------+---------------+-----------------+---------------+------------+
|       1 | 10001   |     5000.00 |          4.50 | 2024-03-01      | 2024-03-31    |    5018.49 |
|       2 | 10002   |    10000.00 |          4.50 | 2024-03-01      | 2024-05-01    |   10075.21 |
|       3 | 10003   |     2000.00 |          4.50 | 2024-03-01      | 2024-03-15    |    2003.45 |
|       4 | 10004   |     7500.00 |          4.50 | 2024-03-01      | 2024-04-15    |    7541.61 |
|       5 | 10005   |     3000.00 |          4.50 | 2024-03-01      | 2024-03-21    |    3007.40 |
|       6 | 10002   |     8000.00 |          4.50 | 2024-03-01      | 2024-06-01    |    8090.74 |
|       7 | 10007   |     6000.00 |          5.00 | 2024-03-01      | 2024-04-10    |    6032.88 |
|       8 | 10008   |     4000.00 |          5.00 | 2024-03-01      | 2024-03-26    |    4013.70 |
|       9 | 10001   |     5500.00 |          4.50 | 2024-03-01      | 2024-04-05    |    5523.73 |
|      10 | 10010   |     9000.00 |          5.00 | 2024-03-01      | 2024-05-10    |    9086.30 |
+---------+---------+-------------+---------------+-----------------+---------------+------------+
10 rows in set (0.01 sec)

03 高效分页

使用传统分页进行深分页查询时(offset 很大时),即使需要的数据行很少,依然会将全部数据读取到内存中进行全量排序后再进行处理,处理效率很低。

为解决深分页查询效率低的问题,我们可以通过自增列为每行数据添加唯一值。 在查询时通过记录上一页面unique_value列最大值max_value,并使用 where unique_value > max_value limit rows_per_page 下推谓词提前过滤大量数据,从而实现更高效地分页。

我们以下方业务表为例,在开启自增列之后,将为表中的每行数据赋予唯一标识:

CREATE TABLE `demo`.`records_tbl` (
    `user_id` int(11) NOT NULL COMMENT "",
    `name` varchar(26) NOT NULL COMMENT "",
    `address` varchar(41) NOT NULL COMMENT "",
    `city` varchar(11) NOT NULL COMMENT "",
    `nation` varchar(16) NOT NULL COMMENT "",
    `region` varchar(13) NOT NULL COMMENT "",
    `phone` varchar(16) NOT NULL COMMENT "",
    `mktsegment` varchar(11) NOT NULL COMMENT "",
    `unique_value` BIGINT NOT NULL AUTO_INCREMENT
) DUPLICATE KEY (`user_id`, `name`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 10
PROPERTIES (
    "replication_allocation" = "tag.location.default: 3"
);

在分页展示中,每页展示 100 条数据,使用以下方式获取第一页的数据:

select * from records_tbl order by unique_value limit 100;

通过程序记录返回结果中unique_value中的最大值,假设为最大值为 99,则可使用以下方式查询第 2 页数据:

select * from records_tbl where unique_value > 99 order by unique_value limit 100;

如果想要直接查询靠后页面中内容,例如直接获取第 101 页的内容,此时不方便直接获取之前页面数据中unique_value的最大值,则可以使用如下方式进行查询:

select user_id, name, address, city, nation, region, phone, mktsegment
from records_tbl, (select unique_value as max_value from records_tbl order by unique_value limit 1 offset 9999) as previous_data
where records_tbl.unique_value > previous_data.max_value
order by unique_value limit 100;

自增列实现原理

传统 OLTP 数据库一般通过事务机制进行中心化的逐个自增 ID 匹配,但在基于 MPP 架构的分布式数据库中,该方式会严重限制数据导入的性能。因此,Apache Doris 2.1 版本对自增 ID 的实现进行了创新,当每个导入协调者 BE 需要分配自增 ID 时,将批量向 FE 申请 ID 区间,且 FE 可保障每个 BE 分配的 ID 区间不重叠,这样就可以保证 ID 的唯一性。

结合下方示意图来说明,下表存在自增列。当 StreamLoad 1 选中 BE1 作为协调者时,BE1 会找 FE 申请一批 ID 区间(1-1000)并缓存在本地,当 1000 个 ID 分配完后,BE1 将继续找 FE 申请下一批。与此同时,StreamLoad 2 选中 BE3 作为协调者,BE3 也会找 FE 申请 ID,由于 1-1000 已经分配给了 BE1,因此 FE 将 1001 - 2000 分配给 BE3 。

自增列实现原理.png

此外,如果 StreamLoad 1 和 StreamLoad 2 分别写了 50 条数据,那么这两批导入产生的自增 ID 范围分别为 1-50 和 1001-1050。如果还存在 StreamLoad3,且也选中 BE1 作为协调者,那么 BE1 会从 51 开始分配 ID。虽然 StreamLoad3 在 StreamLoad2 之后写入,但可能出现 StreamLoad3 写入的数据分配到了更小的自增 ID。

注意事项

在 Apache Doris 中,自增列的使用受到一些严格的语法限制,这些限制确保了数据的完整性和一致性。具体来说:

  • 自增列只支持 Duplicate Key 模型和 Unique Key 模型

  • 每张表有且只能包含一个自增列

  • 自增列的类型必须是 BIGINT 类型,且该列不能为 NULL

  • 手动指定的自增列起始值必须大于等于 0

此外,在使用自增列时,还需要注意以下语义限制:

  • 唯一性保证范围: Doris 保证了自增列上生成的值在表内具有唯一性,但仅限于 Doris 自动填充的值,如果用户通过显式指定自增列的方式插入值,Doris 则无法保证该值的唯一性。
  • 值的稠密性与连续性:Doris 可保证自增列自动生成的值是稠密的,但出于性能考虑,无法保证导入时自动填充的自增列值是完全连续的。这意味着在导入过程中,自增列的值可能出现跳跃现象。此外,由于 BE 会缓存预先分配的自增列值,且值之间互不相交,因此无法根据自增列的值的大小来判断数据导入的先后顺序。

结束语

自增列的实现,使得 Apache Doris 可以在处理大规模时展示出更高的稳定性和可靠性。通过自增列,用户能够高效进行字典编码,显著提升了字符串精确去重以及查询的性能。使用自增列作为主键来存储明细数据,可以完美的解决明细数据更新的问题。同时,基于自增列,用户可以实现高效的分页机制,轻松应对深分页场景,有效过滤掉大量非必需数据,从而减轻数据库的负载压力,为用户带来了更加流畅和高效的数据处理体验。

如果你在实际场景中也有自增列使用需求,非常欢迎大家下载新版本体验。如果你在使用中有任何问题或建议,可进入 Doris 问答论坛 进行讨论~

Doris 画像标签存储实践 根据画像标签的需求场景,我们常常将画像存储分为两部份,分别是: 画像基本信息的存储 用户画像人群的筛选需求的存储 常见画像标签存储方式: 根据类目创建宽表,或者根据更新的频率创建宽表 创建竖表-每个用户+每个标签=一条记录 竖表+横表=》分开计算,定时聚合 ES 标签对象存储,rowKey为user_id,HBASE存储用户明细,通过user_id关联 倒排表,标签-》多个用户Id,bitmap方案 一、根据类目创建宽表,或者根据更新的频率创建宽表 1. 这是最容易想到的方式,同时也是最直观的方式, 阅读详情

相关推荐

Doris数据库---建表、调整表结构操作

doris常见建表语法和问题解决

weixin_51101008的博客 1万+

doris如何实现自增id和uuid生成

doris如何实现uuid生成

苏暴击的博客 9666

Doris的自增列介绍

在 Doris 中,自增列(Auto Increment Column)是一种自动生成唯一数字值的功能,常用于为每一行数据生成唯一的标识符,如主键。每当插入新记录时,自增列会自动分配一个递增的值,避免了手动指定数字的繁琐操作。使用 Doris 自增列,可以确保数据的唯一性和一致性,简化数据插入过程,减少人为错误,并提高数据管理的效率。总之,Doris 的自增列提供了一种在分布式环境下生成全局唯一、单调递增 ID 的有效解决方案,特别适合用作表的主键或需要唯一标识的场景,简化了应用开发。

2301_80954266的博客 927

doris问题

20220111 CREATE EXTERNAL TABLE `tb_onekey_goods_info_manual_match_test` ( `id` bigint(20) NOT NULL COMMENT "业务主键 自增id", `goods_id` varchar(200) NULL COMMENT "商品id", `hz_goods_id` varchar(200) NULL COMMENT "合纵商品id", `goods_name` varchar(200) NULL CO

kyle1314608的博客 3113

Apache Doris (十九) :Doris Properties 配置项及Engine选择

在 0.15 版本后,该属性将自动转换成 replication_allocation 属性,如:"replication_num" = "3" 会自动转换成 "replication_allocation" = "tag.location.default:3"。示例:"disable_auto_compaction" = "false"。2)dynamic_partition.time_unit: 用于指定动态添加分区的时间单位,可选择为DAY(天),WEEK(周),MONTH(月),HOUR(时)。

qq_32020645的博客 2300

Doris 如何基于自增列满足高效字典编码等典型场景需求

在使用自增列时,需要在建[ CREATE-TABLE 时为对应的列添加属性。若要手动指定自增列起始值,可以在建表时通过语句指定,若未指定,则默认起始值为 1。创建一个 Dupliciate 模型表,其中一个 Key 列为自增列自增列也可以用于 Value 列,下方语句示例创建 Dupliciate 模型表,其中一个 Value 列是自增列自增列支持 Duplicate Key 和 Unique Key 两种模型,Unique Key 模型的使用与 Duplicate Key 模型类似,在此不再赘述。

6万+

Apache Doris 基础 -- 数据表设计(使用AUTO_INCREMENT)

Apache Doris 基础 -- 数据表设计(使用AUTO_INCREMENT)

chinusyan的专栏 2567

OAI数据集申请下载全攻略:从个人NDA账号注册到数据包下载的保姆级避坑指南

本文提供OAI数据集申请下载的完整指南,涵盖从个人NDA账号注册到数据包下载的全流程。重点解析login.gov验证陷阱、浏览器兼容性问题、NDA权限申请技巧及nda-tools高效使用方法,帮助医学影像研究者避开常见技术障碍,快速获取全球骨关节炎研究数据库OAI的宝贵数据资源。

weixin_28698059的博客 745

DorisDB系列文档(五) 表设计详解

1 数据存储基本原理 由此可见, 查找维度列的前缀的查找过程为: 先查找shortkey index, 获得逻辑块的起始行号, 查找维度列的行号索引, 获得目标列的数据块, 读取数据块, 然后解压解码, 从数据块中找到维度列前缀对应的数据项. 加速数据处理 列式存储 DorisDB的表和关系型数据相同, 由行和列构成. 每行数据对应用户一条记录, 每列数据有相同数据类型. 所有数据行的列数相同, 可以动态增删列. DorisDB中, 一张表的列可以分为维度列(也成为...

HANG.NIAN 5755

【unity】解决unity编译器安装中文汉化包失败

查看是否有Localization目录如果没有就进行创建,然后点击打开Localization把下载的zh-hans.po文件复制剪切进去即可。如果有的同学中文包安装失败,我们找到相应的编译器版本,点击在资源管理器中显示按钮,我们找到简体中文,复制downloadUrl后面的值到浏览器打开进行下载,点击Edtior language选择框,选择简体中文,等待加载。我们点击当前目录的上一级,进入编译器目录。返回在文件管理器中点击Editor目录。编译器启动后点击Edit[编辑]按钮。复制或者剪切下载的文件。

weixin_44959182的博客 8021

KEPServerEX6教程:IoT Gateway与MQTT Client实现工业数据双向通信

工业物联网的核心挑战在于异构设备协议与云端平台之间的数据互通。Modbus、S7、OPC UA等现场协议纷繁复杂,而上层应用普遍偏好MQTT、REST等轻量接口,此时需要一个可靠的协议转换层。MQTT作为低带宽、高可靠的发布/订阅消息协议,天然适合工业数据采集与远程控制场景。KEPServerEX6作为工业网关软件,内置IoT Gateway与MQTT Client组件,分别承担数据上行发布与指令下行订阅的职责,形成完整的双向闭环。通过配置Modbus TCP设备驱动、创建Tag、设置MQTT Broker

weixin_33787529的博客 386

Doris数据库表操作

【代码】Doris数据库表操作。

A_drizzle_gm的博客 8030

工业视觉检测实战指南:从硬件配置到AI算法部署

本文提供了一套完整的工业视觉检测系统搭建实战指南。从硬件选型(相机、光源、镜头、工控机)到AI算法(深度学习模型)部署,详细解析了如何为生产线配置一双“会思考的眼睛”。重点探讨了深度学习算法在复杂缺陷识别中的应用,并分享了模型训练、优化及云边协同部署的实战心得,旨在帮助工程师实现从实验室Demo到7x24小时稳定运行的工业落地。

weixin_29051193的博客 456

Doris:数据表设计

Doris的数据表设计及基本操作

m0_37559973的博客 5365

RV1126平台librga图像旋转裁剪实战

本文详细介绍了在rv1126平台上使用librga库实现图像旋转和裁剪的方法。首先解释了librga的基本概念和关键对象,包括源图像、目标图像和操作参数。随后分步骤说明了初始化设置、缓冲区创建、裁剪区域定义(通过坐标和尺寸参数)以及旋转操作(支持常见角度)。提供了完整的示例代码演示如何组合裁剪和旋转操作,并强调了性能优化、错误处理、格式支持等注意事项。通过硬件加速的librga,可以在rv1126平台上高效完成图像处理任务。

hwmxrhx的博客 1543

跟着团子学SAP CO:熟练使用结果分析码实现各个场景下收入成本的匹配(一) KKA2/CJ88

PS模块中对财务顾问最难的点在于项目结算,特别是销售型的项目结算。针对客户型项目结算我列举了以下常见的收入成本匹配的一些场景: (1)在项目执行过程中会多次开票,但由于各期成本浮动很大(如前期可能只涉及一些人工、中期全是比较金额较大的材料费),所以希望开票的时候能通过合理的一些指标进行主营业务成本与主营业务收入的匹配。 (2)项目过程中会多次开票,开票确认主营业务收入时,直接将累计发生的实际成本结转为主营业务成本。 (3)项目过程中虽多次开票,但不确认收入,所有发生的实际成本月末计算为在制品,最后项目一次性

Lucas1211的博客 9533

Apache Doris使用总结

doris简介到特性到一些简单的进阶用法

1万+

YOLOv8集成EMA注意力机制YOLOv8完整教程 将EMA注意力机制集成到YOLOv8框架中

YOLOv8教程这篇文章介绍了如何将EMA(高效多尺度注意力)机制集成到YOLOv8目标检测框架中。YOLOv8 EMA注意力机制通过多尺度特征融合和高效计算,能够提升模型对关键特征的关注能力。文章详细解析了EMA的原理和结构设计,包括其核心组件和前向传播过程。此外,提供了完整的实现指南,包括环境准备、项目结构设置、EMA模块代码实现(包含分组处理、空间注意力计算和特征融合等关键步骤)。YOLOv8 YOLOv8 YOLOv8 YOLOv8 YOLOv8

FJN110的博客 925

大数据 - Doris系列《三》- 数据表设计之表的基本概念

所以,即使在同一台物理机上部署了 3 个或更多 BE 实例,如果这些 BE 的 IP 相同,则依然只能设置副本数为 1。Partition 支持通过 VALUES LESS THAN (...) 仅指定上界,系统会将前一个分区的上界作为该分区的下界,生成一个左闭右开的区间。注意,最后一个分区用户缺失,只指定了 date 列的分区值,所以 id 列的分区值会默认填充 MIN_VALUE。如按天分区,当每天的数据量差异很大时,可以通过指定分区的分桶数,合理划分不同分区的数据,分桶列建议选择区分度大的列。

weixin_40968325的博客 1724

ADT MCP Server 把 ABAP 开发带进 Agent 模式

今天讨论 ADT MCP Server,不能只把它看成 Visual Studio Code 里多出来的一个开关。它真正有意思的地方,在于它把 ABAP 后端开发里那些原本需要手工点击、手工创建、手工激活、手工查服务元数据的动作,包装成一组可以被 GitHub Copilot 这类 coding agent 调用的工具。SAP 在 RAP130 练习里把它描述为运行在 ADT for Visual Studio Code 扩展内部的本地 HTTP Server,它实现的是 Model Context Pro

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 181

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

doris创建表出现Failed to find 3 backends for policy解决方案

BE节点少于3个的且未指定副本数时 会报以上错误。一种时增加BE节点数,另一种方式时创建表里设置副本数参数。如果 BE 节点数量小于3,则需指定副本数小于等于 BE 节点数量。在 0.15 版本后,该属性将自动转换成。

rjbcxhc的专栏 8364

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Doris--简单使用

doris 简单使用

chbxw 1187

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Doris Sequence 列

doris 数据导入顺序

qq_15138049的博客 978

基于Doris构建的小程序私域流量增长

小程序目前使用百度云 Palo(Apache Doris 企业版)承载其精细化运营业务。通过本文可以帮助大家了解在 Doris 中使用全局字典、BITMAP 等功能时遇到的问题、解决思路和优化方案。

SmartSi 625

Apache Doris 系列: 入门篇-创建数据表

我们在成功部署完成 Doris 之后,我们可以通过任意 MySQL 客户端来连接 Doris ,下面我们的示例是通过 MySQL 客户端命令行工具来进行操作。命令来修改表的 Schema ,包括增加列,修改列类型、删除列、改变列的顺序。如果作业长时间没有完成,或者影响到了其他操作,你可以通过下面的命令来取消作业。我们执行完建表语句,表创建成功之后,我们可以通过下面的命令来查看表的相关信息。命令来查看创建好的数据库,这个命令会显示所有已经创建的数据库。,来满足不同用户场景的使用,下面我们以。

锋哥聊DORIS数仓 4773

doris建表报错:Failed to find 3 backends for policy

【代码】doris建表报错:Failed to find 3 backends for policy。

qq_40382400的博客 967
上一篇: Apache Doris 2.0.6 版本正式发布
下一篇: 阿里云 SelectDB 联合 DTS ,一键实现 TP 数据实时入仓
SelectDB技术团队
博客等级 码龄4年 2119粉丝 483原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SelectDB技术团队

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值