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

PHPで外部キーを使用する方法

    外部キー列/曖昧性解消の制約

    外部キー制約を参照していると仮定します 、簡単な答えはあなたはそれらを使用しないです 。

    そして、ここに長いものがあります:

    列が外部キーであるを参照することに慣れています。 他のテーブルに。特に正規化プロセスでは、 "user_purchase.i_idのようなフレーズ itemsへの外部キーです テーブル」 非常に一般的です。これは関係を説明するための完全に有効な方法ですが、実装フェーズに達すると少しあいまいになる可能性があります。

    なしでテーブルを作成したとします。 FOREIGN KEY 条項:

    CREATE TABLE user(
      id INT(11) NOT NULL AUTO_INCREMENT,
      username VARCHAR(50) NOT NULL,
      password VARCHAR(20) NOT NULL,
      PRIMARY KEY (id)
    );
    
    CREATE TABLE items(
      i_id INT(11) NOT NULL AUTO_INCREMENT,
      name TINYTEXT NOT NULL,
      price DECIMAL(8,2) NOT NULL,
      PRIMARY KEY (i_id)
    );
    
    CREATE TABLE user_purchase(
      i_id INT(11) NOT NULL,
      name TINYTEXT NOT NULL,
      id INT(11) NOT NULL,
    );
    

    関係的には、外部キーのに注意してください。 まだ実装されていますuserを参照する列があります テーブル(id )およびitemsを参照する別のアイテム テーブル(i_id )-nameを入れましょう しばらく脇に置きます。次のデータを検討してください:

      user              user_purchase    items
    | id  username |    | id  i_id |    | i_id  name            price |
    | 23  john     |    | 55   10  |    |  10   chocolate bar    3.42 |
    | 55  mary     |    | 70   10  |    |  33   mobile phone    82.11 |
    | 70  fred     |    | 70   33  |    |  54   toothpaste       8.67 |
                        | 55   10  |    |  26   toy car          6.00 |
                        | 70   26  |
    

    関係はそこにあります。 user_purchaseを使用して実装されます 誰が何を購入したかに関する情報を保持するテーブル 。関連するレポートをデータベースに照会する場合は、次のようにします。

    select * from user_purchase p
    join user u on (p.id=u.id)
    join items i on (p.i_id=i.i_id)
    

    これが、リレーションと外部キーのの使用方法です。 関与します。

    さて、もし私たちがそうしたらどうなるでしょう:

    insert into user_purchase (id,i_id) values (23,99)
    

    どうやら、これは無効なエントリです。 id=23のユーザーがいますが 、i_id=99のアイテムはありません 。 RDBMSはそれを可能にします。なぜなら、それはそれ以上のことを知らないからです 。まだ。

    ここで、外部キーが制約します。 場に出る。 FOREIGN KEY (i_id) REFERENCES items(i_id)を指定する user_purchaseで テーブル定義では、基本的にRDBMSに従うルールを指定します。 i_idのエントリ items.i_idに含まれていない値 列は受け入れられません 。つまり、外部キー 参照を実装します 、外部キー制約 参照整合性を適用します

    ただし、上記のselect FK制約を定義したからといって、変更されることはありません。したがって、あなた データを保護するために、RDBMSが使用するFK制約を使用しないでください。

    冗長性

    自問してみてください:なぜあなたはそれが欲しいのですか? 2つの外部キーが同じ目的を果たす場合、冗長性は最終的に問題を引き起こします。次のデータを検討してください:

     user_purchase                   items
    | id  i_id  name           |    | i_id  name            price |
    | 55   10   chocolate bar  |    |  10   chocolate bar    3.42 |
    | 70   10   chocolate bar  |    |  33   mobile phone    82.11 |
    | 70   33   mobile phone   |    |  54   toothpaste       8.67 |
    | 55   10   toothpaste     |    |  26   toy car          6.00 |
    | 70   26   toy car        |
    

    この写真の何が問題になっていますか?ユーザー55を実行しました 2つのチョコレートバー、またはチョコレートバーと歯磨き粉を購入しますか?この種のあいまいさは、データの同期を維持するための多大な労力につながる可能性があります。これは、外部キーの1つだけを保持する場合は不要です。実際、nameを削除してみませんか 関係によって暗示されるため、列全体。

    もちろん、PRIMARY KEY(i_id,name)を設定して、複合外部キーを実装することでこれを解決できます。 itemsの場合 テーブル(または追加のUNIQUE(i_id,name)を定義する インデックス、それは実際には重要ではありません)そしてFOREIGN KEY(i_id,name) REFERENCES items(i_id,name)を設定します 。このように、itemsに存在する(i_id、name)カップルのみ テーブルはuser_purchasesに対して有効です 。 まだ1つあるという事実は別として 外部キーi_idであれば、このアプローチはまったく不要です。 列はすでにアイテムを識別するのに十分です(nameについて同じことを言うことはできません 列...)。

    ただし、テーブルに複数の外部キーを使用することに対する規則はありません。実際、そのようなアプローチを必要とする状況があります。 person(id,name)について考えてみましょう。 テーブルとparent(person,father,mother) 1つは、次のデータを使用します:

     person             parent
    | id  name    |    | person  father  mother |
    | 14  John    |    |   21      14      59   |
    | 43  Jane    |    |   14      76      43   |
    | 21  Mike    |
    | 76  Frank   |
    | 59  Mary    |
    

    明らかに、parentの3つの列すべて テーブルはpersonへの外部キーです 。 同じ関係ではありません 、ただし、3つの異なるものの場合 :人の親も人であるため、対応する2つの列は同じテーブルpersonを参照する必要があります します。ただし、3つのフィールドはだけではないことに注意してください。 だけでなく、する必要があります 別のpersonを参照する s同じparent 行、誰も彼自身の親ではなく、誰の父親も彼の母親ではないので。



    1. 自動インクリメントされた主キーを持つMySQLにデータを挿入するにはどうすればよいですか?

    2. JDBCドライバーとの統合セキュリティを使用してSQLServerに接続するにはどうすればよいですか?

    3. データベースから画像を挿入する方法は?

    4. ソートを使用した再帰的サブクエリ