

# 動的な ID パーティショニングを使用する
<a name="partition-projection-dynamic-id-partitioning"></a>

カーディナリティの高いプロパティによってデータが分割されている場合や、値が事前にわからない場合は、`injected` 射影型を使用できます。このようなプロパティの例としては、ユーザー名、デバイスや製品の ID などがあります。`injected` 射影型を使用してパーティションキーを設定すると、Athena はクエリ自体の値を使用して、読み取られるパーティションのセットを計算します。

Athena が `injected` プロジェクションタイプで設定されたパーティションキーを持つテーブルでクエリを実行できるようにするには、以下が満たされている必要があります。
+ クエリには、パーティションキーの値が少なくとも 1 つ含まれている必要があります。
+ 値は、データを読み取らなくても評価できるリテラルまたは式でなければなりません。

これらの基準のいずれかが満たされない場合、クエリは次のエラーで失敗します。

CONSTRAINT\_VIOLATION: injected 射影型のパーティション列 {{column\_name}} では、WHERE 句に静的な等号条件のみが含まれており、このような条件が少なくとも 1 つ存在する必要があります。

## `injected` 射影タイプを使用すべき場合
<a name="partition-projection-injection"></a>

IoT デバイスからのイベントで構成され、デバイスの ID で分割されたデータセットがあるとします。このデータセットには次の特徴があります。
+ デバイス ID はランダムに生成されています。
+ 新しいデバイスは頻繁にプロビジョニングされます。
+ 現在、数十万台のデバイスがあり、今後は数百万台になる見込みです。

このデータセットを従来のメタストアで管理するのは容易ではありません。データストレージとメタストア間でパーティションを同期させることは難しく、クエリ計画中はパーティションのフィルタリングに時間がかかることがあります。ただし、パーティションプロジェクションを使用するようにテーブルを設定し、`injected` 射影型を使用する場合には、メタストア内のパーティションを管理する必要がないことと、クエリでパーティションメタデータを検索する必要がないことの 2 つの利点があります。

次の `CREATE TABLE` の例では、先ほど説明したデバイスイベントデータセットのテーブルを作成します。このテーブルでは、injected 射影型を使用しています。

```
CREATE EXTERNAL TABLE device_events (
  event_time TIMESTAMP,
  data STRING,
  battery_level INT
)
PARTITIONED BY (
  device_id STRING
)
LOCATION "s3://amzn-s3-demo-bucket/{{prefix}}/"
TBLPROPERTIES (
  "projection.enabled" = "true",
  "projection.device_id.type" = "injected",
  "storage.location.template" = "s3://amzn-s3-demo-bucket/{{prefix}}/${device_id}"
)
```

次のクエリ例では、特定の 3 つのデバイスから 12 時間にわたって受信したイベントの数を調べます。

```
SELECT device_id, COUNT(*) AS events
FROM device_events
WHERE device_id IN (
  '4a770164-0392-4a41-8565-40ed8cec737e',
  'f71d12cf-f01f-4877-875d-128c23cbde17',
  '763421d8-b005-47c3-ba32-cc747ab32f9a'
)
AND event_time BETWEEN TIMESTAMP '2023-11-01 20:00' AND TIMESTAMP '2023-11-02 08:00'
GROUP BY device_id
```

このクエリを実行すると、Athena は `device_id` パーティションキーの 3 つの値を確認し、それらを使用してパーティションの場所を計算します。Athena は `storage.location.template` プロパティの値を使用して以下の場所を生成します。
+ `s3://amzn-s3-demo-bucket/{{prefix}}/4a770164-0392-4a41-8565-40ed8cec737e`
+ `s3://amzn-s3-demo-bucket/{{prefix}}/f71d12cf-f01f-4877-875d-128c23cbde17`
+ `s3://amzn-s3-demo-bucket/{{prefix}}/763421d8-b005-47c3-ba32-cc747ab32f9a`

パーティションの射影設定から `storage.location.template` プロパティを除外した場合、Athena は Hive 形式のパーティション分割を使用して、`LOCATION` の値 (例: `s3://amzn-s3-demo-bucket/{{prefix}}/device_id=4a770164-0392-4a41-8565-40ed8cec737e`) に基づいてパーティションの場所を射影します。