6

現在、レシピの保存に使用するデータベース スキーマを設計しています。このデータベースには、タグ付けできるようにしたいさまざまな種類のエンティティがあります (材料、レシピ発行者、レシピなど)。したがって、タグには複数の n:m 関係があります。「3 つのテーブル デザイン」を使用すると、所有するエンティティ タイプ (レシピ、材料、発行者) ごとにテーブル (クロス テーブル) が作成されます。つまり、エンティティを導入するたびに、クロス テーブルを追加する必要があります。

すべてのエンティティが参照する一意の ID を持つテーブルを 1 つ作成し、タグ テーブルと「一意の ID」テーブルの間の関係を作成することを考えていました。このようにして、「一意の ID」テーブルとタグ テーブルの間にクロス テーブルが 1 つだけ存在します。

一部の人々がこの質問はすでに尋ねられたと思うかもしれない場合に備えて. 私はすでにタグ付けのためのデータベース設計を読みました。そして、3つのテーブルのデザインが言及されています。

4

6 に答える 6

2

すべてのタグ割り当てに対して単一のテーブルを使用することに問題はありません (タグ付け可能なエンティティごとに 1 つの複数のテーブルとは対照的に)。

ただし、あなたのデザインの 1 つの重要な詳細は私にはあいまいなままです: これらの線に沿って何かを持っている場合

- - - - - - - - - -
Tag
    ID           // PK
    Name
    ...

- - - - - - - - - -
Taggable
    ID           // PK
    ...

- - - - - - - - - -
TagAssignment
    Tag_ID       // FK -> Tag.ID
    Taggable_ID  // FK -> Taggable.ID
    ...

- - - - - - - - - -
EntityOne
    Taggable_ID  // FK -> Taggable.ID
    ...

- - - - - - - - - -
EntityTwo
    Taggable_ID  // FK -> Taggable.ID
    ...

次に、エンティティ クラスに独自の主キーを持たせるか、 andの事実上の主キーとしてEntityOne.TaggableIDandを使用しますか?EntityTwo.TaggableIDEntityOneEntityTwo

ほとんどの場合、私は用心深く、エンティティに独自の ID を持たせます。

- - - - - - - - - -
EntityOne
    ID           // PK
    Taggable_ID  // FK -> Taggable.ID (Nullable)
    ...

- - - - - - - - - -
EntityTwo
    ID           // PK
    Taggable_ID  // FK -> Taggable.ID (Nullable)
    ...

これは、各エンティティが の対応するインスタンスを持つ必要がないため、Taggableエンティティに関連するすべてのコードがタグを認識している必要もありません。ただし、タグ付けがシステム内で本当に遍在する場合、およびエンティティの他の「共通の祖先」(つまり、 以外Taggable) が必要ないことが確実な場合は、「組み込み」なしで済む可能性があります。エンティティの ID。

NB : 私はこのようなものを実装しようとしたことはないので、私の推奨事項はすべて純粋に理論的なものです。明らかな欠陥が見られない場合は、私を撃たないでください。:-)


ビル・カーウィンのコメントに応えて:

おっしゃる通りです。上記の設計では、複数のエンティティが同じ を参照することは妨げられませんTaggable。しかし:

  1. 私が言ったように、すべては要件に依存します。Taggableエンティティの唯一の「共通の祖先」になることが確実な場合は、 Taggable_IDFK をエンティティの PK として使用してもかまいません。しかし、たとえば、たまたま「タグ付け可能」なエンティティが「監視可能」(通知、通知スケジュールなどを考えてください)または「何でも可能」でなければならない場合はどうなりますか :-)? エンティティを結び付けにくいことで、これらすべての「能力」を遮断できますTaggableか?

  2. 1つのタグ付け可能で1つのエンティティの制約をDBレベルで強制したい場合...私の知る限り、FKをPKとして機能させずにそれを行う一般的な方法が少なくとも1つあります。とにかく他の機能に役立つかもしれません)。

これらの線に沿った何かがあれば、ケーキを食べて食べることができます:

- - - - - - - - - -
Taggable
    ID           // PK
    Type        
    ... 
    - - - - - - - -
    Constraint: (ID, Type) is unique


- - - - - - - - - -
EntityOne
    ID
    Taggable_ID   
    Taggable_Type // Constraint: always = 'EntityOne'
    ...
    - - - - - - - -
    FK: (Taggable_ID, Taggable_Type) -> (Taggable.ID, Taggable.Type)

もちろん、これはすべて、エンティティをタグ付け可能に結び付けるよりも複雑です。しかし、私の謙虚な意見では、元の質問によって提供された狭い全体像に加えて、何を考慮すべきかについて議論しようとしていました.

于 2008-11-19T17:53:12.383 に答える
2

タグをどのように使用するかによって異なります。

一度に1 つのタイプのエンティティのみを検索する場合は、タグ付けするエンティティ タイプごとに追加の交差テーブルを作成できると思います。つまり、「「おいしい」タグが付いた食材を見せて」と言うのは普通でしょうが、「「おいしい」タグが付いた食材とレシピ発行者の両方を見せてください」と言うのが何を意味するのかは明確ではありません。この場合、エンティティごとに個別の交差テーブルを持つことは問題ありません。

ただし、特定のタグを持つすべてのタイプのすべてのエンティティを検索する必要がある場合は、単一の「ID」テーブルを使用する方が簡単です。主キーと外部キーの両方として定義した列を使用して、すべてのエンティティ テーブルがそれを指すようにします。

CREATE TABLE Recipes (
  recipe_id INT NOT NULL PRIMARY KEY, -- not auto-generated
  FOREIGN KEY (recipe_id) REFERENCES Taggables(id)
);

