列的基本类型,可以通过在 mysql-client
中执行 HELP CREATE TABLE
查看。
以 AGGREGATE KEY
数据模型为例进行说明(更多数据模型参阅 Doris 数据模型)。AGGREGATE KEY
数据模型中,所有没有指定聚合方式(SUM
、REPLACE
、MAX
、MIN
)的列视为 Key 列。而其余则为 Value 列。定义列时,可参照如下建议:
Doris 支持两层的数据划分。第一层是 Partition,支持 Range 和 List 的划分方式。第二层是 Bucket(Tablet),仅支持 Hash 的划分方式。也可以仅使用一层分区。使用一层分区时,只支持 Bucket 划分。
分区列通常为时间列,以方便的管理新旧数据。不可添加范围重叠的分区。
Partition 指定范围的方式:
VALUES LESS THAN (…)
仅指定上界,系统会将前一个分区的上界作为该分区的下界,生成一个左闭右开的区间。分区的删除不会改变已存在分区的范围。删除分区可能出现空洞。VALUES […)
同时指定上下界,生成一个左闭右开的区间。通过 VALUES […)
同时指定上下界比较容易理解。这里举例说明,当使用 VALUES LESS THAN (…)
语句进行分区的增删操作时,分区范围的变化情况:
以 上篇博客 中新建的 expamle_range_tbl
示例,当建表完成后,会自动生成如下 3 个分区:
p201701: [MIN_VALUE, 2017-02-01)
p201702: [2017-02-01, 2017-03-01)
p201703: [2017-03-01, 2017-04-01)
增加一个分区 p201705 VALUES LESS THAN (“2017-06-01”)
,分区结果如下:
p201701: [MIN_VALUE, 2017-02-01)
p201702: [2017-02-01, 2017-03-01)
p201703: [2017-03-01, 2017-04-01)
p201705: [2017-04-01, 2017-06-01)
此时删除分区 p201703
,则分区结果如下:
p201701: [MIN_VALUE, 2017-02-01)
p201702: [2017-02-01, 2017-03-01)
p201705: [2017-04-01, 2017-06-01)
注意到 p201702
和 p201705
的分区范围并没有发生变化,而这两个分区之间,出现了一个空洞:[2017-03-01, 2017-04-01)
。即如果导入的数据范围在这个空洞范围内,是无法导入的。
继续删除分区 p201702
,分区结果如下:
p201701: [MIN_VALUE, 2017-02-01)
p201705: [2017-04-01, 2017-06-01)
空洞范围变为:[2017-02-01, 2017-04-01)
现在增加一个分区 p201702new VALUES LESS THAN (“2017-03-01”)
,分区结果如下:
p201701: [MIN_VALUE, 2017-02-01)
p201702new: [2017-02-01, 2017-03-01)
p201705: [2017-04-01, 2017-06-01)
可以看到空洞范围缩小为:[2017-03-01, 2017-04-01)
现在删除分区 p201701
,并添加分区 p201612 VALUES LESS THAN (“2017-01-01”)
,分区结果如下:
p201612: [MIN_VALUE, 2017-01-01)
p201702new: [2017-02-01, 2017-03-01)
p201705: [2017-04-01, 2017-06-01)
即出现了一个新的空洞:[2017-01-01, 2017-02-01)
分区列支持 BOOLEAN
、TINYINT
、SMALLINT
、INT
、BIGINT
、LARGEINT
、DATE
、DATETIME
、CHAR
、VARCHAR
数据类型,分区值为枚举值。只有当数据为目标分区枚举值其中之一时,才可以命中分区。不可添加范围重叠的分区。
Partition 支持通过 VALUES IN (…)
来指定每个分区包含的枚举值。下面通过示例说明,进行分区的增删操作时,分区的变化。
(1)以 上篇博客 中新建的 example_list_tbl
示例,当建表完成后,会自动生成如下 3 个分区:
p_cn: ("Beijing", "Shanghai", "Hong Kong")
p_usa: ("New York", "San Francisco")
p_jp: ("Tokyo")
(2)增加一个分区 p_uk VALUES IN (“London”)
,分区结果如下:
p_cn: ("Beijing", "Shanghai", "Hong Kong")
p_usa: ("New York", "SanFrancisco")
p_jp: ("Tokyo")
p_uk: ("London")
(3)删除分区 p_jp
,分区结果如下:
p_cn: ("Beijing", "Shanghai", "Hong Kong")
p_usa: ("New York", "SanFrancisco")
p_uk: ("London")
如果使用了 Partition,则 DISTRIBUTED …
语句描述的是数据在各个分区内的划分规则。如果不使用 Partition,则描述的是对整个表的数据的划分规则。
分桶列可以是多列,但必须为 Key 列。分桶列可以和 Partition 列相同或不同。
分桶列的选择,是在 查询吞吐 和 查询并发 之间的一种权衡:
分桶的数量理论上没有上限。
以下场景推荐使用复合分区
在建表语句的最后 PROPERTIES 中,可以指定以下两个参数。
每个 Tablet 的副本数量。默认为 3 3 3,建议保持默认即可。在建表语句中,所有 Partition 中的 Tablet 副本数量统一指定。而在增加新分区时,可以单独指定新分区中 Tablet 的副本数量。
副本数量可以在运行时修改。强烈建议保持奇数。
最大副本数量取决于集群中独立 IP 的数量(注意不是 BE 数量)。Doris 中副本分布的原则是,不允许同一个 Tablet 的副本分布在同一台物理机上,而识别物理机即通过 IP。所以,即使在同一台物理机上部署了 3 3 3 个或更多 BE 实例,如果这些 BE 的 IP 相同,则依然只能设置副本数为 1 1 1。
对于一些小,并且更新不频繁的维度表,可以考虑设置更多的副本数。这样在 Join
查询时,可以有更大的概率进行本地数据 Join
。
BE 的数据存储目录可以显式的指定为 SSD(Solid State Disk,固态硬盘)或者 HDD(Hard Disk Drive,机械硬盘),通过 .SSD
或者 .HDD
后缀区分。建表时,可以统一指定所有 Partition 初始存储的介质。注意,后缀作用是显式指定磁盘介质,而不会检查是否与实际介质类型相符。
默认初始存储介质可通过 FE 的配置文件 fe.conf
中指定 default_storage_medium=xxx
,如果没有指定,则默认为 HDD。如果指定为 SSD,则数据初始存放在 SSD 上。
注意,当指定 storage_medium
时:
enable_strict_storage_medium_check
为 False
,该参数只是一个 “尽力而为” 的设置。即使集群内没有设置 SSD 存储介质,也不会报错,而是自动存储在可用的数据目录中。 同样,如果 SSD 介质不可访问、空间不足,都可能导致数据初始直接存储在其他可用介质上。而数据到期迁移到 HDD 时,如果 HDD 介质不可访问 、 空间不足 , 也可能迁移失败 (但是会不断尝试) 。enable_strict_storage_medium_check
为 True
,则当集群内没有设置 SSD 存储介质时,会报错 Failed to find enough host in all backends with storage medium is SSD
。如果没有指定 storage_cooldown_time
,则默认
30
30
30 天后,数据会从 SSD 自动迁移到 HDD 上。如果指定了 storage_cooldown_time
,则在到达 storage_cooldown_time
时间后,数据才会迁移。
本示例中,ENGINE 的类型是 olap
,即默认的 ENGINE 类型。在 Doris 中,只有这个 ENGINE 类型是由 Doris 负责数据管理和存储的。其他 ENGINE 类型,如 mysql
、broker
、es
等等,本质上只是对外部其他数据库或系统中的表的映射,以保证 Doris 可以读取这些数据。而 Doris 本身并不创建、管理和存储任何非 olap
ENGINE 类型的表和数据。