我有点着急,我可能会迷失在你的要求中。 (但 +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 表可能会更好。 (例如,比在零件中添加一列更好。)供应商通常会提供比您今天感兴趣的更多的零件今天,但企业通常希望提前计划,在承诺使用零件之前收集有关零件的信息他们(在您的情况下,担任特定角色)。