この計画の唯一の弱点は、 と の両方Recipesで行Ingredientsが で同じ行を指すのを防ぐことができないことですTaggables

INSERT INTO Taggables (id) VALUES (327);
INSERT INTO Recipes (recipe_id, name) VALUES (327, 'Hollandaise sauce');
INSERT INTO Ingredients (ingr_id, name) VALUES (327, 'eggs');

卵に関連付けられたすべてのタグをオランデーズ ソースにも適用しますか?

単一テーブル設計のこの側面を指摘しているだけです。他の要件を考えると、タグ付けをモデル化するための最良の方法である可能性があります。ただし、依存テーブルで ID が競合する可能性があることに注意する必要があります。

于 2008-11-19T18:13:43.497 に答える
1

あなたは正しい方向に進んでいると思います。あなたはそれを本当に良いと説明しました、あなたはいくつかの異なる実体を持っています。エンティティウィッチと呼ばれるテーブルを作成して、すべての一般的な属性を含めることができます(存在する場合)。だから例えば

実在物

  • EntityId
  • 名前

成分

  • EntityId

RecipeIssuer

  • EntityId
  • その他の情報

これで、エンティティにタグを付けるためのテーブルを作成できます。

于 2008-11-19T15:22:31.003 に答える
0

これはどう?

タイプ(PK:タイプ、set_id [、TypeDesc])

属性(PK :( set_id、FK:Type)、Value)

PS:太字/斜体は本当に吸います

于 2008-11-19T15:23:13.623 に答える
0

レシピや材料などは通常通りテーブルを作ります。

次に、タグテーブルは次のようになります:Id、Type、Tag

さまざまな「タイプ」(エンティティ)を区別するために、コードで列挙型を使用することをお勧めします。

于 2008-11-19T15:33:34.150 に答える
0

私の手にも同様の「問題」があります。タグ付けとタグに値を与えることを含む小さな製品データベースを開発しています(タグ名:色、値:緑など)。

2 つの主要なテーブルは、アイテム (I) と記事 (A) です。アイテムは実際の物理的なアイテムであり、記事はアイテムから派生したものです。記事はウェブサイトに表示できるもので、アイテムは倉庫に保管されるものです。この関係の小さな例は、自動車の部品です。既知の寸法やその他のデータを持つラジエーターは、実際にはさまざまなモデルやメーカーに適合します。そのため、ラジエーターを表すために使用されるアイテムは、ラジエーターが適合できるものを示す複数の記事に関連しています。一方、1 つのモデルで 2 つの異なるラジエーターを利用できる場合があります。1 つは工場出荷時の新しいバージョンで、もう 1 つは再生されたばかりです。このような場合、同じ記事に関連する 2 つの項目があります。

つまり、I と A は N:M の関係にあります。

アイテムと記事には特定のプロパティがあります。たとえば、ラジエーターのアイテムには、状態、素材、重量、高さ、幅、厚さなどのデータが含まれる場合があります。この記事には、メーカー、モデル、年、エンジンなどの基本的な情報も含まれていますが、シャーシ モデル、トランスミッション タイプ、または同じモデルで使用された 2 つの異なるフィッティング タイプなどの特別なデータも必要になる場合があります。2 つのアイテムが 1 つの記事にリンクできるため、単に記事にタグを付けることができません。両方の条件値で記事にタグを付けるのはばかげています。一方、モデル、メーカー、または特別な要件の複数のインスタンスで 1 つのアイテムにタグを付けるのも良い考えではありません。_プロパティには 2 つのタイプがあります。最初のタイプは何かがどのようなものかを示し、2 番目のタイプはそれが適合するものを示します。

タグは値を持つ必要はありません。エンティティに割り当てられた従来のタグとして機能するだけです。

ラジエーターは単純な製品の一例にすぎません。コンピューターの部品や衣服をデータベースに入れることもできます。これは、I と A という 2 つの異なるエンティティに異なる「タグ」を付けることができる必要があることを意味します。

Web ショップで記事の検索を実装できるようにする必要があります。「中古日産ラジエーター」というカテゴリがあるツリーベースのナビゲーションを使用しているとしましょう。検索には、記事とアイテムの両方の検索が含まれます。記事にはタグ Model:Nissan があり、アイテムにはタグ Condition:Used があります。もちろん、ユーザーが記事を見ると、その記事に関連付けられているすべてのアイテムが実際に表示されます。

私が熟考している解決策の 1 つは、すべてのプロパティとタグのタグと呼ばれる共通のテーブルであるトライアングル データベース設計です。

テーブル項目 (I)、記事 (A)、およびタグ (T) があります。これらは N:M の関係で結合されます。I2A は項目を記事に結合します。T2I はタグをアイテムに結合し、タグまたはプロパティの値も保存する場合があります。T2A はタグを記事に結合し、タグの値も保存する場合があります。

紙の上では、この問題に対処するためのこの 6 テーブルの設計は非常に良さそうに見えますが、さまざまなタグとその値のセットに一致する記事を選択できる適切なクエリを作成することに頭を悩ませています。たとえば、Condition=Remanufactured 、メーカー=日産

私ができるようにしたいのは、www.summitracing.com のようなものです。「ショップ」の下の左側から部門を選択し、カテゴリを選択すると、アイテムにいくつかのプロパティを与える方法が表示されます. ほとんどのアプリケーションでエンジンのサイズがありますが、リムを探す場合は、幅のプロパティもあります。

これに関するフィードバックは大歓迎です。私はこれを設計しようとして死んでいます。

于 2009-02-15T02:36:58.377 に答える