はじめに
小売業者には毎日新しいファイルが届きます。これまでのレポートでは、各行にある日付で記録を絞り込みました。パーティション分割テーブルでは、日付による整理をメタデータにも記録するため、クエリは指定日に対応する登録済みのデータの場所を選べます。
HDFS のファイルと、Hive の Metastore にあるパーティション記録の2つが合っている必要があります。Metastore はテーブルやパーティションの定義を保存するカタログです。ディレクトリを作るだけでは Hive パーティションは登録されません。新しい日のファイルを先に置き、後で登録することで、その違いを直接確かめます。
この実験では、2日分のファイルと、ローカルに届いた3日目のデータを独立して準備します。パーティション分割した外部テーブルを作り、場所を登録し、パーティション列を読んで、絞り込みクエリの計画を確認します。Hive は使用可能で、インストールや以前の VM の状態は不要です。外部テーブルと単純な日付フィルターを知っていれば十分です。ターミナルを使用してください。
ファイルの列とパーティション列を分ける
このステップでは、各記録の中に日付を繰り返し書かずに、日付でパーティション分割したテーブルを定義します。準備済みのファイルを確認します。
cd /home/labex/project
cat /home/labex/project/data/orders-2026-10-14.csv
ファイルには6列があります。前の7列の CSV と違い、order_date フィールドはありません。1ファイルには1日分の注文だけが入ります。準備済みの日別 HDFS ディレクトリを確認します。
hdfs dfs -ls /user/labex/hive-partitions/orders
order_date=2026-10-14 のような名前は、人にとって整理を分かりやすくします。ただし、Hive で使うにはパーティションの値と場所の登録が必要です。
次のテーブルは、6つのファイルフィールドを通常どおり宣言し、order_date DATE を PARTITIONED BY で別に宣言します。Hive は、この7つ目の検索可能な列をパーティションメタデータから提供します。両方の宣言に重複して追加したり、ファイルに7つ目のフィールドを加えたりしないでください。
テーブル定義を保存して実行します。ヒアドキュメントは SQL の間のテキストをそのまま書き込みます。Beeline の -f が保存したスクリプトを実行し、接続 URL とユーザー名は準備済みのローカル Hive サービスを指定します。
cat > /home/labex/project/queries/create-partitioned-orders.sql <<'SQL'
CREATE EXTERNAL TABLE retail_partitions.orders (
order_id STRING, customer_id STRING, product_id STRING,
quantity INT, unit_price DECIMAL(10,2), order_status STRING
)
PARTITIONED BY (order_date DATE)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS TEXTFILE
LOCATION 'hdfs://localhost:9000/user/labex/hive-partitions/orders'
TBLPROPERTIES ('skip.header.line.count'='1', 'external.table.purge'='false');
SQL
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -f /home/labex/project/queries/create-partitioned-orders.sql
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "DESCRIBE retail_partitions.orders;"
DESCRIBE には通常のフィールドとパーティション情報が含まれます。まだパーティションを登録していない段階で、行を数えます。
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "SELECT COUNT(*) FROM retail_partitions.orders;" > /home/labex/project/output/before-registration.tsv
cat /home/labex/project/output/before-registration.tsv
期待されるのは0です。テーブル定義も、その基点ディレクトリの下のファイルもありますが、新しいテーブルにはパーティション記録がまだありません。これはメタデータの管理範囲の違いであり、CSV が削除された証拠ではありません。
既存の2日分の場所を登録する
このステップでは、各日付の値を実際のディレクトリに結び付けます。ALTER TABLE ... ADD PARTITION は Metastore にパーティション記録を加えます。各 PARTITION (...) は日付値を、LOCATION は対応するファイルの場所を指定します。値を1つずつ明示するので、これは静的パーティションです。
両方の登録を1つのスクリプトに保存します。
cat > /home/labex/project/queries/register-first-dates.sql <<'SQL'
ALTER TABLE retail_partitions.orders ADD
PARTITION (order_date='2026-10-14') LOCATION 'hdfs://localhost:9000/user/labex/hive-partitions/orders/order_date=2026-10-14'
PARTITION (order_date='2026-10-15') LOCATION 'hdfs://localhost:9000/user/labex/hive-partitions/orders/order_date=2026-10-15';
SQL
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -f /home/labex/project/queries/register-first-dates.sql
登録した値を一覧表示し、日付列を読みます。
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "SHOW PARTITIONS retail_partitions.orders;" > /home/labex/project/output/registered-dates.tsv
cat /home/labex/project/output/registered-dates.tsv
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "SELECT order_id, order_date FROM retail_partitions.orders ORDER BY order_id;" > /home/labex/project/output/registered-orders.tsv
cat /home/labex/project/output/registered-orders.tsv
SHOW PARTITIONS には10月14日と15日が含まれるはずです。クエリは o1~o3 を10月14日、o4~o6 を10月15日として返します。日付は隠れた7つ目の CSV フィールドではなく、登録したパーティションから得られます。
登録は既存データを指すだけで、元ファイルをコピーしたり書き換えたりはしません。テーブルには支払い待ちと返金済みも含む6注文すべてが見えるようになりました。支払い済み売上のレポートには、引き続き状態フィルターが必要です。
ファイルを追加してから新しい日付を登録する
このステップでは、新しいディレクトリと新しいパーティション記録が別の操作であることを確かめます。ローカルに準備された10月16日のファイルを確認します。
cat /home/labex/project/data/orders-2026-10-16.csv
HDFS ディレクトリを作り、ファイルをアップロードします。これらの既習コマンドが変えるのはストレージだけです。
hdfs dfs -mkdir -p /user/labex/hive-partitions/orders/order_date=2026-10-16
hdfs dfs -put /home/labex/project/data/orders-2026-10-16.csv /user/labex/hive-partitions/orders/order_date=2026-10-16/orders.csv
登録する前に、その日の行数を Hive に問い合わせます。
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "SELECT COUNT(*) FROM retail_partitions.orders WHERE order_date = DATE '2026-10-16';" > /home/labex/project/output/new-date-before.tsv
cat /home/labex/project/output/new-date-before.tsv
アップロード済みでも0が期待されます。不足するメタデータを加え、同じ日付のクエリを再度実行します。
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "ALTER TABLE retail_partitions.orders ADD PARTITION (order_date='2026-10-16') LOCATION 'hdfs://localhost:9000/user/labex/hive-partitions/orders/order_date=2026-10-16';"
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "SELECT order_id, customer_id, order_status, order_date FROM retail_partitions.orders WHERE order_date = DATE '2026-10-16' ORDER BY order_id;" > /home/labex/project/output/new-date-orders.tsv
cat /home/labex/project/output/new-date-orders.tsv
今度は o7/c1/paid と o8/c2/pending が、10月16日とともに表示されます。Hive が、このパーティション値とアップロード先のディレクトリを対応させられました。意図的に前後を比べることで、新しいファイルが HDFS にあるのにレポートには出ない理由を説明できます。
パーティションで絞ったクエリと計画を読む
このステップでは、登録した1日を選び、Hive がその要求をどう計画するか調べます。WHERE にパーティション列を使うクエリを保存します。
cat > /home/labex/project/queries/query-sales-partition.sql <<'SQL'
SELECT order_id, quantity, order_date
FROM retail_partitions.orders
WHERE order_date = DATE '2026-10-15'
ORDER BY order_id;
SQL
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -f /home/labex/project/queries/query-sales-partition.sql > /home/labex/project/output/selected-partition.tsv
cat /home/labex/project/output/selected-partition.tsv
o4/2、o5/1、o6/2 がすべて10月15日で表示されるはずです。これは日付の選択で、まだ支払い済みのフィルターではありません。そのため、返金済みの o5 が残るのはこのクエリでは正しい動作です。
EXPLAIN は、データ行を返さずにクエリの計画を説明します。DEPENDENCY オプションは、読むテーブルとパーティションに焦点を当てます。この簡潔な表示なら、実行段階の内部構造を先に学ばずに入力選択を調べられます。同じクエリの前に EXPLAIN DEPENDENCY を付け、結果を保存します。
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "EXPLAIN DEPENDENCY SELECT order_id, quantity, order_date
FROM retail_partitions.orders
WHERE order_date = DATE '2026-10-15'
ORDER BY order_id;" > /home/labex/project/output/partition-plan.txt
cat /home/labex/project/output/partition-plan.txt
結果は、名前付きのフィールドとリストで表すテキスト形式 JSON です。retail_partitions@orders を示す input_tables と、唯一の partitionName が order_date=2026-10-15 で終わる input_partitions を探してください。ほかの2日分は入力一覧にありません。日付条件によって Hive は、記録を読む前に関係する登録済みパーティションを選べます。これをパーティションプルーニングと呼びます。小さなサンプルは選択の理解が目的なので、クエリ時間を性能比較として使っても意味はありません。
最後に、登録済みのパーティションをもう一度一覧表示します。
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "SHOW PARTITIONS retail_partitions.orders;"
3日分すべてが登録されたままのはずです。1日を選ぶことで変わるのはクエリの入力選択であり、ほかのパーティション記録やファイルは削除されません。これで、どの日次データがクエリから見えるかを説明するための、ストレージ側とカタログ側の証拠がそろいました。
まとめ
ファイルのフィールドとパーティション列を分け、日別の HDFS の場所を Hive に登録し、新しいディレクトリがパーティション追加まで見えないことを観察しました。その後、すべての日付を保持したまま1日を選び、クエリ計画を調べました。次は、クエリ結果を再利用可能な列指向の ORC テーブルに保存します。



