クライアント固有のアイテムをリンクするために使用される次のテーブルについて、誰かと話し合っています。
Table LINK:
Client (int)
Item1 (int)
Item2 (int)
これは論争のあるデザインです。3つのフィールドはすべて、他のテーブルを参照します。2つのItemフィールドは、同じ他のテーブルを参照します。これらは実際のフィールド名ではないため、命名規則については気にしないでください(ただし、「1」と「2」は実際にはフィールド名の一部です)。私は、この設計は1NF違反の理由で悪いと主張していますが、他の人は、これは不快に思えますが、他のすべてのオプションは、特定のユースケースでは悪いと主張しています。
ノート:
- ほとんどの場合、2つのアイテムを相互にリンクするだけで済みます。
- ただし、N:1グループは許可されます。このような場合、同じItem1がItem2の値が異なる複数の行で繰り返されます。
- 一部のItem2値(既存のItem1-Item2リンク内)自体が他のItemにリンクされている場合も非常に少なく、これらの場合、これらの値はItem1列にあり、他のリンクされた値はItem2列にあります。 ; リンクされたすべてのアイテムは1つのグループに対応するため、そのように取得する必要があります。
私の主張:
- これは1NFに違反します。Item1とItem2は同じテーブルの外部キーであるため、繰り返しグループを構成します(相手は繰り返しグループの定義に同意しません)。
- Itemの検索の場合、これは、たとえばGroupIDフィールドを代わりに使用するテーブルでは、1つではなく2つのインデックスが必要であることを意味します。
- これにより、制限句はItem1フィールドとItem2フィールドの両方を調べる必要があるため、このテーブルで特定のアイテムを検索するクエリはより複雑になります。
- アイテムリンクのチェーンが発生する場合の取得は、より複雑になります。
反対側は主張します:
- 最も実行可能な代替案は、単一のItemフィールドと追加のGroupIDフィールドを持つテーブルです。
- より単純で、より一般的な2項目のリンクの場合は、より複雑になります。
- GroupIDスロットの取得に同時実行の問題がある可能性があり、それを管理する必要があります
- GroupIDの同時実行性の問題を管理するには、一意性の制約があるフィールドにGroupIDを含む2番目のテーブルが必要になる可能性があります
- 特にORMが使用されている場合は、少なくとも一部の時間は結合を実行する必要があります。結合は、現在の設計のように単一のテーブルを使用するよりも効率的ではありません。
これについていくつか意見を聞きたいと思います。私はデータベース設計、特に1NFに関するSOに関する他の投稿を読みましたが、それらは私が望んでいたように上記の私のケースを具体的に扱っていません。また、オンラインでの多くの調査に基づいて、1NFのようないわゆる標準は、さまざまな人々によってさまざまな方法で定義できることも理解するようになりました。私は両方の議論について可能な限り明確にし、どちらか一方にバイアスをかけないように努めました。
編集1:
- Item1とItem2は(金融)取引です
- 「1」と「2」は実際にはフィールド名の一部です