sql >> データベース >  >> Database Tools >> phpMyAdmin

phpMyAdminでテーブル間の関係を設定する方法

    table2外部キー制約は、table2のcustomerId値がtable1にcustomerIdとして表示される必要があることを意味します。 table1に表示されないcustomerIDをtable2に挿入しているため、エラーが発生します。

    DBMSは自動インクリメントによってtable1customerIDを生成しているため、行を挿入する場合、そのcustomerIDを使用して行をtable2に挿入するには、その値を取得する必要があります。

    「table1とtable2の関係はすでに確立している」とは、「外部キー制約を宣言した」という意味だと思います。これは、「table1に挿入した後、DBMSはtable2に挿入するときに、自動生成されたキー値を外部キー値として使用する」という意味だと思います。しかし、それはそれを意味するものではありません。あなたはそれを自分でしなければなりません。外部キー制約は、DBMSがすべてのtable2customerId値がtable1customerId値として表示されることを確認することを意味します。

    以前に挿入されたキー値を、そのキーへの外部キーを使用してテーブルに挿入するときに、対応する値として使用でき、使用する必要があります。

    DBMSによって生成された自動インクリメントされたキー値を取り戻すには、を使用します。 LAST_INSERT_ID()

    INSERT INTO table1 (CustomerName,Address,State)
    VALUES('value1','value2','value3');
    INSERT INTO table2 (customerId,product,cost)
    VALUES(LAST_INSERT_ID(),'valueA','valueB');
    

    これがその目的です。ただし、使用しない場合の問題は次のとおりです。

    まず、シリアル化されたトランザクションを実行していない場合は、LAST_INSERT_ID()を使用する必要があります。 table1の挿入後、table2の挿入前に、他のユーザーが新しい行を含む行を追加したり、行を削除したり、新しい行を含む行を変更したりする可能性があるためです。したがって、table1を挿入した後、追加したことがわかっているcustomerId値を取得した後、table1のクエリに依存することはできません。

    次に、シリアル化されたトランザクションを実行していて、LAST_INSERT_ID()を使用していないとします。

    (CustomerName、Address、State)もスーパーキーである場合 table1の、つまりその値は一意です。つまり、SQL UNIQUE / KEY / PKがそのすべてまたは一部の列で宣言されている場合、それを使用して、関連付けられた新しいcustomerIdを照会できます。

    set @customerId = (
        SELECT customerId
        FROM table1
        WHERE CustomerName = 'value1'
        AND Address = 'value2'
        AND State = 'value3');
    INSERT INTO table2 (customerId,product,cost)
    VALUES(@customerId,'valueA','valueB');
    

    ただし、(CustomerName、Address、State)がスーパーキーではない場合 table1の場合、これを行うことはできません。そのサブ行と重複している他の行がtable1にある可能性があるためです。したがって、複数の行を取り戻すことができます。したがって、どれが最新のものかわかりません。代わりに、挿入する前にtable1を照会してから挿入し、customerIdの古いセットと新しいセットの違いを見つける必要があります。

    CREATE TEMPORARY TABLE table1old (
        customerId (int) PRIMARY KEY
        );
    INSERT INTO table1old
    SELECT customerId FROM table1;
    
    INSERT INTO table1 (CustomerName,Address,State)
    VALUES('value1','value2','value3');
    
    set @customerId = (
        SELECT customerId
        FROM table1
        WHERE CustomerName NOT IN table1old);
    INSERT INTO table2 (customerId,product,cost)
    VALUES(@customerId,'valueA','valueB');
    

    LAST_INSERT_ID()を使用するだけです。

    PS:興味深いことに、テーブルの定義を考えると、理想的には次のように書くことができます:

    INSERT INTO (
        SELECT CustomerName,Address,State,A,B
        FROM table1 JOIN table2
        USING (CustomerId))
    VALUES('value1','value2','value3','valueA','valueB')
    

    結果として生じる可能性のある新しいtable1とtable2の値のペアが1つしかないためです。現在、MySQLの複数のテーブルに関係するものはありませんが、SQLのビューを介したいくつかの法的な更新があります




    1. mampでphpmyadminにアクセスする

    2. phpMyAdminアクセスが拒否されました

    3. MySQLテーブルのデフォルトの文字セットを変更するにはどうすればよいですか?

    4. XAMPP1.7.7を解決する方法-PHPMyAdmin-UbuntuでのMySQLエラー#2002