4

まず、これがだましである場合はお詫び申し上げます。

会社のテーブルがあるとします。

 id | company_name
----+--------------
  1 | Someone
  2 | Someone else

...そして連絡先の表:

 id | company_id | contact_name | is_primary
----+------------+--------------+------------
  1 |     1      | Tom          |      1
  2 |     2      | Dick         |      1
  3 |     1      | Harry        |      0
  4 |     1      | Bob          |      0

1 つだけのレコードに各コモンのフラグが設定されている必要がcontactsあるように、テーブルを設定することは可能ですか?is_primarycompany_id

だから私がやろうとした場合:

UPDATE contacts
SET is_primary = 1
WHERE id = 4

Tom... ( id = 1) は の主要連絡先として既にフラグが設定されているため、クエリは失敗しますcompany_id = 1。またはさらに良いことに、クエリが成功するようにトリガーを作成することは可能ですが、同じ操作Tomis_primaryフラグがクリアされますか?

company_idテーブルに存在するかどうかをチェックすることはあまり気にしませんcompanies。私の PHP コードは、この段階に到達する前に既にこのチェックを実行していたはずです (ただし、同じ操作でこれを行う方法があれば、それは素晴らしいことだと思います)。 .

最初にこれについて考えたとき、「それは簡単だろう。列company_idis_primary列に一意のインデックスを追加するだけだ」と思ったが、明らかにそれはうまくいかない。 3 番目の連絡先を追加しようとすると失敗します。しかし、私が必要とする最小限の機能を提供する一意のインデックスを構成する方法があると感じずにはいられません。つまり、2 番目の主要な連絡先を追加しようとする試みを拒否したり、主要な連絡先のない会社を離れようとする試みを拒否したりします。

テーブルに FK を使用してテーブルにprimary_contactフィールドを追加するだけでよいことはわかっていますが、面倒です。両方のテーブルが他のテーブルに FK を持つという考えは好きではありません - 両方のテーブルが互いに依存するのではなく、一方のテーブルが他方に依存するべきだと私には思えます。時間が経つにつれて、何かがうまくいかない可能性が高くなると思います。companiescontacts

総括する:

  • 指定された 1 つのレコードだけcompany_idis_primaryフラグが設定されるように連絡先テーブルを制限するにはどうすればよいですか?
  • 互いに FK を持つ 2 つのテーブルが良い/悪い考えであるかどうかについて、誰か考えがありますか?
4

2 に答える 2

3

テーブル間の循環参照は確かに厄介です。この (10 年前の) 記事を参照してください: SQL By Design: The Circular Reference

このような制約を作成する最もクリーンな方法は、別のテーブルを追加することです。

Company_PrimaryContact
----------------------
company_id
contact_id
PRIMARY KEY (company_id)
FOREIGN KEY (company_id, contact_id)
  REFERENCES Contact (company_id, id)

UNIQUEこれには、テーブルの制約Contactも必要です(company_id, id)

于 2012-02-17T10:38:12.080 に答える
2

その1つの設定の前にクエリを実行できます

UPDATE contacts SET is_primary = 0 WHERE company_id = .....

あるいは

UPDATE contacts
SET is_primary = IF(id=[USERID],1,0)
WHERE company_id = (
    SELECT company_id FROM contacts WHERE id = [USERID]
);

代替案を提示するだけです。個人的には、このタイプの回避策の代わりに、おそらく FK アプ​​ローチを検討するでしょう。つまり、会社テーブルに primary_user_id フィールドを持つフィールドがあります。

contact.is_primary フィールドに依存しないEDITメソッド

別の方法として、まず連絡先から is_primary を削除します。次に、「primary_contact_id」INT フィールドを会社に追加します。第三に、一次連絡先を変更するときは、その primary_contact_id を変更するだけで、バックグラウンドでトリガーなどを必要とせずに、いつでも複数の一次連絡先が存在する可能性を防ぐことができます。

このオプションは、単に INT フィールドを更新するだけなので、どのエンジンでも問題なく機能します。FK への依存などは必要に応じて追加/削除できますが、最も簡単なのは INT フィールドの値を変更することだけです。

このオプションは、企業からプライマリにフラグを立てている連絡先へのリンクが 1 つ、正確に 1 つ必要な場合に実行できます。

于 2012-02-17T10:38:19.543 に答える