模型数据库表示约束

时间:2012-10-13 09:49:00

标签: database data-modeling entity-relationship

我正在构建一个数据库(用于类)来为零件订购应用程序建模。 “供应商”提供零件(不同的供应商可能各自提供一个或多个履行相同角色的零件,每个零件只履行一个角色),“经理”决定哪些零件可订购(只有一个零件履行特定角色)可以订购),用户可以订购零件。

我目前正处于E-R图绘制阶段。我不确定如何模拟零件,角色和orderables。我可以将每个可订购/角色表示为(概念)“客户部分”实体,并为“供应商部分”实体创建两个关系:

enter image description here

对于整个版本的“试用版本”看起来非常俗气,但请相信我,它比我的鸡毛刮笔手写更好。

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

我也尝试使用三元关系和聚合对其进行建模,但我仍然无法捕获所有约束。

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

感谢您提供任何见解。

2 个答案:

答案 0 :(得分: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(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表。 (例如,比向零件添加色谱柱更好。)供应商通常会提供比您今天感兴趣的更多零件,但企业通常希望提前计划,在承诺使用之前收集有关零件的信息他们(在你的情况下,在一个特定的角色)。

答案 1 :(得分: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_id,而不是roles表。