3

3 つのデータベース テーブルがあります。

  • ユーザー
  • メール
  • 招待状

メールは user_id フィールドによってユーザーにリンクされます。

招待は、user_id フィールドによってユーザーにもリンクされます

電子メールは招待なしで作成できますが、すべての招待には電子メールが必要です。

特定の招待状のメールを見つけられるように、メールと招待状のテーブルをリンクしたいと思います。

ただし、これにより循環参照が作成され、招待状と電子メール レコードの両方が同じユーザーの ID を保持します。

これは悪い設計ですか? もしそうなら、どうすれば改善できますか?

私の感覚では、外部キーと優れたビジネス ロジックを使用すれば問題ないと思います。

users
-----
id

emails
------
id
users_id

invitations
-----------
id
users_id
emails_id
4

5 に答える 5

2

これは循環参照ではありません。

電子メールが招待状と強力な整合性関係を持ち、招待状が独立した強力な整合性関係を電子メールに戻す場合 (たとえば) です。

編集:デザインについて

Henk Holterman が指摘するように、問題は設計が適切な程度まで正規化されているかどうかです。

表の想定: 主キーなど

ユーザー: id
電子メール: id、users_id
招待: id、users_id、email_id

また、table_id フィールドに外部キーがあり、テーブルに他の制約が設定されていない (たとえば、キーの一部のみが一意であるなど) と仮定する、次のようにモデル化されます。

  • ユーザーごとに複数の電子メールが存在する可能性があり、対応するユーザーレコードのない電子メールを持つことはできません
  • メールごとに複数の招待があり、対応するメールやユーザー レコードがない招待はできません (注: 上記の定義から、user_id がメールまたはユーザーのエントリを参照しているかどうかはわかりません)。

これらのルールが、モデル化しようとしている現実世界の状況のルールに対応しているかどうかを判断できるのは、あなただけです。

データベース設計を見る 1 つの方法は、実際には間違ったデータベース設計はなく、ほとんどの場合、エラーのように見えるものを正当化するデータを見つけることができるということです。そのため、規則 (文の形式) と表 (ER 図、表と関係の説明) の両方を使用しないと、設計に問題があるかどうかを判断することはできません (個人的な経験から提案を与えることは可能ですが)。

説明すると、上記の注記では、user_id がどのテーブルを参照しているかが明確ではないため、簡単に答えられるように思えるかもしれません。そして、すべての招待にはメールがあるとあなたが言ったことを考えると、一般的な答えは、mail テーブルから user_id を参照する必要があるということです。

そうしないと、招待状に記録されている user_id と、メールに記録されている user_id が異なる招待状が存在する可能性があります。

通常、これにより、「データを正規化する」というラベルの付いた赤いライトが頭の中で点滅します。しかし、ここでは、email_id が user_id を決定するという暗黙の仮定がよくありますが、それは正しくない可能性があります (!)。

これは、データのセマンティクス (各テーブルの述語) によって異なります。たとえば、ある人に招待状を送信し、別の人から電子メールの返信を受け取ることができる状況をモデル化しようとしている場合 (たとえば、秘書を通じて人々を招待し、直接の返信を受け取る)、赤いライトが消え、すべて問題ありません。これが実際に起こったことであり、設計で許可することです。

于 2010-04-08T08:17:34.140 に答える
1

メールは招待なしで作成できますが、すべての招待にはメールが必要です。

invitation1つにつき1つ以上存在できますemailか?そうでない場合、あなたのデザインはすでに間違っています。

特定の招待状のメールを見つけることができるように、メールと招待状のテーブルをリンクしたいと思います。ただし、これにより循環参照が作成され、招待状と電子メールレコードの両方が同じユーザーのIDを保持します。

inが同じinを参照しているuser_idかどうかは(私には)不明です。もしそうなら、それは冗長であり、非正規化です。それを削除し、に戻るためのリンクテーブルとして使用します。パフォーマンスなどのために必要な場合は、両方の列に全体(主キーであるため、すでに一意)と外部キーを作成します。これにより、データの整合性を犠牲にすることなく非正規化が可能になります。invitationuser_idemailemailuser_idunique constraintemail.(id, user_id)id

それが異なる user_id場合は、名前を少し改善することをお勧めします。のようなものにinvited_user_idなりemail.user_idますemail.sent_by_user_id

于 2010-04-08T11:24:35.953 に答える
1

ここでの適切な通常の形式は、招待状がユーザーではなく電子メールとFK関係を持つようにすることだと思います。そして、それはうまくいくと思います。

あなたの説明では、招待状はユーザーに属していると述べていますが、制約から、招待状は電子メールに属していると言う方が正確です。

一方、あなたは正しいです。招待状にUserIdとEmailIdの両方を与えることは大きな問題ではありません。それもあまり利点がありません。

于 2010-04-08T08:16:31.593 に答える
1

私はあなたがすでに持っているすべての答えに満足していると思います.テーブル名を複数形で使用しないでください.

それは紛らわしく、不必要です。

user_idがinvitationsテーブルに属していないという意見を共有しますが、user_idとemail_idの間に強力なリンクを作成したいと本当に確信している場合に限ります。

その場合は、招待テーブルから user_id を削除するだけです。それは役に立ちません。

于 2011-12-06T02:45:43.573 に答える
1

すべての招待には電子メールが必要ですが、電子メールは招待なしで作成できます。わかりました-しかし、ユーザーなしでメールを作成できますか?

  • 招待状に電子メールが必要であり、電子メールもユーザーに属している必要がある場合、招待状は実際にはユーザーに関連しています。この場合、現在のデータ モデルは問題なく、フィールドを追加する必要はありません。ユーザー ID を介して電子メールへの招待に参加するだけです。

  • ユーザーなしで電子メールが存在できる場合、電子メールはユーザーと招待の両方から独立しています。この場合、「users」と「invitations」の両方に「emails」テーブルにリンクする「email-id」フィールドが必要です。ただし、この場合、ユーザーが 1 つの電子メールを受け取り、招待状には別の (または重複した) 電子メールが送信されるという状況になる可能性があります。

于 2010-04-08T09:42:19.847 に答える