2

これは、1 対 1 の関係で 2 つのテーブルをリンクする正しいコードMySQLですか?

Table1

CREATE TABLE employees (id INT PRIMARY KEY AUTO_INCREMENT,FullName VARCHAR(50))

Table2

CREATE TABLE salary (id INT PRIMARY KEY AUTO_INCREMENT,SalaryNumber VARCHAR(6))

ALTER TABLE salary
ADD FOREIGN KEY (id) REFERENCES employees (id)
ON DELETE CASCADE
ON UPDATE CASCADE
4

2 に答える 2

4

あなたの例には多くの問題があります.1つ目は、関連のない2つの自動インクリメントIDをリンクしていることです。これは起こるのを待っている悪夢です。これら 2 つの ID の同期が失われるような事態が発生した場合、あなたは水の中にいることになります。

あなたの例では、「従業員」レコードは「給与」レコードが依存する親レコードと見なされます(つまり、対応する給与レコードのない従業員レコードがあるかもしれませんが、給与レコードは必要ありません従業員とは関係ありません)。

MySql ドキュメントに記載されているように、外部キー制約は子テーブルに属します。そのため、「給与」テーブルに必要なのは、次のような列です。

EmployeeIdINT NOT NULL

あなたの外部キーは

ALTER TABLE 給与 ADD FOREIGN KEY (EmployeeId) REFERENCES 従業員 (id) ON DELETE CASCADE ON UPDATE CASCADE

この時点では、同じ EmployeeId を使用して給与テーブルに複数のエントリを挿入することを妨げるものは何もないため、まだ多対 1 の関係があります。

この関係を 1 対 1 にするには、salary.EmployeeId 列に一意のインデックスを作成する必要があります。

このタイプの関係では、次のことに注意することが重要です。

  1. 有効な EmployeeId を持たない給与に行を挿入することはできません
  2. 従業員 ID が重複している行を給与に挿入することはできません。
  3. 給与レコードを削除しても、従業員レコードはそのまま残ります。
  4. 従業員レコードを削除すると、参照している給与レコードが削除されます (この動作が望ましくない場合は、ON DELETE CASCADE を別のものに変更してください)。
  5. 給与テーブルが空になって削除されるまで、employee テーブルを削除することはできません。
于 2013-02-22T17:29:24.693 に答える
0

いいえ、それは 1 対多の関係です。単一の従業員行にリンクする給与行はいくつでも (なしを含む) 持つことができます。

給与は従業員に大きく依存する属性であるため、従業員テーブル自体に配置することを検討します (私たちと共有していない余分な知識があり、これが問題になる場合を除きます)。


個別のテーブル間で 1 対 1 を強制する方法あります。

たとえば、トリガーを使用して重複を停止できますが、トリガーに反対する人もいますが、それでも 1 対 0 のマッピングが表示されるのを防ぐことはできません。

別の方法として、両方のテーブルでダミー行を含む双方向の外部キーを使用して (互いに指している)、一度に 1 つのテーブルに挿入できるようにすることもできます。

これを行う方法は、ダミーの給与行を指す行を employees に挿入することです。

次に、新しく挿入された従業員を指す給与行を挿入します。

次に、従業員行を更新して、新しく挿入された給与行にピントします。もちろん、アプリケーションレベルで参照整合性を維持するために、これはすべて単一のトランザクションとして発生する必要があります。

ダミー行を取得するには、外部キー制約をスキーマに追加する前にダミー行を挿入する必要があります。そうしないと、鶏が先か卵が先かという状況になります。

そのレベルの作業が実際に必要かどうかは議論の余地があります。特に、提案されているようにデータを 1 つのテーブルに結合するだけで 1 対 1 を適用できる場合はそうです :-)

于 2013-01-12T11:17:28.677 に答える