2012-10-13 25 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