0

3 つのテーブルを含むデータベースを作成しました。

Restaurant
restaurant_id (autoincrement, PK)

Owner
owner_id (autoincrement, PK)
restaurant_id (FK to Restaurant)

Deal
deal_id (autoincrement)
owner_id (FK to Owner)
restaurant_id (FK to Restaurant)
(PK: deal_id, owner_id, restaurant_id)

各レストランには多くのオーナーがいる場合があります。オーナーまたはレストランのいずれかが取引を参照できるように、Deal に 2 つの外部キーを選択しました。deal テーブルには 3 つの主キーがあり、そのうちの 2 つは外部キーです。そして、それを指す 2 つの 1 対多の関係があります。私の外部キーはすべて主キーであり、後でこのようにして後悔するかどうかはわかりません。このデザインは理にかなっており、私が達成しようとしていることに適しているように見えますか?

編集: ここで本当に必要なのは、オーナーがログインして自分のアカウントを表示しているときに、その特定のレストランに関連付けられているすべての取引を表示および編集できるようにすることです。また、レストランごとに複数のオーナーが存在する可能性があるため、次のようなクエリを実行できる必要があります。select *from deal where restaurant_id = restaurant_id. つまり、私が所有者であり、ログインしている場合、クエリを実行できる必要があります。つまり、所有者である私だけでなく、関連するすべての所有者に関連するすべての取引を取得する必要があります。このレストラン。

4

5 に答える 5

4

用語に問題があります。

テーブルは主キーを1 つだけ持つことができます。2 つの異なる主キーを持つテーブルを作成することはできません。2 つの異なる一意のインデックス (主キーによく似ています)を持つテーブルを作成できますが、存在できる主キーは 1 つだけです。

あなたが求めているのは、複合主キーと複合キーのどちらが必要かということです。複数の列を使用する主キー。

あなたのデザインは問題ありませんが、書かれているように、deal_id 列はおそらく必要ありません。私には、deal の行を一意に識別するには、restaurant_id と owner_id を合わせれば十分であるように思えます。(これは、1 人のオーナーが資本増強または別のオーナーの買収の結果として 1 つのレストランで 2 つの異なる所有権を持つことができる場合には当てはまらないかもしれませんが、問題の説明ではそのようなことは何も言及していません)。

この場合、deal_id は大部分が無駄なストレージです。Deal を指す外部キーを持つ多くのテーブルがある場合、または複数のレストランとオーナーの取引を同時にユーザーに表示したいインスタンスがある場合、deal_id 列を使用するための引数が作成される可能性があります。 .

これらの引数の 1 つが deal_id 列を採用するようにあなたを揺るがすなら、それだけを主キーにする必要があります。自動インクリメント値自体は一意であるため、他の 2 つの列を含めても何も追加されません。

于 2012-05-17T02:57:55.823 に答える
1

一意のフィールドがある場合、これは PK である必要があり、インクリメントされたフィールドになります。
この特定のケースでは、このキーにフィールドを追加することはまったくありません。実際には、パフォーマンスにいくらか影響を与えます (どのくらいか聞かないでください)。

于 2012-05-17T00:46:20.317 に答える
0

最高ではないと思います。

まず、DealテーブルPKはdeal_idである必要があります。列を追加する理由はありません。別のテーブルでdeal_idを参照したい場合は、restaurant_idとowner_idを含める必要がありますが、これは適切ではありません。Deal_idをクラスター化インデックス(この列で編成されたインデックス)にするかどうかは、データアクセスパターンによって異なります。データベースは、検索に最も頻繁に使用されるdata_id値でいっぱいになりますか、それとも主にowner_idまたはrestaurant_idで取引を検索しますか?

また、あなたが説明した2つの別々のFKを使用すると(私が知る限り!)、有効ではない所有者とレストランの組み合わせ(そのレストランに属していない所有者の組み合わせ)を取引に含めることができます。Dealテーブルでは、1つのFKからOwnerと1つのFKからRestaurantの代わりに、両方の列が必要な場合は、(OwnerID、RestaurantID)のOwnerテーブルのみに複合FKがあり、Ownerテーブルに対応する一意のキーがあります。このリンクを許可します。

ただし、このような単純なテーブル構造では、OwnerIDは常にRestaurantIDを完全に暗示しているため、RestaurantIDをDealテーブルから除外しても問題は発生しません。明らかに、Deal:Ownerで1:Mの関係を意味するため、取引をレストランだけにリンクすることはできません。所有者テーブルを介してレストランに基づいて検索するコストは、それほど悪くはないはずです。

于 2012-05-17T01:16:14.457 に答える
0

それは間違いではありません、それは機能します。ただし、お勧めしません。

自動インクリメント主キーは、外部キー(またはマスターキー)なしで機能します

一部のデータベースでは、複数のフィールドを単一の主キーとして使用できません。

複合主キーまたは合成主キーは、クエリで処理するのがより困難です。

複合主キークエリの例:

SELECT
  D.*
FROM 
  Restaurant AS R,
  Owner AS O,
  Deal AS D
WHERE
  (1=1) AND
  (D.RestaurantKey = D.RestaurantKey) AND
  (D.OwnerKey = D.OwnerKey)

単一の主キークエリの例:

SELECT
  D.*
FROM 
  Restaurant AS R,
  Owner AS O,
  Deal AS D
WHERE
  (D.OwnerKey = O.OwnerKey)

場合によっては、レコードの外部キーの値を別のレコードに変更する必要があります。たとえば、顧客はすでに注文し、取引レコードが登録されており、あるレストランのテーブルから別のテーブルに変更することにしました。したがって、「所有者」テーブルと「取引」テーブルのデータを更新する必要があります。

+-----------+-------------+
|  OwnerKey | OwnerName   |
+-----------+-------------+
|      1    | Anne Smith  |
+-----------+-------------+
|      2    | John Connor |
+-----------+-------------+
|      3    | Mike Doe    |
+-----------+-------------+

+-----------+-------------+-------------+
|  OwnerKey |   DealKey   |     Food    |
+-----------+-------------+-------------+
|      1    |       1     | Hamburguer  |
+-----------+-------------+-------------+
|      2    |       2     |   Hot-Dog   |
+-----------+-------------+-------------+
|      3    |       3     | Hamburguer  |
+-----------+-------------+-------------+
|      1    |       3     |    Soda     |
+-----------+-------------+-------------+
|      2    |       1     | Apple Pie   |
+-----------+-------------+-------------+
|      3    |       3     |    Chips    |
+-----------+-------------+-------------+

複合主キーを使用する場合は、「所有者」の新しいレコードと「取引」の新しいレコードを作成し、他のフィールドをコピーして、前のレコードを削除する必要があります。

単一のキーを使用する場合は、新しいレコードを挿入または削除せずに、テーブルの外部キーを変更するだけです。

乾杯。

于 2012-05-17T01:02:18.373 に答える
0

s名前レストランのテーブルが顧客によって予約されているかどうかを識別し、データベースをどのように設計したかを確認するために使用されるように思われます。テーブルを指定しなくても、予約したテーブルをすでに識別できます。所有者テーブルを使用することにより、取引テーブルの外部キーは、所有者テーブルの外部キーとして使用するため、すでに予約されているテーブルを識別できます。テーブル間の関係を定義する際には、実際に賢明である必要があります。冗長性はできるだけ避けてください。:)

于 2012-05-17T01:02:42.930 に答える