2012-10-13 24 views
3

我正在构建一个数据库(对于一个类)来建模零件排序应用程序。 “供应商”提供部件(不同的供应商可能提供一个或多个能够履行相同职责的部分,而每个部分只能担任一个角色),“经理”决定哪些部分将可订购(只有一个部分履行了特定职责可以订购),用户可以订购部件。模型数据库来表示约束条件

我目前在E-R关系图绘制阶段。我不确定如何对部件,角色和可订购器进行建模。我可以代表一个(概念)“客户一部分”实体每个订购/角色,并创建两个关系到“供应商部件”实体:

enter image description here

这看起来极其俗气与“创建者试用版的”遍布它,但相信我,这比我的鸡抓伤手写更好。

但是,有一个关键的约束,这里不会被捕获。想象一下,你有两套供应商部件,每一个都能履行一个角色。每个部分(每个角色)将由一个客户部分表示。然而,该模型并不能保证客户部分将对应于在“订单”关系中履行正确角色的部分。

我也试着用三元关系和聚合来建模它,但我仍然无法捕获所有的约束。

我的问题归结为:我有部分,角色和orderables。角色和orderables映射1-1,并且可以真正地合并成一个实体。我如何表示每个部分只与一个角色关联,每个角色恰好与一个可订购关联,反之亦然,每个可订购与恰好与同一个可订购角色相关联的一个部分关联?

谢谢你的任何见解,你可能有。

回答

2

我有点匆忙,我可能会迷失在你的要求中。 (但是+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处理经理。)只有一个完成特定角色的部分可以进行订购。(这意味着role_name上的主键约束或唯一约束)。除非有人提供它,否则您不能订购零件。 (所以我们需要重叠外键约束。)

这就是我前面提到的test.part_roles UNIQUE约束(PART_NUM,ROLE_NAME)的用武之地。

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表更好。 (例如,比向零件添加列更好)。供应商通常会提供更多的零件,而不是您现在的,但企业通常希望提前计划,在零件承诺使用前收集有关零件的信息(在您的案例中,在一个特定的角色)。

+0

谢谢!这应该很好地满足要求。奖励! – Oxynatus

0
suppliers 
--------- 
PK supplier_id 

parts -- 1-1 part to role 
----- 
PK part_id 
FK role_id 

stocks -- suppliers' parts 
------ 
PK stock_id 
FK supplier_id 
FK part_id 

roles 
----- 
PK role_id 

managers 
-------- 
PK manager_id 

selections -- part selected by a manager for a role 
---------- 
PK selection_id 
FK manager_id 
FK role_id 
FK part_id 

LEGEND: PK = Primary Key (assuming SERIAL PRIMARY KEY), FK = Foreign Key 

取而代之的是selections表,你也可以添加到FK part_idroles