2010-02-18 76 views
5

我在MySQL服務器下表:如何跨多個表執行的唯一身份

Companies: 
- UID (unique) 
- NAME 
- other relevant data 

Offices: 
- UID (unique) 
- CompanyID 
- ExternalID 
- other data 

Employees: 
- UID (unique) 
- OfficeID 
- ExternalID 
- other data 

在他們每個人的UID是唯一標識符,由數據庫創建的。

有外鍵可以確保UID上Employee - > Office - > Company之間的鏈接。

辦公室和員工中的ExternalID字段是公司(我的客戶實際)提供給我的應用程序的ID。客戶沒有(也不關心)我自己的ID,並且我的應用程序從他們收到的所有數據僅根據其ID(即我的表中的ExternalID)標識。

I.e.來自客戶端的僞語言請求就像「我是公司X,更新我的員工Y的數據」。

我需要對CompanyID和Employees.ExternalID的組合強制執行唯一性,所以在我的數據庫中不會有同一公司的員工有重複的ExternalID。

我想約3可能的解決方案:

  1. 更改爲員工架構,包括CompanyID,並在這兩個領域創造出獨特的約束。

  2. 強制執行觸發器,在Employees中更新/插入時驗證唯一性。

  3. 強制對應用程序級別(即我的接收服務)進行檢查。

我的另類dbadmin功能於我的最高審計機關是(3)是最糟糕的解決方案,因爲它不保護不一致的數據庫應用程序錯誤或其他什麼東西的情況下,並極有可能將是最慢一。我可能會想要觸發器解決方案,但它可能會變得複雜,特別是如果需要在單個語句中執行多個插入/更新,並且我不確定性能與(1)的關係。 (1)看起來是最快和最簡單的方法,但有點違揹我對關係模型的理解。

SO DB專家認爲每種方法的優缺點是什麼,特別是如果有可能增加額外的間接層次 - 即公司 - >辦公室 - >部門 - >員工,以及相同的唯一性需要保存(公司/員工)。

回答

3

你是對的 - #1是最好的選擇。當然,我會乍一看(因爲捷徑)而質疑它,但知道業務規則以確保員工只與一家公司相關 - 這是有道理的。

此外,我有一個外鍵將員工表中的companyid與officeid中的companyid關聯起來。否則,您允許員工與沒有辦公室的公司有關。除非這是可以接受的......

如果關係無法在數據模型中演示,並且從應用程序提供的邏輯服務意味着邏輯集中 - 觸發器不可能發生錯誤數據,除非有人放棄限制(這意味着你有更大的問題)。

+0

@OMG:是的,外鍵是外鍵。爲了簡單起見,我沒有在Q中添加它們。無論如何感謝您發現這一點。我將編輯Q. – 2010-02-18 22:23:00

0

將auto_increment_increment設置爲您擁有的表的數量。 SET auto_increment_increment = 3; (你可能想把它設置在我的。CNF)

然後手動每個表的起始AUTO_INCREMENT值 第一個表的第二表中所設置爲不同的值爲1,〜2,第三表3

表1將有像1,4,7值10,13等

表2將具有值等2,5,8,11,14等

表3將有像3,6,9,12,15-值等

當然,這只是一個選擇,我個人只是讓它成爲一個組合值即可以像TableID,AutoincrementID那樣簡單,其中TableID在所有行中都是常量。

+0

當你添加一個4臺這樣壯觀失敗。 – 2010-02-18 21:39:50

+0

有趣的想法。那麼我究竟如何強制組合Company + Employee.ExternalID的唯一性呢? – 2010-02-18 22:26:26

+1

在思考中,我的想法很愚蠢,儘管創建獨特創意的一個有趣方法是通過一個票據表。 http://code.flickr.com/blog/2010/02/08/ticket-servers-distributed-unique-primary-keys-on-the-cheap/ – MindStalker 2010-02-19 13:48:54

1

貴公司提供的每個表格都應該包含CompanyID到公司提供的ID中的`UNIQUE KEY'。

公司提供的引用完整性應使用公司提供的IDS:

CREATE TABLE company (
     uid INT NOT NULL PRIMARY KEY, 
     name TEXT 
     ); 

CREATE TABLE office (
     uid INT NOT NULL PRIMARY KEY, 
     companyID INT NOT NULL, 
     externalID INT NOT NULL, 
     UNIQIE KEY (companyID, externalID), 
     FOREIGN KEY (companyID) REFERENCES company (uid) 
     ); 

CREATE TABLE employee (
     uid INT NOT NULL PRIMARY KEY, 
     companyID INT NOT NULL, 
     officeID INT NOT NULL, 
     externalID INT NOT NULL, 
     UNIQIE KEY (companyID, externalID), 
     FOREIGN KEY (companyID) REFERENCES company(uid) 
     FOREIGN KEY (companyID, officeID) REFERENCES office (companyID, externalID) 
     ); 

+0

感謝您的回覆 - 所以選項一在旅途中。 – 2010-02-18 22:24:38