这里有一些很好的问题/答案
配置单元在多个列上聚集
使用群集的 Hive 子查询优化依据
蜂巢中的 Cluster By 和 CLUSTERED BY 之间的区别?
在 Hive 中对表进行分区和存储桶有什么区别?
但是我还有一些,不幸的是,第 24 页没有很好的解释: https://docs.hortonworks.com/HDPDocuments/HDP3/HDP-3.0.1/using-hiveql/hive_using_hiveql.pdf
我的问题:
在下面的例子中:
CREATE TABLE pageviews (userid VARCHAR(64), link STRING, from STRING)
PARTITIONED BY (datestamp STRING) CLUSTERED BY (userid) INTO 256 BUCKETS;
INSERT INTO TABLE pageviews PARTITION (datestamp = '2014-09-23') VALUES
('jsmith', 'mail.com', 'sports.com'), ('jdoe', 'mail.com', null);
INSERT INTO TABLE pageviews PARTITION (datestamp) VALUES ('tjohnson',
'sports.com', 'finance.com', '2014-09-23'), ('tlee', 'finance.com', null,
'2014-09-21');
为什么网页浏览的架构中不存在"日期戳字符串"?
为什么它被定义为字符串?不应该是时间戳?
为什么第二个插入缺少它并且只有它作为类型,但它有作为值(即'2014-09-23'和'2014-09-21?
日期戳字符串"在网页浏览的架构中不存在?
尽管日期戳的外观和行为类似于架构中定义的标准列,但它实际上只是对表的基础数据的特定分区的引用。当您在日期戳列中看到"2014-09-23"时,它实际上并没有显示其中一个数据文件的特定记录中包含的值,而是告诉您行其余部分的数据来自名为"datestamp=2014-09-23"的HDFS目录,其中包含数据的分区或"块"。这是很多优化的结果,因为将查询过滤到特定分区允许 Hive 简单地转到该特定目录中的数据并忽略其他 n 个分区中包含的数据。
为什么它被定义为字符串?应该是时间戳?
由于分区只是引用目录名称,因此只有该类型是特定日期格式的字符串表示形式而不是时间戳或日期才有意义。从概念上讲,日期字段没有意义,因为尽管"2014-09-23"和"9/23/2014"是两个相等的日期戳,但如果它们是目录名称,它们将被视为不同的目录。换句话说,如果一个目录被命名为"2014-09-23",则不能用任何其他名称来引用它,使其更像一个字符串,而不像一个具有许多等效替代形式的日期。此外,Hive已经将日期视为字符串,这使得它比int类型更好的解决方案。例如,如果将时间戳传递给 Hive 的 to_date(( 用户定义函数,它将日期作为字符串返回。
此外,由于您提到了时间戳,因此使用包含几分之一秒的完整时间戳对于分区来说是一个坏主意,即使您使用它的字符串表示形式也是如此。您最终会得到大量的分区,每个分区中可能只有一条或最多只有几条记录。我想您很快就会失去分区的任何性能优势。
为什么第二个插入缺少它并且只有它作为类型,但它有作为值(即'2014-09-23'和'2014-09-21?
这只是产生相同结果的不同语法。包含分区时,Hive 将假定值数组末尾的值引用分区。因此,如果您的表在架构中包含 3 列和 1 个分区,则当您执行插入表命令并指定分区(日期戳(时,您只需传入 4 个值,Hive 就会知道前 3 个值将插入到架构中的 3 列中,第四个值是指要将此记录的数据添加到哪个日期戳分区。