[[ディメンショナルモデリング]] では、ユーザーレビューやアンケートの回答、[[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]" } ``` ## 関連ノート なし