2016-08-04 84 views
4

讓我們想象一下我每天一個文件存儲格式:按日期範圍閱讀蜂巢表中的多個文件

/path/to/files/2016/07/31.csv 
/path/to/files/2016/08/01.csv 
/path/to/files/2016/08/02.csv 

我如何讀取指定日期範圍在一個蜂巢表中的文件(例如從2016-06-04到2016-08-03)?

+0

您是否允許更改文件結構/名稱? – cheseaux

+0

@cheseaux只有當沒有其他選項時:) –

回答

2

假設每一個文件都遵循相同的模式,那麼我建議您將文件存儲與以下命名約定:

/path/to/files/dt=2016-07-31/data.csv 
/path/to/files/dt=2016-08-01/data.csv 
/path/to/files/dt=2016-08-02/data.csv 

然後,您可以創建一個外部表由dt分區和指向位置/path/to/files/

CREATE EXTERNAL TABLE yourtable(id int, value int) 
PARTITIONED BY (dt string) 
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' 
LOCATION '/path/to/files/' 

如果你有多個分區,不想寫alter table yourtable add partition ...查詢的每一個,你可以簡單地使用修復命令,將自動廣告d分區。

msck repair table yourtable 

然後,您可以簡單地通過指定分區範圍

SELECT * FROM yourtable WHERE dt BETWEEN '2016-06-04' and '2016-08-03' 
+0

謝謝。有趣的解決方案...讓我們等待一段時間,我希望看到沒有文件名修改的解決方案。順便說一句...請你澄清,你是否建議閱讀所有文件,並通過分區優化下一個SELECT? –

+1

外部表格不會讀取所有文件,只有在查詢表格時它纔會讀取,並且只會查看您在查詢中指定的分區(文件)。 – cheseaux

+0

我已經問過@waltersu - 閱讀的開銷是多少,讓我們來想象一下,按日期劃分的2000年日誌? –

0

不動你的文件中選擇一個日期範圍內的數據:

  1. 設計你的表模式。在蜂房殼,創建表(按日期分區)
  2. Loading files into tables
  3. 查詢與HiveQL(SELECT * FROM表,其中DT '2016年6月4日' 和 '2016年8月3日' 之間)

移動你的文件:

  1. 設計你的表模式。在蜂巢外殼,創建表(按日期分區)
  2. /path/to/files/2016/07/31.csv/dbname.db/tableName/dt=2016-07-31舉動,那麼你就必須 /dbname.db/tableName/dt=2016-07-31/file1.csv /dbname.db/tableName/dt=2016-08-01/file1.csv /dbname.db/tableName/dt=2016-08-02/file1.csv

  3. alter table tableName add partition (dt=2016-07-31);

負載分區見Add partitions

+0

是否可以避免加載所有文件?假設我有2000年的日誌:)並且只需幾個星期或幾個月就可以查詢它們。閱讀2000年(按日期劃分)日誌的開銷是多少? –

0

在Spark-shell中,閱讀配置單表

/path/to/data/user_info/dt=2016-07-31/0000-0 

1.創建SQL

val sql = "CREATE EXTERNAL TABLE `user_info`(`userid` string, `name` string) PARTITIONED BY (`dt` string) ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe' STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat' LOCATION 'hdfs://.../data/user_info'" 

2.運行它

spark.sql(sql) 

3.load數據

val rlt= spark.sql("alter table user_info add partition (dt=2016-09-21)") 

4。現在您可以從表

中選擇數據
val df = spark.sql("select * from user_info")