sql >> データベース >  >> RDS >> Mysql

MySQL:2つのn:1関係ですが、同時に両方ではありません

    現在のデザインは排他的アークと呼ばれます ここで、sets テーブルには2つの外部キーがあり、そのうちの1つだけがnull以外である必要があります。特定の外部キーは1つのターゲットテーブルしか参照できないため、これはポリモーフィックアソシエーションを実装する1つの方法です。

    もう1つの解決策は、両方のusersが共通の「スーパーテーブル」を作成することです。 およびschools 参照し、それをsetsの親として使用します 。

    create table set_owner
    
    create table users 
      PK is also FK --> set_owner
    
    create table schools
      PK is also FK --> set_owner
    
    create table sets 
      FK --> set_owner
    

    これは、インターフェースに類似していると考えることができます。 OOモデリングの場合:

    interface SetOwner { ... }
    
    class User implements SetOwner { ... }
    
    class School implements SetOwner { ... }
    
    class Set {
      SetOwner owner;
    }
    

    コメントを再確認してください:

    SetOwnersテーブルにid値を生成させます。ユーザーまたは学校に挿入する前に、SetOwnersに挿入する必要があります。したがって、ユーザーと学校のIDをではないようにします。 自動インクリメント; SetOwnersによって生成された値を使用するだけです:

    INSERT INTO SetOwners DEFAULT VALUES; -- generates an id
    INSERT INTO Schools (id, name, location) VALUES (LAST_INSERT_ID(), 'name', 'location');
    

    このように、特定のID値が学校とユーザーの両方に使用されることはありません。

    あなたは確かにこれを行うことができます。実際、ユーザーと学校の両方に共通する他の列が存在する可能性があり、これらの列をスーパーテーブルのSetOwnersに配置できます。これは、MartinFowlerのクラステーブル継承 に入ります。 パターン。

    参加する必要があります。特定のセットからクエリを実行していて、それが(学校ではなく)ユーザーに属していることがわかっている場合は、SetOwnersへの参加をスキップして、ユーザーに直接参加できます。結合は必ずしも外部キーによるものである必要はありません。

    SELECT u.name FROM Sets s JOIN Users u ON s.SetOwner_id = u.id WHERE ...
    

    特定のセットがユーザーに属しているのか学校に属しているのかわからない場合は、両方に外部結合を行う必要があります。

    SELECT COALESCE(u.name, sc.name) AS name 
    FROM Sets s 
    LEFT OUTER JOIN Users u ON s.SetOwner_id = u.id
    LEFT OUTER JOIN Schools sc ON s.SetOwner_id = sc.id 
    WHERE ...
    

    SetOwner_idは、UsersまたはSchoolsのいずれかのテーブルと一致する必要がありますが、両方と一致する必要はありません。



    1. PHP:ビューをカウントし、カウントを1つのIPアドレスに制限するためにテーブル行の値をインクリメントする方法

    2. MySQLの電話番号に最適なデータ型はどれですか?また、そのためのJava型マッピングはどうあるべきですか?

    3. ユーザー入力に依存する長いクエリに対してPHPでMySQLエラーを表示するにはどうすればよいですか?

    4. Laravel 5.5は、ConsoleTVのチャートパッケージを使用して動的チャートをレンダリングできません