2010-01-28 55 views
0

我們有多個辦事處,每個辦事處內有多個部門(有些部門在多個辦事處有員工)。我們有兩種現有的系統以不同的方式識別員工:一是員工由IDA識別;其他員工由IDB確定。如何強制執行可選的現有唯一鍵的參照完整性?

在員工由IDA識別的情況下,我們需要在SUPERVISOR_IDA中識別該員工的主管(如果有的話)。

我的表看起來像這樣:

IDA 
IDB 
SUPERVISOR_IDA 
OFFICE 
DEPARTMENT 

員工可以有一個以上的辦公位置,或在多個部門,所以同樣IDA或IDB可能存在一次以上,但有不同的辦公室,部門或兩者。

問題是IDA可能爲空(如果是這樣,那麼IDB不爲空)或IDB可能爲空(如果是這樣,那麼IDA不爲空)或兩者都可以存在。

我試圖設置唯一的和/或主鍵和約束來確保數據庫的完整性。

所以我創建了一個唯一的密鑰(IDA,IDB,OFFICE,DEPARTMENT)。

這裏是我的問題:

我需要確保員工引用他們的上司。我想擁有一個自引用的外鍵,以便刪除主管不會留下擁有非空SUPERVISOR_IDA的孤兒員工記錄。但是因爲我需要包括IDB我在這個表上唯一的密鑰,如果我創造我需要包括IDB因此本外鍵:

local PARENT_IDA -> reference IDA 
local OFFICE -> reference OFFICE 
local DEPARTMENT -> reference DEPARTMENT 
**local IDB -> reference IDB** 

這是一個問題,因爲員工IDB不應該是與主管IDB相同。

我知道這似乎是我想在一張桌子上做太多事情,但實際上我的領域很難形容,所以我創建了員工/辦公室/部門作爲例子來說明我的問題。我真的不能將IDA和IDB分解​​成單獨的表格,因爲它們以一些有問題的方式交織在一起,並且一個,另一個或兩者的存在具有一些不能分開的重要含義。

首先,我想在除了上述唯一鍵之外還設置一個唯一鍵(IDA,OFFICE,DEPARTMENT),但與由單個列組成的唯一鍵不同,組合鍵將處理(空, 'A')和(空,'A')作爲副本,而不是允許空列避免違反唯一性約束。

回答

2

我認爲這個問題是與模型。該表應該有一個主鍵(如果IDA或IDB可以爲null,那麼它們不是PK列),並且外鍵應該引用PK。

我認爲您正在嘗試對唯一索引使用FK來強制執行數據模型中的一串跨行驗證規則,例如「員工只能由同一辦公室和部門中的某個人監督」和「一名IDA員工只能由另一名IDA員工監督」。

實際上,當您考慮多個人可能同時更新不同行上的不同列時,實施這些操作非常困難。也就是說,您可以嘗試添加列DEPT_IDA和OFFICE_IDA,並使用觸發器僅在設置了IDA時才從DEPT和OFFICE設置它們。然後在這些列上創建英國

0

我不確定這是否適用於Oracle,但在SQL Server中,我會在SUPERVISORS表上創建一個在UPDATE和DELETE上觸發的觸發器。觸發器將在EMPLOYEES表中查詢SUPERVISORS.SUPERVISOR_IDA = EMPLOYEES.SUPERVISOR_IDA的任何記錄。如果發現任何記錄,它將回滾事務。

我發現這個鏈接概述了你需要做什麼。

http://www.techonthenet.com/oracle/triggers/before_delete.php

+0

使用觸發器來強化關係完整性不是一個好主意。它不能很好地擴展,並且在多用戶環境中中斷(因爲Oracle只允許具有READ COMMITTED隔離級別的事務。 – APC 2010-01-29 13:32:29

1

我認爲你的數據模型是錯誤的。每位員工只能有一個僱員記錄。然後你可以在每個IDA和IDB上都有unique密鑰。

由於員工在多個辦事處工作,因此您需要一張表來表示該表; POSTS將成爲OFFICES和EMPLOYEES之間的交匯點。

問題是SUPERVISOR_IDA和SUPERVISOR_IDB是POSTS的屬性,因此您可以在這些列和EMPLOYEES表之間實施一個外鍵。使用檢查約束來確保如果POSTS記錄由EMPLOYEE_IDA標識,則SUPERVISOR_IDA被填充並且同上EMPLOYEE_IDB。