1、Hive中建内表和外表的区别是什么?如何建分区表?
内部表(Internal table):内部表也称为被Hive拥有和管理的托管表(Managed table)。默认情况下创建的表就是内部表,Hive拥有该表的结构和文件。换句话说,Hive完全管理表(元数据和数据)的生命周期。
外部表(External table):外部表中的数据不是Hive拥有或管理的,只管理表元数据的生命周期。
区别 | 内部表 | 外部表 |
创建 | 内部表不需要指定数据存储的路径,直接将数据存储在默认的目录中 | 外部表需要使用external关键字指定,需要使用location指定存储数据的位置 |
删除 | 内部表的数据和元数据都是由hive来管理的,删除的时候全部删除 | 外部表的数据由hdfs管理,元数据由hive管理,删除的时候只删除元数据,数据不会删除 |
分区表:当Hive表对应的数据量大、文件多时,为了避免查询时全表扫描数据,Hive支持根据用户指定的字段进行分区,分区的字段可以是日期、地域、种类等具有标识意义的字段。
创建分区表语法:
CREATE TABLE table_name (column1 data_type, column2 data_type) PARTITIONED BY (partition1 data_type, partition2 data_type,….);
注意:分区字段不能是表中已经存在的字段,因为分区字段最终也会以虚拟字段的形式显示在表结构上。
2、如何在hive中实现实现时间拉链?
拉链表适用于:数据量有点大,表中某些字段有变化,但是呢变化的频率也不是很高,业务需求呢又需要统计这种变化状态,每天全量一份呢,有点不太现实,不仅浪费了存储空间,有时可能业务统计也有点麻烦,这时,拉链表的作用就提现出来了,既节省空间,又满足了需求。
一般在数仓中通过增加begin_date,en_date来表示,如下图,后两列是start_date和end_date。
begin_date表示该条记录的生命周期开始时间,end_date表示该条记录的生命周期结束时间;
end_date = ‘9999-12-31’表示该条记录目前处于有效状态。
在hive中实现实现时间拉链:
1)拉链建表语句:
CREATE TABLE orders (
orderid INT,
createtime STRING,
modifiedtime STRING,
status STRING )
row format delimited fields terminated by '\t'
CREATE TABLE ods_orders_inc (
orderid INT,
createtime STRING,
modifiedtime STRING,
status STRING
) PARTITIONED BY (day STRING)
row format delimited fields terminated by '\t'
CREATE TABLE dw_orders_his (
orderid INT,
createtime STRING,
modifiedtime STRING,
status STRING,
dw_start_date STRING,
dw_end_date STRING
) row format delimited fields terminated by '\t' ;
准备好数据文件,向orders表中导入数据load data local inpath "/home/hadoop/orders.txt" into table orders;
2)第一次全量操作详解
第一步:抽取全量数据到ODS,先把到2016-08-20为止的数据初始化进去。
INSERT overwrite TABLE ods_orders_inc PARTITION (day = '2016-08-20')
SELECT orderid,createtime,modifiedtime,status
FROM orders
WHERE createtime < '2016-08-21' and modifiedtime <'2016-08-21';
第二步:从ODS刷新到DW。
INSERT
overwrite TABLE dw_orders_his
SELECT orderid,createtime,modifiedtime,status,
createtime AS dw_start_date,
'9999-12-31' AS dw_end_date
FROM ods_orders_inc
WHERE day = '2016-08-20';
3)进行增量更新
INSERT overwrite TABLE ods_orders_inc PARTITION (day = '2016-08-21')
SELECT orderid,createtime,modifiedtime,status
FROM orders
WHERE (createtime = '2016-08-21' and modifiedtime = '2016-08-21') OR modifiedtime = '2016-08-21';
通过DW历史数据(数据日期为2016-08-20),和ODS增量数据(2016-08-21),刷新历史表
//1、判断失效值,
//2、判断有效值
//3、通过UNION ALL进行联合
DROP TABLE IF EXISTS dw_orders_his_tmp;
CREATE TABLE dw_orders_his_tmp AS
SELECT orderid,
createtime,
modifiedtime,
status,
dw_start_date,
dw_end_date
FROM (
//判断失效值
SELECT a.orderid,
a.createtime,
a.modifiedtime,
a.status,
a.dw_start_date,
CASE WHEN b.orderid IS NOT NULL AND a.dw_end_date > '2016-08-21' THEN '2016-08-21' ELSE a.dw_end_date END AS dw_end_date
FROM dw_orders_his a
left outer join (SELECT * FROM ods_orders_inc WHERE day = '2016-08-21') b
ON (a.orderid = b.orderid)
UNION ALL
//判断有效值
SELECT orderid,
createtime,
modifiedtime,
status,
modifiedtime AS dw_start_date,
'9999-12-31' AS dw_end_date
FROM ods_orders_inc
WHERE day = '2016-08-21'
) x
ORDER BY orderid,dw_start_date;
INSERT overwrite TABLE dw_orders_his
SELECT * FROM dw_orders_his_tmp;
再根据上面步骤把2016-08-22号的数据更新进去,就得到了我们想要的数据。
3、传统的关系型数据库和大数据有什么区别?
比较内容 | 数据仓库的特征 | 常规事务处理数据库 |
目标 | OLAP联机分析处理 | OLTP联机事务处理 |
作用 | 面向主题 | 面向过程 |
活动持征 | 分析式 | 事务处理 |
构成 | 集成 | 不同的、分散的 |
内容 | 不更改性 | 更改的 |
时间性 | 时序性、历史性 | 当前的 |
基础结构 | 多维型 | 关系型 |
关系结构 | 星型/雪花型结构或混杂型结构 | 3NF三级范式 |
终端用户 | 多为管理人员和决策者 | 多为专业及操作人员 |
4、传统的sql语句和Hive中的hql有什么区别,各自的优缺点是什么?它们在机器中执行的过程是什么样子的?
Hive的查询语言是HQL,HQL支持SQL-92标准,所以与SQL非常相似。但Hive是基于Hadoop,而SQL通常是基于关系型数据库。
用法上的区别:
- HQL不支持行级别的增、改、删,所有数据在加载时就已经确定,不可更改。
- 不支持事务。
- 支持分区存储。
语法上的区别:
区别点 | HQL | SQL |
注释符 | -- | # |
数据类型 | 基本数据类型,如:int, float等 复杂数据类型 struct、map、array | 仅支持基本数据类型 |
删除非空数据库 | drop database cascade | drop database |
返回对于右表满足判定条件的左表 | left semi join | in |
优缺点:
HQL | SQL | |
优点 | 类似于SQL,但具有更宽松的语法。Hive支持大规模数据的分布式查询和分析,适用于处理大数据集和复杂查询。 | 具有成熟的标准化语法和庞大的生态系统。它适用于结构化数据的查询和操作,并具有广泛的支持和工具。 |
缺点 | 对于传统SQL,Hive的执行速度较慢,因为它的查询经过了复杂的转换和作业调度,需要将HQL转化为底层的MapReduce任务。此外,Hive的实时性较差,不适合对实时数据进行处理 | 在大数据处理方面存在一定局限性。难以对海量数据进行高效处理,特别是在分布式环境下,性能可能受限。 |
传统的SQL语句执行过程:
1)客户端向数据库发送SQL命令。
2)数据库接收到命令后进行语法解析和语义验证。
3)执行计划生成:数据库优化器生成最优的执行计划。
4)执行计划执行:数据库执行引擎根据执行计划执行SQL查询。
5)返回结果给客户端。
Hive中的HQL执行过程:
1)客户端向Hive发送HQL命令。
2)Hive将HQL转化为底层的MapReduce或Tez作业。
3)作业调度器将作业提交给集群的资源管理器(如YARN)。
4)资源管理器分配资源,并将作业分成多个任务在集群中运行。
5)任务执行:每个任务在相应的节点上执行Map和Reduce操作。
6)结果汇总:各个任务的结果被汇总并返回给客户端。
5、如果两个人同时对一张表进行更新操作会出现什么情况?怎么解决这个问题?
可能会出现以下情况:
丢失更新:当两个人同时对同一行数据进行更新时,最后提交的更新会覆盖之前的更新,导致之前的更新操作丢失。
脏读:一个人在更新数据的同时,另一个人读取了未提交的更新结果,导致读取到不一致或错误的数据。
可以采取的措施:
1)乐观锁(Optimistic Locking):在每一行数据中添加一个版本号字段,每次更新时先检查版本号是否匹配,如果不匹配则表示其他人已经修改过该数据,需要进行相应的处理,如回滚或报错。这种方式不会阻塞其他用户的读操作,但可能需要重新执行更新操作。
2)悲观锁(Pessimistic Locking):在更新数据时对该行数据进行加锁,直到事务提交后才释放锁,从而防止其他人对同一行数据的并发操作。这种方式可以确保数据的一致性,但可能导致其他用户在锁定期间等待,降低系统的并发性能。
3)分布式锁:使用分布式锁机制,如基于Redis、ZooKeeper等的分布式锁,确保在更新操作期间只有一个人能够持有锁,从而避免并发更新问题。
4)时间戳(Timestamp):在每一行数据中添加一个时间戳字段,记录最后更新的时间。在更新操作时,比较时间戳,判断更新操作的先后顺序,从而避免丢失更新和脏读问题。
5)冲突检测与解决:当出现并发更新冲突时,系统可以通过检测到更新冲突,并提供冲突解决机制,如自动合并、冲突通知等方式,让用户自行解决更新冲突。
注意:具体应该根据具体的业务场景和系统架构来选择和实施。