私は少し急いでいるので、あなたの要求で迷ってしまったかもしれません. (しかし、それらをかなり明確に述べるために+1します。) 最初に簡単なことに取り組みましょう。ここでは主に自然キーを使用しています。なぜなら、自然キーを使用すると何が起こっているかを簡単に確認できるからです。あなたにとって本当に重要な部分は、オーバーラップしている外部キー制約 (終わり近く) だと思います。
簡単なもの - 部品、サプライヤー、役割のテーブル。
create table test.parts (
part_num varchar(15) primary key
);
insert into test.parts values
('Part A'), ('Part B'), ('Part C');
-- "Suppliers" provide parts.
create table test.suppliers (
supplier_name varchar(35) primary key
);
insert into test.suppliers values
('Supplier A'), ('Supplier B'), ('Supplier C');
create table test.roles (
role_name varchar(15) primary key
);
insert into test.roles values
('Role 1'), ('Role 2'), ('Role 3');
1 つの要件: すべてのパーツが 1 つの役割を果たすこと。(UNIQUE 制約の詳細と、単に「パーツ」に列を追加する代わりにこのテーブルを使用する方法については、後で説明します。)
create table test.part_roles (
part_num varchar(15) primary key references test.parts (part_num),
role_name varchar(15) not null references test.roles (role_name),
unique (part_num, role_name)
);
insert into test.part_roles values
('Part A', 'Role 1'), ('Part B', 'Role 1'), ('Part C', 'Role 2');
もう 1 つの要件は、各サプライヤが同じ役割を果たす 1 つまたは複数の部品を提供することです。これは「各サプライヤーが複数の部品を供給する」と単純化できると思います。(パーツがどの役割に属しているかについての事実を格納することは、別のテーブルの責任です。)
create table test.supplied_parts (
supplier_name varchar(35) not null
references test.suppliers (supplier_name),
part_num varchar(15) not null references test.parts (part_num),
primary key (supplier_name, part_num)
);
insert into test.supplied_parts values
('Supplier A', 'Part A'),
('Supplier A', 'Part B'),
('Supplier A', 'Part C'),
('Supplier B', 'Part A'),
('Supplier B', 'Part B');
もう 1 つの要件は、マネージャがどの部品を注文可能にするかを決定することです。(マネージャーは GRANT と REVOKE で処理します。) 指定された役割を果たす 1 つのパーツのみを注文できます。(これは、role_name に対する主キー制約または一意制約のいずれかを意味します。) また、誰かが部品を提供しない限り、部品を注文することはできません。(そのため、重複する外部キー制約が必要になります。)
ここで、先ほど述べた test.part_roles (part_num, role_name) の UNIQUE 制約の出番です。
create table test.orderable_parts (
role_name varchar(15) primary key references test.roles,
part_num varchar(15) not null,
foreign key (part_num, role_name)
references test.part_roles (part_num, role_name),
supplier_name varchar(35) not null,
foreign key (supplier_name, part_num)
references test.supplied_parts (supplier_name, part_num)
);
insert into test.orderable_parts values
('Role 1', 'Part A', 'Supplier A'),
('Role 2', 'Part C', 'Supplier A');
part_roles の別のテーブルを使用したほうがよいと思います。(たとえば、部品に列を追加するよりも優れています。) サプライヤーは通常、現在関心のあるよりも多くの部品を供給しますが、企業は多くの場合、事前に計画を立てて、部品の使用を約束する前に部品に関する情報を収集したいと考えています (あなたの場合、特定の役割)。