当前位置: 代码迷 >> 综合 >> Hive-模式设计
  详细解决方案

Hive-模式设计

热度:49   发布时间:2023-10-17 20:32:07.0

一、按天划分表

二、关于分区

通过创建分区可以优化一些查询,但同时也可能对其他一些重要的查询不利。
HDFS用于设计存储数百万的大文件,而非数十亿的小文件。使用分区可能导致的一个问题就是会创建大量的非必须的Hadoop文件和文件夹。一个分区就对应着一个包含有多个文件的文件夹。如果指定的表存在数百个分区,那么可能每天都会创建好几万个文件。如果保持这样的表很多年,那么最终会超出NameNode对系统云数据信息的处理能力。因为NameNode必须要将所有的系统文件的元数据信息保存在内存中。虽然每个文件只需要少量字节大小的元数据(大约时150字节/文件),但是这样也会限制一个HDFS实例所能管理的文件总数的上限。
MapReduce会将一个任务(job)转换成多个任务(task).默认情况下,每个task都是一个新的JVM实例,都需要开启和销毁的开销。对于小文件,每个文件都会对应一个task,在一些情况下,JVM开启和销毁的时间中销毁可能回避实际处理数据的时间消耗要长!
因此,一个理想的分区方案不应该导致产生太多的分区和文件夹目录,并且每个目录下的文件应该足够大,应该是文件系统中快大小的若干倍。

三、唯一键和标准化

Hive没有主键或基于序列密钥生成的自增键的概念。如果可以的话,应避免对非标准数据进行(JOIN)操作。复杂的数据类型,如array、map和struct,有助于实现在单行中存储一对多数据。这并不是说不应该进行标准化,但是星形架构类型设计并非最优的。
避免标准化的主要原因是为了最小化磁盘寻道,比如那些通常需要外键关系的情况。非标准化数据允许被扫描或写入到大的、连续的磁盘存储区域,从而优化磁盘驱动器的I/O性能。然而。非标准化数据可能导致数据的重复,而且有更大的导致数据不一致的风险。

四、同一份数据多种处理

Hive本身提供了一个独特的语法,它可以从数据源产生多个数据聚合,而无需每次聚合都要重新扫描一次。
hive> FROM history
> INSERT OVERWRITE sales SELECT * WHERE action='purchased'
> INSERT OVERWRITE credits SELECT * WHERE action='returned';

五、对于每个表的分区

六、分桶表数据存储

分桶是将数据集分解成更容易管理的若干部分的另一种技术。
hive> CREATE TABLE weblog (user_id INT, url STRING, source_ip STRING)
> PARTITIONED BY (dt STRING)
> CLUSTERED BY (user_id) INTO 996 BUCKETS;
对表weblog进行分桶,并使用user_id字段作为分桶字段,则字段值会根据用户指定的值进行哈希分发到桶中。同一个user_id下的记录通常会存储到同一个桶内,假设用户数要比桶数多得多,那么每个桶内就将会包含多个用户记录。

七、为表增加列

Hive允许在原始数据文件之上定义一个模式,而不是很多的数据库那样,要求必须以特定的格式转换和导入数据。这样的分离方式的好处是,当为数据文件增减新的字段时,可以容易地适应定义的模式。
Hive提供了SerDe抽象,其用于从输出中提取数据。SerDe同样用于输出数据,尽管输出功能并非经常使用,因为Hive主要用于查询,一个SerDe通常是从左到右进行解析的。