[英]Modeling a hierarchical data structure
假設我們有實體R,D和E,並且此關系基數
該規范的映射很簡單,但是我們還有另一個要求:
附帶條件:如果E1與某些D1相關並且此D1與R1相關,則E1可能僅被“分配”給R1。
不幸的是,即使E2與D2相關,而D2與R2相關-E2也可能與R2不相關。
一位朋友建議創建一個實體DxR,該實體通過元組(D,R)鏈接其D和R。 然后創建一個關系
嗯...
系統由頂層區域(Z)組成 。 一個區域可以具有多個區域(R) 。
所謂的部門(D)可以分配給區域 。 僅當每個部門屬於不同的區域時,一個部門才能被分配到多個區域。
最后, 雇員(E)屬於一個部門,並且只有一個部門 。
僅當員工部門屬於該地區時,員工才能被分配到該地區。
重要提示: 員工不必屬於其部門所屬的所有區域。
假定在以下圖形中E1屬於D1。 E1也應該屬於R1,但不屬於R2-盡管D1屬於R1和R2:
- Z Z
- __|___ ___|___
- R1 R R2 R
- \_________/
- D1
問:請提出對以上規范進行建模的關系數據庫的表結構?
從某種意義上說,這個問題非常具體,有些人可能會認為它過於本地化。 但是,有一個更普遍適用的想法可能對將來的其他人有用,因此問題不一定太具體。
這些業務規則中真正有趣的部分是這一部分:( 我的重點是補充)
僅當每個部門屬於不同的區域時,一個部門才能被分配到多個區域 。
這是一個模式,它以聲明方式捕獲了幾乎所有陳述的業務規則,而不必訴諸任何觸發器。
create table ZONE
( ID int not null
, NAME varchar(50) not null
, constraint PK_ZONE primary key clustered (ID)
)
create table REGION
( ZONE_ID int not null
, REGION_ID int not null
, NAME varchar(50) not null
, constraint PK_REGION primary key clustered (ZONE_ID, REGION_ID)
, conttraint FK_REGION__ZONE foreign key (ZONE_ID)
references ZONE (ID)
)
create table DEPARTMENT
( ID int not null
, NAME varchar(50) not null
, constraint PK_DEPARTMENT primary key clustered (ID)
)
create table EMPLOYEE
( ID int not null
, NAME varchar(50) not null
, DEPT_ID int not null
, constraint PK_EMPLOYEE primary key clustered (ID)
, constraint FK_EMPLOYEE__DEPARTMENT foreign key (DEPT_ID)
references DEPARTMENT (ID)
)
上表很明顯。 但是,有一個特別的問題: REGION
表具有一個復合主鍵,其中包括FK到ZONE
。 這對於傳播有關部門必須在區域內不同的約束很有用。
將部門分配到區域需要一個相交表:
create table DEPT_ASGT -- Department Assignment
( REGION_ID int not null
, DEPT_ID int not null
, ZONE_ID int not null
, constraint PK_DEPT_ASGT (REGION_ID, DEPT_ID)
, constraint FK_DEPT_ASGT__REGION foreign key (ZONE_ID, REGION_ID)
references REGION (ZONE_ID, ID)
, constraint FK_DEPT_ASGT__DEPARTMENT foreign key (DEPT_ID)
references DEPARTMENT (ID)
, constraint UN_DEPT_ASGT__ZONES unique nonclustered (ZONE_ID, DEPT_ID)
)
這個交集表是很正常的,因為它對它鏈接的每個表都有一個外鍵。 此交集表的特殊之處在於唯一性約束。 這就是強制執行以下規則的規定:部門不能位於同一區域內的兩個不同區域中。
最后,我們需要將員工映射到部門和地區。 這需要另一個交集表:
create table EMP_ASGT -- Employee Assignment
( REGION_ID int not null
, DEPT_ID int not null
, EMPLOYEE_ID int not null
, constraint PK_EMP_ASGT (REGION_ID, DEPT_ID, EMPLOYEE_ID)
, constraint FK_EMP_ASGT__DEPT_ASGT (REGION_ID, DEPT_ID)
references DEPT_ASGT (REGION_ID, DEPT_ID)
, constraint FK_EMP_ASGT__EMPLOYEE (EMPLOYEE_ID) refernces EMPLOYEE (ID)
)
您將注意到EMPLOYEE
表具有DEPARTMENT
的外鍵-這將強制執行以下規則:每個員工只能屬於一個部門。 EMP_ASGT
表添加有關員工參與的區域的詳細信息。由於員工可能未參與其部門分配到的每個區域,因此EMP_ASGT
表將員工連接到他們所參與的那些區域。
這是需要觸發器或其他一些過程邏輯的地方。 您需要確保EMPLOYEE.department_id與EMP_ASGT中的記錄保持一致。 您可以通過將EMPLOYEE的PK設置為ID和DEPT_ID的組合,嘗試將其推入聲明性參照完整性,但這將迫使您決定是否要違反3NF或使員工部門更改為一個程序丑陋的混亂局面。 歸根結底,只要稍加觸發即可確保EMP_ASGT不反對EMPLOYEE.DEPT_ID,這將大大減少麻煩。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.