このような設計をするには、2つの方法が考えられます。しかし、最初に認識しなければならないことは、あなたのデータが本質的に階層構造であり、必ずしも規則的ではないということです。これは、伝統的なリレーショナルデータベースを使用することは、このタイプのデータに特に適していないことを意味します。しかし、それを行うことができます。
私がおそらく自分自身を使う最初の方法は、MongoDBなどの非リレーショナルデータベースを選択することです。これは "ドキュメント"のコレクションを格納するように設計されています。ドキュメントは本質的にオブジェクトのようなもので、内に他の埋め込みドキュメントを含めることができます。これは、あなたのデータタイプに特に適しています。あなたはこのように、データモデルを作成することができます。
Item {
main_options: [{
name: "Shape",
sub_options: [{
name: "1/2 Circle",
// Other fields here
}]
},
{
// Other main option
}]
}
ドキュメントベースのデータモデルのこのタイプの美しさはあなたが付着する必要がありません固定スキーマがあるということです。アイテムに複数のネストされたオプションセットが必要な場合は、そのアイテムのドキュメントをそのように定義するだけです。潜在的に全く異なる「アイテム」ドキュメントにもかかわらず、それらはすべて同じ「コレクション」に格納され、異なるアイテムを見つけるためにクエリを実行できます。たとえば、 "1/2 Circle"サブオプションが "Shape"のすべてのアイテムを見つけるようにデータベースに問い合わせることができます。
リレーショナルデータベースの操作に慣れていた場合、MongoDBのようなものに移行するのはちょっと心配ですが、実際にはデータの性質に合っていると思います。
一方、絶対にリレーショナルデータベースを使用する必要がある場合は、物事を階層としてモデル化する必要がありますが、これはややこしいことがあります。そこでここでは、私達の項目テーブルとそのセットにアイテムをマップする別のテーブルを定義
item (id (pk), name: text, ...)
option (id (pk), owner: option_id (fk), name: text, ...)
item_options (item_id, option_id)
:私はここに作ると思い変化とそれらを修正再表示しましたが、基本的には、少しあなたのようなテーブルが既に説明必要主要なオプションの "オプション"テーブルで定義されています。
オプションテーブルには、メインオプションの場合は "null"に設定されますが、サブオプションの場合はメインフィールドのオプションIDにこのフィールドを設定しますそれを所有しているサブオプションです。この種の構造を使用すると、好きな深さにオプションを入れ子にすることができます。ここではいくつかの例のデータは次のとおりです。
item (1, "Sofa", ...)
option (1, null, "Shape", ...)
option (2, null, "Length", ...)
option (3, 1, "1/2 Circle", ...)
option (4, 1, "3/4 Circle", ...)
option (5, 2, "Short", ...)
option (6, 2, "Long", ...)
option (7, 5, "Specific Short Measurement", ...)
option (8, 5, "Other Short Measurement", ...)
item_options (1, 1)
item_options (1, 2)
このタイプのデータのためのリレーショナルデータベースを使用しての欠点は、物事を見つけるためのクエリは非常に簡単ではないということです。あなたが見ることができるように、より深いあなたの商品構造があり、より多くの加入
select * from item i inner join item_options io on i.id = io.item_id inner join option o on io.option_id = o.id left join option o2 on o.id = o2.owner where o.name = 'Shape' and o2.name = '1/2 Circle';
あなたが行う必要があります。たとえば、「1/2サークル」オプションを使用して、すべてのソファを検索するには、次のようなものが必要になる場合があります階層内の何かを照会することができます。そのクエリは、メインオプションとサブオプションのみを持つものにすぎません。
とにかく、これはあなたに物事をモデル化する方法のいくつかのオプションを与えることを願っています。
私はダビデの答えから「本当の答え」がないことを認識しました。皆さん、ありがとう、私を助けてくれました! –
David - あなたの提案されたソリューションには重大な問題があります。あなたの最初の解決策は、RDBMSから離れて、多量の構文解析ロジックの作成を必要とする階層的な文書モデルを作成することです。すでに安定したライブラリコードがサポートされているXMLのようなものを使うことは勧められませんでした。あなたの2番目の提案は、私が提案したものよりOPの現在のモデルからのより大きい脱退であり、オプション値とオプションのカテゴリとの区別を非常にはっきりと述べていません。 –
ジョエルは - 私の最初の提案は、MongoDBのを使用して問題をモデル化することでした。このタイプのデータには非常に適しています。特別な解析は必要ありません。これは、通常のリレーショナルデータベースとは異なるタイプのデータベースです。だから、私はこの答えに「深刻な問題がある」という事実に異議を唱えます。私はあなたが私が提案した技術に精通していないと思う。私が提案したリレーショナルモデルは、あなたが上に描いたものと似ています。それは、自己参照表を必要とする古典的な部分/部分の関係です。私はここにも「深刻な問題」があるとは思わない。 – OzBandit