分区与分桶秉承着"大而化小,分而治之"的目标,目的都是为了便于查询,提高查询的效率。
分区的定义: 对数据进行水平切分,水平切分之后数据是完全物理隔离的,每个分区即为一个物理文件夹。
比如一个网站每天的埋点行为日志数据量比较大,在查询时进行全表扫描耗费的资源非常多。那在这个情况大数据体量下,可以按照每天日期对数据表进行分区,不同日期的数据存放在不同的分区下,在查询时只要指定分区字段的值就可以直接从该分区查找。
分桶的定义: 对数据进行垂直切分,各个分桶相互独立,每个分桶即为一个文件。
比如我们按照name列分为4个桶,就是对name列值的hash值对4取摸,按照取模结果对数据分桶。如取模结果为0的数据记录存放到一个文件,取模为1的数据存放到一个文件,取模为2的数据存放到一个文件、取模为3的数据存放到一个文件。
从上面可见,分区注重粗粒度,而分桶注重细粒度。同时需要注意的是这存在一定的担忧:分区容易造成数据倾斜。
今天主要讲讲,Doris分区与分桶。
Doris支持两级分区存储, 第一层为 range 分区,也可支持list方式, 第二层为 hash分桶。
(1)分区列必须为key列。
(2)分区列可以指定一列或多列。
(3)不论分区列是什么类型,在写分区值时,都需要加双引号。
(4)add partition添加分区,可以为该分区单独指定桶的数量。
通过 values less than (xxx) 仅指定上界,系统会将前一个分区的上界作为该分区的下界,生成一个左闭右开的区间。
同 Range Partition,当导入数据值在分区范围外,则不会被导入。
PARTITION BY RANGE (`dt`) ( PARTITION p_20220501 VALUES LESS THAN ("2022-05-01"), PARTITION p_20220502 VALUES LESS THAN ("2022-05-02"), PARTITION p_20220503 VALUES LESS THAN ("2022-05-03"), PARTITION p_20220504 VALUES LESS THAN ("2022-05-04") )
通过 VALUES IN (xxx) 来指定每个分区包含的枚举值,分区值为枚举值。只有当数据为目标分区枚举值其中之一时,才可以命中分区。
现List Partition 的分区列必须为 NOT NULL 列
PARTITION BY RANGE (`city_code`) ( PARTITION `p_city` VALUES IN ("1001", "1002", "1003") )
PARTITION BY LIST(`id`, `city_code`) ( PARTITION `p_id_city` VALUES IN (("1", "1000"), ("1", "1001")) )
表按date或datetime类型字段进行分区,对于新的数据,需要我们手动添加分区,和删除旧的分区,自动的总比手动的更加方便些。
PARTITION BY RANGE(dt)() PROPERTIES ( "dynamic_partition.enable" = "true", "dynamic_partition.time_unit" = "DAY", "dynamic_partition.end" = "3", "dynamic_partition.prefix" = "p", "replication_num" = "1" );
key |
说明 |
dynamic_partition.enable |
是否开启动态分区 |
dynamic_partition.time_unit |
区时间单位可以是hour、day、week、month。(yyyyMMddHH) |
dynamic_partition.start |
动态分区的起始偏移量,分区范围在此偏移之前的分区将会被删除,默认不删 |
dynamic_partition.end |
动态分区的结束偏移量,以当前为基准,提前创建对应范围的分区 |
dynamic_partition.prefix |
分区名前缀 |
以当前天(20220504)为基准,会提前创建三天的分区(20220505,20220506,20220507)
关掉动态分区
ALTER TABLE xxx SET ("dynamic_partition.enable" = "false")
删除分区
ALTER TABLE xxx DROP PARTITION p_20220504;
新建分区
ALTER TABLE xxx ADD PARTITION p_20220505 VALUES [('2022-05-05'), ('2022-05-06'));
查看分区
show partitions from xxx
DISTRIBUTED BY HASH(id) BUCKETS 10
(1)分桶列可以是多列,但必须为 Key 列。
(2)分桶列可以和分区列相同或不同。