MySQLデータベースで1対1の関係を達成しようとしています。たとえば、UsersテーブルとAccountsテーブルがあるとします。また、ユーザーが持つことができるアカウントは1つだけであることを確認します。また、ユーザーごとに1つのアカウントしか存在できないこと。
これには2つの解決策を見つけましたが、何を使うべきかわかりませんし、他の選択肢もあります。
DROP DATABASE IF EXISTS test;
CREATE DATABASE test CHARSET = utf8 COLLATE = utf8_general_ci;
USE test;
CREATE TABLE users(
id INT NOT NULL AUTO_INCREMENT,
user_name VARCHAR(45) NOT NULL,
PRIMARY KEY(id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
CREATE TABLE accounts(
id INT NOT NULL AUTO_INCREMENT,
account_name VARCHAR(45) NOT NULL,
user_id INT UNIQUE,
PRIMARY KEY(id),
FOREIGN KEY(user_id) REFERENCES users(id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
この例では、ユーザーの主キーを指すアカウントで外部キーを定義します。そして、外部キーを一意にするため、アカウントに2人の同一ユーザーを含めることはできません。テーブルを結合するには、このクエリを使用します。
SELECT * FROM users JOIN accounts ON users.id = accounts.user_id;
DROP DATABASE IF EXISTS test;
CREATE DATABASE test CHARSET = utf8 COLLATE = utf8_general_ci;
USE test;
CREATE TABLE users(
id INT NOT NULL AUTO_INCREMENT,
user_name VARCHAR(45) NOT NULL,
PRIMARY KEY(id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
CREATE TABLE accounts(
id INT NOT NULL AUTO_INCREMENT,
account_name VARCHAR(45) NOT NULL,
PRIMARY KEY(id),
FOREIGN KEY(id) REFERENCES users(id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
この例では、主キーから別のテーブルの主キーを指す外部キーを作成します。主キーはデフォルトで一意であるため、この関係は1対1になります。テーブルを結合するには、これを使用できます:
SELECT * FROM users JOIN accounts ON users.id = accounts.id;
今、質問:
私はMySQL Workbenchを使用しており、EER図で1対1の関係を設計し、MySQL WorkbenchでSQLコードを生成すると、1対多の関係が得られます:Sそれは私を混乱させるものです:S
そして、これらのソリューションのいずれかをMySQL Workbench EERダイアグラムにインポートすると、リレーションが1対多として認識されます:Sこれも混乱を招きます。
したがって、MySQL DDLで1対1の関係を定義する最良の方法は何でしょうか。そして、これを達成するためのオプションは何ですか?
主キーはデフォルトで一意であるため、この関係は1対1になります。
いいえ、それは関係を「1対0または1」にします。それは実際に必要なものですか?
yesの場合、「2番目の解決策」の方が優れています。
ところで、あなたはaccounts.id
これが機能するための通常の整数(自動インクリメントではない)。
noの場合、以下を参照してください...
MySQLで1対1の関係を作成する最良の方法は何ですか?
「ベスト」はオーバーロードされたWordですが、「標準」ソリューションは他のデータベースと同じです。両方のエンティティ(ユーザーの場合はアカウント)を同じ物理テーブルに配置します。
これら2つ以外のソリューションはありますか?
理論的には、2つのPK間で循環FKを作成できますが、残念ながらMySQLではサポートされていない鶏と卵の問題を解決するためにdeferred制約が必要になります。
そして、これらのソリューションのいずれかをMySQL Workbench EER図にインポートすると、リレーションが1対多として認識されます:Sそれも混乱します。
私はその特定のモデリングツールであまり実用的な経験はありませんが、それは「多くの」側がユニークになることで「多くの」側が1に制限された「1対多」だからだと思います。 「多」は「1または多」を意味せず、「0または多」を意味するため、「キャップ」バージョンは実際には「0または1」を意味することに注意してください。
1 追加フィールドのストレージ費用だけでなく、セカンダリインデックスも同様です。 常にクラスターテーブル であるInnoDBを使用しているため、クラスター化テーブルのセカンダリインデックスは、ヒープベースのテーブルよりもさらに高価であることに注意してください。
2 InnoDB インデックスが必要 外部キー。
最初のアプローチでは、accountsテーブルにid
とuser_id
の2つの候補キーを作成します。
したがって、2番目のアプローチ、つまり外部キーを主キーとして使用することをお勧めします。この: