大数据Hadoop学习七

博客二:Hive数据操作、复杂类型与性能优化策略

摘要: 本文是Hive入门的第二周学习总结,聚焦于数据的导入导出、复杂数据类型的应用,以及通过分区和分桶来优化查询性能的核心策略,是构建高效数据仓库的关键。

一、数据操作语言(DML):加载与导出

  1. 使用LOAD命令加载数据
    LOAD DATA是一个高效的数据移动命令。

    -- 从本地Linux文件系统加载(复制文件)
    LOAD DATA LOCAL INPATH '/path/to/local/file.txt' INTO TABLE my_table;
    
    -- 从HDFS加载(移动文件)
    LOAD DATA INPATH '/path/on/hdfs/file.txt' INTO TABLE my_table;
    
    -- 覆盖加载(覆盖原有数据)
    LOAD DATA LOCAL INPATH '/path/to/local/file.txt' OVERWRITE INTO TABLE my_table;
    

    关键区别LOCAL关键字表示本地系统,否则是HDFS。从HDFS加载是移动操作,原始文件会消失;从本地加载是复制操作。

  2. 使用INSERT导出数据
    INSERT语句提供了更灵活的数据导出方式。

    -- 将查询结果导出到本地目录,使用默认分隔符
    INSERT OVERWRITE LOCAL DIRECTORY '/tmp/export1'
    SELECT * FROM employees;
    
    -- 导出到本地并指定分隔符
    INSERT OVERWRITE LOCAL DIRECTORY '/tmp/export2'
    ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
    SELECT * FROM employees;
    
    -- 导出到HDFS(省略LOCAL关键字)
    INSERT OVERWRITE DIRECTORY '/hdfs/export'
    ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
    SELECT * FROM employees;
    

二、复杂数据类型:让数据模型更丰富

Hive支持三种主要的复杂数据类型,用于处理非标准化的数据。

  1. Array(数组)
    用于存储同类型的元素集合。
    数据示例 (data.txt):

    zhangsan    beijing,shanghai,tianjin
    lisi        changchun,chengdu
    

    建表语句

    CREATE TABLE test_array (
      name STRING,
      work_locations ARRAY<STRING> -- 定义数组类型
    ) ROW FORMAT DELIMITED
    FIELDS TERMINATED BY '\t' -- 列分隔符
    COLLECTION ITEMS TERMINATED BY ','; -- 数组元素分隔符
    

    常用查询

    -- 查询所有
    SELECT * FROM test_array;
    -- 查询数组第一个元素
    SELECT name, work_locations[0] AS first_city FROM test_array;
    -- 查询数组元素个数
    SELECT name, SIZE(work_locations) AS city_count FROM test_array;
    -- 判断数组是否包含某元素
    SELECT * FROM test_array WHERE ARRAY_CONTAINS(work_locations, 'tianjin');
    
  2. Map(键值对)
    用于存储K-V对。
    数据示例
    1,John,father:Joe#mother:Mary#brother:David,28
    建表语句

    CREATE TABLE test_map (
      id INT,
      name STRING,
      family_members MAP<STRING,STRING>, -- K是STRING, V是STRING
      age INT
    ) ROW FORMAT DELIMITED
    FIELDS TERMINATED BY ',' -- 列分隔符
    COLLECTION ITEMS TERMINATED BY '#' -- Map之间的分隔符
    MAP KEYS TERMINATED BY ':'; -- K-V之间的分隔符
    

    常用查询

    -- 获取指定key的value
    SELECT id, name, family_members['father'] AS father FROM test_map;
    -- 获取所有key
    SELECT id, name, MAP_KEYS(family_members) AS relations FROM test_map;
    -- 获取所有value
    SELECT id, name, MAP_VALUES(family_members) AS names FROM test_map;
    
  3. Struct(结构体)
    类似于一个微型的表,可以包含多个带有名称和类型的子列。
    数据示例
    1#周杰轮:11
    建表语句

    CREATE TABLE test_struct (
      id STRING,
      info STRUCT<name:STRING, age:INT> -- 定义结构体,包含子列
    ) ROW FORMAT DELIMITED
    FIELDS TERMINATED BY '#' -- 列分隔符
    COLLECTION ITEMS TERMINATED BY ':'; -- 结构体子列分隔符
    

    常用查询

    -- 查询所有,包括子列
    SELECT * FROM test_struct;
    -- 通过‘.’访问子列
    SELECT id, info.name, info.age FROM test_struct;
    

三、性能优化利器:分区与分桶

  1. 分区表(Partitioned Table)
    概念:根据某一列的值(如日期、地区)在HDFS上创建不同的子目录,查询时通过WHERE筛选分区,可以避免全表扫描,极大提升查询性能。

    -- 创建一个按日期分区的日志表
    CREATE TABLE logs (
      id INT,
      message STRING
    ) PARTITIONED BY (dt STRING) -- 分区字段
    ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
    
    -- 向特定分区加载数据
    LOAD DATA LOCAL INPATH './log_20231027.txt' INTO TABLE logs PARTITION (dt='2023-10-27');
    -- 查询特定分区数据,效率极高
    SELECT * FROM logs WHERE dt = '2023-10-27';
    
  2. 分桶表(Bucketed Table)
    概念:根据指定列的Hash值模除分桶数量,将数据分散到固定数量的文件中。适用于大数据量的JOIN、采样和高效过滤

    -- 开启分桶优化
    SET hive.enforce.bucketing = true;
    -- 创建一个按用户ID分桶的表,分为4个桶
    CREATE TABLE user_bucketed (
      id INT,
      name STRING
    ) CLUSTERED BY (id) INTO 4 BUCKETS;
    

    关键点:分桶表的数据加载不能使用LOAD DATA,必须使用INSERT SELECT来触发MapReduce计算Hash值,从而正确分桶。

    -- 正确方式:通过查询插入数据以实现分桶
    INSERT OVERWRITE TABLE user_bucketed
    SELECT * FROM users;
    

四、总结

本周我们深入学习了Hive的数据操作,掌握了如何高效地导入导出数据。通过Array、Map、Struct三种复杂数据类型,我们能够更自然地在Hive中建模复杂业务数据。最后,分区和分桶作为Hive最核心的性能优化手段,帮助我们构建出高效、可扩展的数据仓库结构,为应对海量数据查询挑战打下了坚实基础。

下一周,我们将进入HiveQL的实战阶段,学习各类查询语法、函数,并最终完成一个从数据清洗、分析到可视化展示的完整项目案例。


posted @ 2025-09-07 16:01  haoyinuo  阅读(8)  评论(0)    收藏  举报