2012-04-30 55 views
0

鑑於這些業務規則:執行的一致性:m關係

  • 用戶有0或多個賬戶,所有賬戶都與一個單個用戶相關聯
  • 用戶有0或更多的資產,所有資產與單個用戶關聯
  • 資產可能與單個帳戶相關聯。如果將其分配給任何帳戶,則該帳戶必須屬於與該資產相關聯的用戶。

假設以下建議方案:

User 
-id 

Account 
-id 
-user_id 

Asset 
-id 
-user_id 
-account_id (Nullable) 

這似乎在此架構中的一個弱點,因爲進行資產 分配到屬於不同的用戶比 資產帳戶。這是通過導致更好的模式的正常形式之一來解決的嗎?如果它沒有通過規範化覆蓋是最好的約束,然後在業務邏輯端?

+0

「所有帳戶都與單個用戶相關聯」 - 這是否意味着沒有兩個用戶可以擁有相同的帳戶ID號? (對於資產也是同樣的問題。) –

回答

1

本(下同)實現關係正常化可能處理的是空列的唯一部分。在Chris Date的理解中,如果列允許NULL,那麼關係不在1NF中。

如果您試圖嚴格遵循關係模型,我認爲您可以使用斷言來處理此問題。但是大多數SQL平臺不支持斷言。在SQL中,我相信你正在尋找這方面的東西。我在PostgreSQL中測試了這個。

create table users (
    user_id integer primary key 
); 

create table accounts (
    user_id integer not null references users (user_id), 
    account_id integer not null unique, 
    primary key (user_id, account_id) 
); 

create table assets (
    user_id integer not null references users (user_id), 
    asset_id integer not null unique, 
    account_id integer null, 
    primary key (user_id, asset_id), 
    foreign key (user_id, account_id) references accounts (user_id, account_id) 
); 

-- Insert 3 users. 
insert into users values (1), (2), (3); 

-- User 1 has two accounts, user 2 has 3 accounts, user 3 has none. 
insert into accounts values 
(1, 100), 
(1, 101), 
(2, 102), 
(2, 103), 
(2, 104); 

-- User 1 has 1 asset not assocated with an account. 
insert into assets values (1, 200, null); 

-- User 1 has 1 asset associated with account 101 
insert into assets values (1, 201, 101); 

-- User 1 tries to associate an asset with account 102, which doesn't belong to user 1. 
insert into assets values (1, 202, 102); 
[Fails with foreign key violation] 

-- User 2 has two assets not associated with an account. 
insert into assets values 
(2, 500, null), 
(2, 501, null); 
-1

我會建議從表資產中完全刪除account_id外鍵。由於account_id與您的用戶表相關,因此您可以加入資產和用戶,然後執行從用戶到帳戶的左連接(如果這是其中account_id是主鍵的表)。如果您從左連接中獲得結果,則資產鏈接到一個帳戶,並且用戶是相同的。這樣你強制這個約束。

希望這有助於 問候

埃爾切

+0

我不確定它是否仍然滿足第三個業務要求 - 資產被分配到一個帳戶或沒有帳戶。如果我從資產中刪除account_id,那麼沒有明確的資產分配到賬戶。資產和用戶的加入會生成所有資產及其相應用戶的集合。我認爲進一步加入帳戶(通過user_id)不會將一個資產捕獲到一個或沒有帳戶,而只是一個交叉產品(例如,特定用戶的每個資產都屬於該用戶的每個帳戶)。 – user1338952

+0

你當然是對的,我忘記了。如何讓一個表將用戶鏈接到帳戶和資產。 account_asset accountid assetid 如果這是不可能的,你必須強制與businesslogic這種關係我猜 –