この記事はMagento Advent Calendar 2017の14日目です。
動機
- 備忘録
- 社内の人間のテーブル構造を理解してもらいたい
商品周りのテーブル構造について
所感
たまに大変なことがある。
ここが良くない
- EAVパターンは良くない
- DDL上で外部キーが貼ってあったりなかったり
- DDL上で外部キーが貼れないような外部キーの使われ方がされている
- 後述するがcatalog_product_entity_intとeav_attribute_option_value等
- primary keyの名前に一貫性がない。テーブル名+id等なら良いし、entity_idなら良いがテーブルによってまちまち。
商品
- catalog_product_entity
商品IDがentity_idでSKUがくっついている。
すべての商品について持っていて、商品ごとにtype_idが文字列で入っていて、
それによって単品かセット商品か、コンフィグ商品かを区別している。
has_options、required_optionsで商品オプションについて存在するかが表現されているが、コンフィグ商品の場合には絶対に1にはならない、などがありカラム間で依存性がある。
商品関連テーブル
商品とセット商品
catalog_product_entityにtype_idがbundleで入力される。
その上で下記の関連するテーブルにレコードが入力される。
- catalog_product_bundle_option
- catalog_product_bundle_option_value
セット商品の場合には二つ以上の組み合わせを選ぶことになる。
仮に服を考えるときに、トップとボトムのセットを仮定する場合に、
「トップ」「ボトム」といった区分がここに入力される。
catalog_product_bundle_optionは組み合わせ自体のIDと組み合わせの選択方法(セレクトメニューやテキスト入力など)が保持される。
catalog_product_bundle_option_valueには、「トップ」「ボトム」といった組み合わせに付随する情報が保存される。
- catalog_product_bundle_selection
それぞれの組み合わせ、つまり「トップ」「ボトム」に属する商品が入力される。
catalog_product_bundle_option.option_idがoption_idとして、
option_id下につく商品IDがproduct_idとして入力される。
parent_product_idという形で親商品IDももっている。(catalog_product_bundle_optionにも当然ある。
- catalog_product_bundle_selection_price
- catalog_product_bundle_price_index
セットでの特別価格的に使うテーブルに見受けられるが自分の環境では使用していないので不明。
商品とオプション商品
商品に紐付いて選択可能なオプションを提示する。オプション自体は商品としては扱わない。
- catalog_product_option
- catalog_product_option_title
商品IDを持って、商品テーブルにたいして1:Nなレコードを作成する。
typeにはオプションの選択形式が文字列で入力され(テーブル作って外部キー化した方が良いと思う)、
一部の入力形式用のバリデーションが入力される。NULL値が入る設計。
catalog_product_option_titleにはオプションの名前が入る。
- catalog_product_option_type_value
catalog_product_optionにたいして1:Nなオプション選択項目が入力される。
- catalog_product_option_type_title
catalog_product_option_type_valueのprimary keyを外部キーとして、
1:1関係(正確にはstoreがあるので1:nになるが)の、テーブルで、
catalog_product_option_type_valueの表示名が入力される。
catalog_product_option_type_valueの子のテーブルになるので、
テーブル名はcatalog_product_option_type_title_value
とかになってる方が良いかと思います。
- catalog_product_option_type_price
catalog_product_option_type_titleと同様、価格が存在すれば入力される。
1:1というよりは1:0or1といった形のテーブルとなっている。
商品とコンフィグ商品
商品に紐付いて選択可能なオプションを提示する。オプション自体が別の商品である。
イメージはセット商品で選ぶものが一つしかないような形。
- catalog_product_super_attribute
α商品の下にA,B,C...商品と紐づく形になる。
A,B,C...商品が何の属性を以ってα商品に紐づくかを表現する。
管理画面での設定画面では、特定のeav_attributeの1レコードを選択(同画面で作成もできる)をして、
親商品IDと属性IDの組み合わせテーブルとしてレコードが作成される。
- catalog_product_entity_int
子商品に上記で指定した属性値が付与される。
attribute_idには、対象となるeav_attribute_idが入力される
valueにはeav_attribute_optionのoption_idが入力される(!?)
- eav_attribute
名の通りEAV的に属性値を持たせるテーブル。
問題としては、商品のみならず、カテゴリやら顧客やらに属性を持たせるときにも同じように使う。
- eav_attribute_option
- eav_attribute_option_value
eav_attributeで定義した属性の下になる値を持たせる。
eav_attribute_optionはレコードのみを持ち、eav_attribute_option_valueに具体的な名前が入力される。
eav_attributeに仮にcolorを作成し、red,brownを作成したい場合には
eav_attribute_optionが2レコード作成される。
eav_attribute_option_valueには、eav_attribute_optionのprimary keyと、それぞれの色の名前を持つレコードが作成される。
- catalog_product_super_link
親商品と子商品がどのように紐づくかが記述される。
商品テーブルと属性
- catalog_product_entity_datetime
- catalog_product_entity_decimal
- catalog_product_entity_gallery
- catalog_product_entity_text
- catalog_product_entity_varchar
- catalog_product_entity_int
catalog_product_entity.entity_idとeav_attribute.attribute_idで関係テーブルを持たせている。
eav_attributeには値自体の型を持っていてそれにしたがって、上記テーブル群に振り分けをして入力される。
value部分に具体的な値を持つことになる。
とある商品にたいして、発売開始日が2017年1月1日、みたいなものを持たせたい場合には、
該当商品ID、発売開始日属性レコード、2017-01-01をそれぞれ、entity_id,attribute_id,valueに入力することになる。
例外としては、上記のコンフィグ商品の属性と属性値のように、
catalog_product_entity_intでレコードを持ち、valueにeav_attribute_optionのoption_idを保持する形がある。
- catalog_product_entity_media_gallery
- catalog_product_entity_media_gallery_value
- catalog_product_entity_media_gallery_value_to_entity
- catalog_product_entity_media_gallery_value_video
商品画像など。