在使用传统的RDBMS数据库(关系数据库),例如MySql时,对于一些大表,我们通常会进行分表操作,以提升查询效率。在Hive中也提供了类似的概念和操作,本文将对其进行讲述。
RDBMS中的分表操作
假设有一张订单表OrderInfo,简化一下,字段分别为:订单Id OrderId、卖家 Retailer、买家 Customer、订单金额 OrderAmount、下单日期 OrderDate。比较常见的做法有两种:一种是按年分表,例如建OrderInfo_2018、OrderInfo_2017。按年分表的问题是如果查询不基于时间,例如查询某个单号、查询某个买家/卖家的所有订单,则依然要全表查找(所有按年分的表都要查)。类似地,也可以按卖家进行分表。按卖家分表(或者类似的其他字段)的问题在于:数据分布不一致,会造成有的表数据极多,有的表数据极少。
可以实际地建两张表 OrderInfo_2018、OrderInfo_2017,也可以隐式地建,对数据库的上层应用不可见(表名仍然为OrderInfo)。隐式建表有时会有一些限制,也需要对数据库有更深一些的了解,因此,很多开发人员直接显式地创建多张不同表。
还有一种是按单号的Hash值取模进行分表,假设分4张表(OrderInfo_0~OrderInfo_3),那么具体某个订单存入哪张表,规则是 Hash(OrderId)%4,根据余数决定存入那张表。根据这种方式分表,优点是可以提升基于单号的查找速度,以及对于单号的join连接查询。但是如果针对某个买家或者时间段来查询,又需要全表查询。使用这种方式还有一个缺陷就是不好扩表,假设开始时设计了4张表(除4取余),后来单表数据仍然很多,想要重新改为8张表(除8取余),此时就需要将现有表中的记录重新进行计算并迁移到对应的表中。
这两种方式,第一种可以视为连续的(基于时间连续,或者基于某个列连续,比如卖家),第二种则为离散的。有一种间接的改进策略可以集成两种方式的优点,称为异构索引表。具体可以参看这里:企业IT架构转型之道。
Hive中的表分区
Hive中的表分区和上面RDBMS的第一种方式极为类似,用来对连续的数据进行分区。Hive中的表存储在HDFS上,HDFS是一个分布式文件系统,通过目录来对文件进行组织和管理。Hive中的一张表对应HDFS上的一个或者多个文件。创建一个Hive的表分区