同じタイプのエンティティで構成されるエンティティで深い再帰クエリを防ぐ方法は? [中のクールな例
質問
心配ない!それは実際よりも複雑に見えます!飲み物に降りてください!
tldr-version: :他のエンティティとの関係を持つエンティティを効率的にクエリし、更新する方法は?
これは、私を困惑させている2つのテーブルを備えた興味深いデータモデリングシナリオです。
Entities { ID, Name, ScalarValue }
ComponentEntities { AggregateEntityID, ComponentEntityID, quantity }
AggregateEntityID
と ComponentEntityID
の外国の鍵です Entities
テーブル。
すでに血まみれの例を教えてください
Drinks { ID, Name, Alcohol% }
DrinkIngredients { CocktailID, IngredientID, amount }
Drinks { 1, "Vodka", 40% }
Drinks { 2, "Tomato juice", 0% }
Drinks { 3, "Tabasco", 0% }
Drinks { 4, "Bloody mary", - }
DrinkIngredients { 4, 1, 0.2 } // Bloody mary has 0.2*Vodka
DrinkIngredients { 4, 2, 0.7 } // Bloody mary has 0.7*Tomato juice
DrinkIngredients { 4, 3, 0.1 } // Bloody mary has 0.1*Tabasco
ブラッディメアリーのアルコールの内容を手に入れたいなら、 SELECT * FROM DrinkIngredients WHERE CocktailID == 4
.
かなり標準。そこに奇妙なことはありません。リサは、それに情熱を加えることで少し甘くするのが好きです:
Drinks { 6, "Passion", 13% }
Drinks { 7, "Bloody Mary Pink", - }
DrinkIngredients { 7, 4, 0.8 } // Bloody Mary Pink has 0.8*Bloody Mary
DrinkIngredients { 7, 6, 0.2 } // Bloody Mary Pink has 0.2*Passion
リサの母はこれらを長い間味わっているので、彼女は2つの間に究極のブレンドを見つけたと信じています。
Drinks { 8, "Bloody Milf", - }
DrinkIngredients { 8, 4, 0.45 } // Bloody Milf has 0.45*Bloody Mary
DrinkIngredients { 8, 7, 0.55 } // Bloody Milf has 0.55*Bloody Mary Pink
これらのカップルを追加します で構成されています レベルと私たちは深い関係の再帰を持っています。唯一の制限は、エンティティがそれ自体で構成できないことです。
これはaを形成しているようです 指示された非環式グラフ.
RDBMS:データを「キャッシュ」する1つの方法は、関連するデータを計算し、エンティ自体(またはおそらく別のテーブルに)に保存することです。上記の例では、ブラッディメアリーのアルコール含有量は、アルコール%畑に作成され保存されたときに一度計算されました。この場合、更新されたもので構成されるすべての飲み物(依存関係全体)を更新する必要があるため、更新は高価になります。
質問
RDBMS:リーフドリンクに到達するまで「親」の飲み物を手に入れるよりも、葉の値(他のもので構成されていない飲み物)に到達するためのより良い方法はありますか?
RDBMSとNOSQLの両方に、これに問題があります。
ボトムライン:これはさらに実用的で実行可能ですか?
私が必要とするのは反論です
解決
「RDBMS:リーフドリンクに到達するまで「親」の飲み物を手に入れるよりも、葉の値(他のもので構成されていない飲み物)に到達するためのより良い方法はありますか?」
これを理解しないでください。他のもので構成されていない飲み物は、再帰とは何の関係もありません。存在しない場所を除いて、それは単純です。
そして、「葉の値に到達する」(親を与えられた)は、それをモデル化するために使用されるデータ構造(リレーショナルまたは階層)に関係なく、必然的にツリーを横断する必要がありますか?
RDBMSとNOSQLの両方に、これに問題があります。
rdbmsはこれに実際に問題を抱えていません。この問題は数十年前(80年代ほど)すでに特定されており、リレーショナル代数を推移的な閉鎖操作とその一般化バージョンで修正することで対処されました。 SQLは再帰的なクエリを通じてこれをサポートしており、フランクが言ったように、少なくともすべての大きな犬はすべて、何らかの方法で再帰クエリをサポートしています。
ボトムライン:これはさらに実用的で実行可能ですか?」
これまでにやったことがないなら、再帰的なクエリを書くことは些細なことではありません。それはそれを「非実践」にしますか?私は知りません。
他のヒント
多くのRDMSが再帰クエリをサポートしています。例を参照してください http://msdn.microsoft.com/en-us/library/ms186243.aspx.