[[ディメンショナルモデリング]] では、ユーザーレビューやアンケートの回答、[[SQL]] クエリといった長文テキスト属性を[[ファクトテーブル]]に直接埋め込まず、独立した [[Text Comment Dimension]] に切り出すアプローチが推奨されている。
以降は EC サイトの注文トランザクションデータの `order_comment` 列を配置する例で議論する。注文時にユーザーが自由入力するコメントで、「彼女の誕生日プレゼント。ピンクのリボンで包装、5/25 午前中着希望」のような文面が想定されるものとする。
```mermaid
erDiagram
order {
order_id string "[PK]"
user_id string "[FK]"
order_date datetime
order_status string
shipping_method string
product_id string "[FK]"
quantity int64
order_amount int64
order_comment string
}
```
## 長文テキスト属性のアンチパターン
### 1. ファクトテーブルに残す
長文テキスト属性は集計対象のメジャーにもディメンション属性にも当てはまらないため、注文番号や請求書番号のような [[Degenerate Dimension]] と同じ扱いで、仕方なくファクトテーブルに残す発想になりやすい。
```mermaid
erDiagram
dim_user ||--|{ fct_order : user_key
dim_product ||--|{ fct_order : product_key
fct_order }|--|| dim_order_profile : order_profile_key
fct_order["fct_order [TF]"] {
order_key int64 "[SK]"
user_key int64 "[FK]"
product_key int64 "[FK]"
order_profile_key int64 "[FK]"
order_id string "[GD, DD]"
order_date datetime "[DD]"
order_comment string "[GD]"
quantity int64 "[FA]"
order_amount int64 "[FA]"
}
dim_order_profile["dim_order_profile [CV]"] {
order_profile_key int64 "[SK]"
order_status string "[GD]"
shipping_method string "[GD]"
}
```
図の `order_comment` のような異物が積み重なっていくと、ファクトテーブルは「軸で分類できない列の集合場所」へと退化する。スキーマ全体で関心の分離が機能しなくなり、データモデルの使い勝手が悪くなる。
### 2. Junk Dimension に押し込む
[[Junk Dimension]] の名前空間が「雑多な属性を入れる場所」と曖昧に拡張されていると、`order_comment` のような長文テキスト属性も入れてしまう発想になりやすい。
```mermaid
erDiagram
dim_user ||--|{ fct_order : user_key
dim_product ||--|{ fct_order : product_key
fct_order }|--|| dim_order_profile : order_profile_key
fct_order["fct_order [TF]"] {
order_key int64 "[SK]"
user_key int64 "[FK]"
product_key int64 "[FK]"
order_profile_key int64 "[FK]"
order_id string "[GD, DD]"
order_date datetime "[DD]"
quantity int64 "[FA]"
order_amount int64 "[FA]"
}
dim_order_profile["dim_order_profile [CV]"] {
order_profile_key int64 "[SK]"
order_status string "[GD]"
shipping_method string "[GD]"
order_comment string "[GD]"
}
```
Junk Dimension に `order_comment` のような高カーディナリティ属性を含めると、Junk Dimension の圧縮効果は消え、本来の役割が機能しなくなる。
## 推奨パターン: Text Comment Dimension として切り出す
長文テキスト属性は専用の Text Comment Dimension に切り出し、ファクトテーブルから FK で参照する。長文テキスト属性が付かない行には、ディメンション側にゴーストレコードを 1 行作成し、その FK で参照する。
これにより Junk Dimension を本来の役割 (低カーディナリティ属性の圧縮) に保ったまま、長文テキスト属性の分離が両立する。
注文の例なら、`order_comment` を `dim_order_comment` に切り出し、`fct_order` から `order_comment_key` で参照する。
```mermaid
erDiagram
dim_user ||--|{ fct_order : user_key
dim_product ||--|{ fct_order : product_key
fct_order }|--|| dim_order_profile : order_profile_key
fct_order }|--|| dim_order_comment : order_comment_key
fct_order["fct_order [TF]"] {
order_key int64 "[SK]"
user_key int64 "[FK]"
product_key int64 "[FK]"
order_profile_key int64 "[FK]"
order_comment_key int64 "[FK]"
order_id string "[GD, DD]"
order_date datetime "[DD]"
quantity int64 "[FA]"
order_amount int64 "[FA]"
}
dim_order_profile["dim_order_profile [CV]"] {
order_profile_key int64 "[SK]"
order_status string "[GD]"
shipping_method string "[GD]"
}
dim_order_comment["dim_order_comment [CV]"] {
order_comment_key int64 "[SK]"
order_comment string "[GD]"
}
```
## 関連ノート
なし