ここには 2 つの異なる問題があります。
- 宣言的制約の管理。
- 挿入、更新、および削除の管理。
x のすべての行に対して y に行が存在することを保証する「通常の」方法は、両方のテーブルに外部キーを含めることです。各テーブルは他のテーブルを参照します。
create table x (
x_id integer primary key,
y_id integer not null
);
create table y (
y_id integer primary key,
x_id integer not null references x (x_id)
);
alter table x
add constraint one_to_one
foreign key (y_id)
references y (y_id) deferrable initially deferred;
begin transaction;
insert into x values (1, 100);
insert into y values (100, 1);
commit;
これは、すべての "x" が "y" を持つことを保証しますが、いわば、すべての "x" が異なる"y" を持つこと、またはすべての "x" が独自の "y" を持つことを保証するものではありません。それがあなたの要件かどうかはわかりません。
2 つのテーブル間に 1:N の関係があるため、これは探しているものとは異なります。機能させることはできますが、テーブル「y」への変更を管理するトリガーを作成する必要があると思います。たとえば、ユーザーが「x」が外部キー参照を保持している行を「y」から削除した場合、「x」を更新して「y」の別の行を参照する必要があります。
しかし、これは 2 番目の問題、つまり挿入、更新、および削除の管理につながります。それにはいくつかの方法があります。
- クライアントは、データベースの一貫性を保つために必要なすべてのステートメントを提供する責任があります。(上記の外部キーの問題の可能性のある例外を除いて、「y」のトリガーで処理する方がよい場合があります。)
- クライアントはベース テーブルに直接アクセスできません。すべての変更は、ストアド プロシージャを介して行われます。
- クライアントはベース テーブルに直接アクセスできません。すべての変更は、更新可能なビューを通じて行われます。
ストアド プロシージャと更新可能なビューを使用すると、"y" に行を自動的に追加できますが、そのためには手続き型のコードを記述する必要があります。