前面的解释中缺少一些细节。为了更好地了解分区和存储的工作原理,您应该查看数据在hive中的存储方式。假设您有一张桌子

CREATE TABLE mytable (
name string,
city string,
employee_id int )
PARTITIONED BY (year STRING, month STRING, day STRING)
CLUSTERED BY (employee_id) INTO 256 BUCKETS

然后配置单元将在目录层次结构中存储数据,例如

/user/hive/warehouse/mytable/y=2015/m=12/d=02

因此,在分区时必须格外小心,因为例如,如果按employee_id进行分区,并且拥有数百万个员工,那么文件系统中最终将拥有数百万个目录。术语“ 基数 ”是指字段可以具有的可能值的数量。例如,如果您有一个“国家”字段,那么世界上的国家大约为300个,因此基数约为300。对于“ timestamp_ms”这样的字段(每毫秒更改一次),基数可以达到数十亿。通常,在选择要进行分区的字段时,它的基数应该不高,因为文件系统中的目录太多了。

另一方面,由于也指定了存储桶的数量,因此集群化也称为存储桶将具有固定数量的文件。配置单元将执行的操作是获取字段,计算哈希值并将记录分配给该存储桶。但是,如果您使用256个存储桶,而您正在存储的字段具有低基数(例如,这是美国州,那么只能有50个不同的值)会发生什么?您将拥有50个带数据的存储桶,以及206个无数据的存储桶。

有人已经提到分区如何可以极大地减少您查询的数据量。因此,在我的示例表中,如果只想从某个日期开始查询,按年/月/日进行分区将大大减少IO数量。我认为有人也提到了存储桶如何加快与具有完全相同存储桶的其他表的联接,因此在我的示例中,如果要在同一个employee_id上连接两个表,hive可以逐桶进行联接存储桶(甚至更好)如果它们已经由employee_id进行了排序,因为它将用于合并已排序的部分,这将在线性时间(即O(n))中起作用。

因此,当字段具有高基数并且数据在存储桶之间均匀分布时,存储桶可以很好地工作。当分区字段的基数不太高时,分区效果最好。

另外,您可以按顺序在多个字段上进行分区(年/月/日是一个很好的示例),而只能在一个字段上进行存储。