2011-12-21 10 views
3

私たちは価格リストを説明するアプリケーションを作成しようとしています。価格表自体は複数レベルになっているため、商品の価格は多数の「オプション」に依存します。私はここで一番良い選択肢になると思う。複数のレベルのアイテム

現在、私は、次の表があります。

アイテム:

  • のitem_id(PK)
  • 名前

Main_Option:

  • Main_Option_ID(PK)
  • 名前を

Sub_Option:

  • Sub_Option_ID(PK)
  • Main_Option_ID(FK)
012 Sub_Option_ID

Item_To_Sub_Option

  • ITEM_ID
  • 名前

    これは、我々が現在持っている構造である - ここではそれがどのように機能するかを実証する例です。

    アイテム:ソファ

    Main_Option:長さ

    Sub_Option:40” -50”

    Item_To_Sub_Option:ソファのItem_ID、40 "-50" Sub_Option_ID

    画像が表示されます。ここまではかなりストレートです。基本的には、すべてのアイテムが無制限の量のサブオプションとメインオプションを持つことができます。

    ここで、私たちが達成しようとしているのは、説明されているソリューションまたは複数レベルのオプションソリューションのドリルダウンです。

    たとえば、さらに複雑なオプションを生成する必要があるが、それらのオプションはアイテムからではなく、他のサブオプションから生成されます。例えば次のように

    アイテム:ソファ

    Main_Option:形状

    Sub_Option:1/2サークル

    "1/2円は" 追加Main_Optionを有する必要がある - 「直径」意志Sub_Options(50 "Round、60" Roundなど)があります。これらのオプションはアイテムとは直接関係しませんが、上位レベルで前に選択されたサブオプション「1/2 Circle」を使用します。

    このソリューションを実現するためにデータベースを設計する最良の方法は何ですか?

答えて

2

あなたがこれに苦しんでいる理由は、間違った方法で問題を少し考えているからです。他のサブオプションを持つサブオプションを持つメインオプションの考え方ではなく、他のメインオプションからなるメインオプションについて考える必要があります。

メインオプションを「機能」または「品質」と、サブオプションを「値」と考えると、これは少し明確になります。あなたの例では、ソファの品質は「シェイプ」です。あなたの目的のために、SHAPEはLINEARまたはROUNDかもしれません。線形の品質はLENGTHですが、円形の品質はANGLEです。 SHAPE、LINEAR、ROUND:これらの資質のいずれも、を持っていません。しかし、これらの品質:長さ、角度には値があります。 LENGTHの値は40のようなものかもしれない「-50」とANGLEためには1/2サークルかもしれません。

あなたのデータモデルは、したがって、非常に多くの変更する必要はありません。

ERD

だけMAIN_OPTIONから自身に別のFKを追加します。デビッドはこれを貧しい第二の選択肢として提案しましたが、現実には第一の選択肢であることを除いて、これはダビデも提案したものです。

階層を通じてドリルダウンする場合を除き、ルールは階層型であり、階層データの場合はRDBMSが扱いにくい可能性があります。あなたが掘り下げているとき、各ステップは単純なものです。

+0

私はダビデの答えから「本当の答え」がないことを認識しました。皆さん、ありがとう、私を助けてくれました! –

+0

David - あなたの提案されたソリューションには重大な問題があります。あなたの最初の解決策は、RDBMSから離れて、多量の構文解析ロジックの作成を必要とする階層的な文書モデルを作成することです。すでに安定したライブラリコードがサポートされているXMLのようなものを使うことは勧められませんでした。あなたの2番目の提案は、私が提案したものよりOPの現在のモデルからのより大きい脱退であり、オプション値とオプションのカテゴリとの区別を非常にはっきりと述べていません。 –

+0

ジョエルは - 私の最初の提案は、MongoDBのを使用して問題をモデル化することでした。このタイプのデータには非常に適しています。特別な解析は必要ありません。これは、通常のリレーショナルデータベースとは異なるタイプのデータベースです。だから、私はこの答えに「深刻な問題がある」という事実に異議を唱えます。私はあなたが私が提案した技術に精通していないと思う。私が提案したリレーショナルモデルは、あなたが上に描いたものと似ています。それは、自己参照表を必要とする古典的な部分/部分の関係です。私はここにも「深刻な問題」があるとは思わない。 – OzBandit

0

このような設計をするには、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サークル」オプションを使用して、すべてのソファを検索するには、次のようなものが必要になる場合があります階層内の何かを照会することができます。そのクエリは、メインオプションとサブオプションのみを持つものにすぎません。

とにかく、これはあなたに物事をモデル化する方法のいくつかのオプションを与えることを願っています。

+0

私は、リレーショナルデータベースで行かなければならないと仮定します - このためのより良い構造ではないですか?他の誰かが別のアイデアを持っていますか? –

+0

これ以上の構造はありません。古典的なリレーショナルデータベースモデリングの問題です。パーツとサブパーツの関係をモデリングする例については、Googleを参照してください。あなたは私が概説したのと同じセットのテーブルを見つけるでしょう。本当の問題は、あなたのデータは階層的かつ不規則である(必ずしも同じ深さ)と効率的なものをモデル化するように設計されていないリレーショナルデータベースにモデル化することが困難であるということです。だから私は、MongoDBを使ってモデルを作るほうがはるかに簡単だが、あなたの状況に応じて使うことはできないかもしれないMongoDBを提案したのだ。 – OzBandit

関連する問題