我有点着急,我可能已经迷失在你的要求中了。(但 +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');
一个要求:每个部分都只扮演一个角色。(有关 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');
另一个要求——每个供应商可以提供一个或多个履行相同角色的零件。我认为这简化为“每个供应商提供多个零件”。(存储有关部件所属角色的事实是不同表的责任。)
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');
另一个要求——经理决定哪些零件可以订购。(用 GRANT 和 REVOKE 处理经理。)只有一个满足给定角色的零件可以订购。(这意味着对角色名称的主键约束或唯一约束。)除非有人提供,否则您不能订购零件。(所以我们需要重叠的外键约束。)
这就是我前面提到的 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 表可能会更好。(例如,比在零件中添加一列更好。)供应商通常提供的零件比您今天感兴趣的要多,但企业通常希望提前计划,在他们承诺使用零件之前收集有关零件的信息(在您的情况下,在特定角色)。