Doris主要支持的表类型即为数据模型,主要分为3类:
Aggregate,聚合模型
Unique,主键唯一模型
Duplicate,明细模型
建表语法
通用的建表语法如下
CREATE TABLE [IF NOT EXISTS] [database.]table
(
column_definition_list,
[index_definition_list]
)
[engine_type]
[keys_type]
[table_comment]
[partition_info]
distribution_desc
[rollup_list]
[properties]
[extra_properties]
常用参数说明:
engine_type , 表引擎类型。默认是OLAP ,其它类型的目前支持有 MYSQL、BROKER、HIVE、ICEBERG 、HUDI
olap引擎第一个字段不能是float, double, string类型,可以使用decimal 或者varchar
key_type ,数据模型
UPLICATE KEY(默认):其后指定的列为排序列。
AGGREGATE KEY:其后指定的列为维度列。
UNIQUE KEY:其后指定的列为主键列。
table_comment ,表注释
partition_desc ,分区信息
distribution_desc ,数据分桶定义
Hash 分桶 语法:
DISTRIBUTED BY HASH (k1[,k2 ...]) [BUCKETS num]
说明:使用指定的 key 列进行哈希分桶。Random 分桶 语法:
DISTRIBUTED BY RANDOM [BUCKETS num]
说明:使用随机数进行分桶。rollup_list 。建表的同时可以创建多个物化视图(ROLLUP)
properties ,表属性设置,有以下参数项
replication_num 。副本数,默认为3,新版本使用参数 replication_allocation 指定
in_memory , Doris 是没有内存表 ,这个属性设置成
true
, Doris 会尽量将该表的数据块缓存在存储引擎的 PageCache 中,已减少磁盘IO。但这个属性不会保证数据块常驻在内存中,仅作为一种尽力而为的标识。compression ,压缩方式默认压缩方式是 LZ4
数据模型
Aggregate
聚合模型 ,与clickhouse的AggregatingMergeTree引擎原理一样,但没有clickhouse支持的聚合函数多
目前支持以下四种聚合方式:
SUM:求和,多行的 Value 进行累加。
REPLACE:替代,下一批数据中的 Value 会替换之前导入过的行中的 Value。
MAX:保留最大值。
MIN:保留最小值。
使用例子
创建一张聚合模型的表,定义了 AGGREGATE KEY 和 AGGREGATE VALUE(last_visit_date,cost,max_dwell_time,min_dwell_time)
CREATE TABLE IF NOT EXISTS example_tbl
(
`user_id` LARGEINT NOT NULL COMMENT "用户id",
`date` DATE NOT NULL COMMENT "数据灌入日期时间",
`city` VARCHAR(20) COMMENT "用户所在城市",
`age` SMALLINT COMMENT "用户年龄",
`sex` TINYINT COMMENT "用户性别",
`last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 00:00:00" COMMENT "用户最后一次访问时间",
`cost` BIGINT SUM DEFAULT "0" COMMENT "用户总消费",
`max_dwell_time` INT MAX DEFAULT "0" COMMENT "用户最大停留时间",
`min_dwell_time` INT MIN DEFAULT "99999" COMMENT "用户最小停留时间"
)
AGGREGATE KEY(`user_id`, `date`, `city`, `age`, `sex`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 1
PROPERTIES (
"replication_allocation" = "tag.location.default: 1"
);
多次插入数据然后查看数据内容
insert into example_tbl values(10000,'2017-10-01','广州','18','1','2023-03-24 10:03:35',100,10,20);
select * from example_tbl
10000 2017-10-01 广州 18 1 2023-03-24 10:03:35 100 10 20
insert into example_tbl values(10000,'2017-10-01','广州','18','1','2023-03-24 11:03:35',100,100,200);
select * from example_tbl
10000 2017-10-01 广州 18 1 2023-03-24 11:03:35 200 100 20
在第二次插入后,数据按照我们定义的聚合方式进行了汇总。
也可以对聚合模型的数据进行删除
delete from example_tbl where user_id =10000;注意,对于删除的语法,这个版本只支持指定的值删除,不支持关联表删除,例如
--
delete from example_tbl
where user_id in(select user_id from example_tbl2 where user_id=10000)
SQL 错误 [1105] [HY000]: errCode = 2, detailMessage = Child of in predicate should be value
--
delete from example_tbl a
using example_tbl2 b
where b.user_id=a.user_id and b.user_id=10000
SQL 错误 [1105] [HY000]: errCode = 2, detailMessage = Syntax error in line 2:
读时合并
聚合模型在数据写入时并在最后的模型聚合会有一定的延迟性,所以查最终数据时,需要与clickhouse的聚合模型方法一样,对最终的模型表再进行聚合操作后的数据才能保证正确。
Unique
主键唯一模型
实际就是聚合模型Aggregate,只是聚合函数都是使用REPLACE来保证主键的唯一
建表示例
CREATE TABLE IF NOT EXISTS example_db.example_tbl
(
`user_id` LARGEINT NOT NULL COMMENT "用户id",
`username` VARCHAR(50) NOT NULL COMMENT "用户昵称",
`city` VARCHAR(20) COMMENT "用户所在城市",
`age` SMALLINT COMMENT "用户年龄",
`sex` TINYINT COMMENT "用户性别",
`phone` LARGEINT COMMENT "用户电话",
`address` VARCHAR(500) COMMENT "用户地址",
`register_time` DATETIME COMMENT "用户注册时间"
)
UNIQUE KEY(`user_id`, `username`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 1
PROPERTIES (
"replication_allocation" = "tag.location.default: 1"
);
使用UNIQUE KEY关键字
与下面建表sql一样
CREATE TABLE IF NOT EXISTS example_db.example_tbl
(
`user_id` LARGEINT NOT NULL COMMENT "用户id",
`username` VARCHAR(50) NOT NULL COMMENT "用户昵称",
`city` VARCHAR(20) REPLACE COMMENT "用户所在城市",
`age` SMALLINT REPLACE COMMENT "用户年龄",
`sex` TINYINT REPLACE COMMENT "用户性别",
`phone` LARGEINT REPLACE COMMENT "用户电话",
`address` VARCHAR(500) REPLACE COMMENT "用户地址",
`register_time` DATETIME REPLACE COMMENT "用户注册时间"
)
AGGREGATE KEY(`user_id`, `username`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 1
PROPERTIES (
"replication_allocation" = "tag.location.default: 1"
);
使用AGGREGATE聚合模型,指定聚合函数为REPLACE
写时合并
Unique模型的写时合并实现没有聚合模型的局限性 ,可以实现在数据写入时就进行合并,但这功能默认是关闭的,需要添加下面的property来开启 ,且只能在建表时通过指定property的方式打开
"enable_unique_key_merge_on_write" = "true"Duplicate
明细模型,与clickhouse的MergeTree引擎一样。
DUPLICATE KEY是用来指明底层数据按照那些列进行排序 ,相当于ck的排序键。
DUPLICATE KEY注意事项:
并且指定的字段顺序要放在建表字段前顺序一致。
字段类型不能为String
如果没有指定,默认为第一个
建表示例
drop table table_hash;
CREATE TABLE table_hash
(
k1 DATE,
k2 DECIMAL(10, 2) DEFAULT "10.5",
k3 CHAR(10) COMMENT "string column",
k4 INT NOT NULL DEFAULT "1" COMMENT "int column"
)
DUPLICATE KEY(k1, k2)
COMMENT "my first table"
PARTITION BY RANGE(k1)
(
PARTITION p1 VALUES LESS THAN ("2020-02-01"),
PARTITION p2 VALUES LESS THAN ("2020-03-01"),
PARTITION p3 VALUES LESS THAN ("2020-04-01")
)
DISTRIBUTED BY HASH(k1) BUCKETS 32
PROPERTIES (
"replication_num" = "1"
);
插入3行数据
insert into table_hash values('2020-02-01',1.2,'a',1);
insert into table_hash values('2020-02-01',1.3,'a',1);
insert into table_hash values('2020-02-02',1.4,'b',2);
MySQL [test]> select * from table_hash;
+------------+------+------+------+
| k1 | k2 | k3 | k4 |
+------------+------+------+------+
| 2020-02-01 | 1.20 | a | 1 |
| 2020-02-01 | 1.30 | a | 1 |
| 2020-02-02 | 1.40 | b | 2 |
+------------+------+------+------+
删除明细表的数据
如果是分区表,需要指定分区
如果不是分区表,直接delete可以成功
MySQL [test]> delete from table_hash where k4=1;
ERROR 1105 (HY000): errCode = 2, detailMessage = errCode = 2, detailMessage = This is a range or list partitioned table. You should specify partition in delete stmt, or set delete_without_partition to true
MySQL [test]> delete from table_hash PARTITION p2 where k4=1;
Query OK, 0 rows affected (0.05 sec)
{'label':'delete_311df3bf-38d9-453b-907f-915c3baeb777', 'status':'VISIBLE', 'txnId':'315674'}
MySQL [test]> select * from table_hash;
+------------+------+------+------+
| k1 | k2 | k3 | k4 |
+------------+------+------+------+
| 2020-02-02 | 1.40 | b | 2 |
+------------+------+------+------+
删除所有数据,要使用truncate
MySQL [test]> delete from table_hash ;
ERROR 1105 (HY000): errCode = 2, detailMessage = Where clause is not set
MySQL [test]> truncate table table_hash ;
Query OK, 0 rows affected (0.05 sec)
数据模型的选择建议
因为数据模型在建表时就已经确定,且无法修改。所以,选择一个合适的数据模型非常重要。
Aggregate 模型可以通过预聚合,极大地降低聚合查询时所需扫描的数据量和查询的计算量,非常适合有固定模式的报表类查询场景。但是该模型对 count(*) 查询很不友好。同时因为固定了 Value 列上的聚合方式,在进行其他类型的聚合查询时,需要考虑语意正确性。
Unique 模型针对需要唯一主键约束的场景,可以保证主键唯一性约束。但是无法利用 ROLLUP 等预聚合带来的查询优势。
对于聚合查询有较高性能需求的用户,推荐使用自1.2版本加入的写时合并实现。
Unique 模型仅支持整行更新,如果用户既需要唯一主键约束,又需要更新部分列(例如将多张源表导入到一张 doris 表的情形),则可以考虑使用 Aggregate 模型,同时将非主键列的聚合类型设置为 REPLACE_IF_NOT_NULL。
Duplicate 适合任意维度的 Ad-hoc 查询。虽然同样无法利用预聚合的特性,但是不受聚合模型的约束,可以发挥列存模型的优势(只读取相关列,而不需要读取所有 Key 列)。




