2014-02-21 77 views
1

給出,其中有可能人和Item.Label需要幾個不同的值,它可能是有意義採用等效模式PersonItem集團非標量值

Person   Item 
-------   ------ 
Id <-----.  Id 
Name  `---- PersonId 
        Label 

間的一種一對多的關係:

Person  List  Item 
--------  ------ ------ 
Id  .--> Id <--. Id 
ListId --`   `-- ListId 
Name     Label 

這樣很多人可以共享相同的列表。

從第二模式到第一模式的遷移是微不足道的。我的問題是,如何從第一個模式遷移到第二個

的挑戰是選擇只有一個代表Person

SELECT Label FROM Item WHERE PersonId = ? 

每一個可能的結果,我能夠通過使用FOR XML目前在MS SQL服務器來解決這個問題。也就是,

SELECT P.Id, (SELECT Label FROM Item WHERE PersonId = P.Id FOR XML) list 
FROM Person P 

然後簡單地SELECT MIN(P.Id) FROM ... GROUP BY list收集代表。雖然我不滿意這個解決方法,但希望找到更純粹的解決方案。

編輯:

SELECT p.Id, q.Id FROM Person p, Person q 
WHERE NOT EXISTS (--symmetric difference between 
    (SELECT Label FROM Item WHERE PersonId = p.Id) --and 
    (SELECT Label FROM Item WHERE PersonId = q.id)) 

應該是人,爲此,代表需要被發現的等價關係。我仍然不知道如何完成,而且這看起來效率很低。

+0

從這個樣子看,一個物品只能在一個列表中? List可能更有意義,包含一個PersonID和一個ItemID。然後,您可以查詢List表中特定人員可能擁有的所有物品,或具有特定物品的所有人員。 – aglassman

+0

@aglassman,在不同的列表中可能有多個具有相同標籤的項目,但是沒有兩個列表可以具有完全相同的項目集合。 –

+0

請指明您的DBMS(SQL Server,MySQL,Oracle等) – ErikE

回答

0

這要看!我建議你堅持你的模型到你的商業邏輯。 如果人們擁有預先製作的物品組,它會使感官創建一張表來保存該邏輯。

考慮到人們可以擁有「家庭版」,「專業版」或「標準版」。 在Edition_Items之間創建一個關係表,這種版本可以包含項目(A,B),(A,B,C,D)和(A,C),例如。

而且你可以在它擁有的People和Edition之間創建一個關係表。在你的情況下,如果該版本是「定製」版本,即使你有兩個包含相同的項目集,你可以認爲它們是不同的集合(僅僅因爲它們是由不同的人擁有)。

因此,「組合集」表可以用作人與物品之間的關係表。

編輯:

OP評論強制我的最後陳述。 因此,您的「列表」表可以是人員和項目之間的關係表。

|People | |List| |List_Item| |Item| 
|-------| |----| |---------| |----| 
|P1, L1 | | L1 | | L1, I1 | |I1 | 
|P2, L2 | | L2 | | L1, I2 | |I2 | 
      | L3 | | L2, I1 | |I3 | 
      | L4 | | L2, I1 | 

看着它你可以問,爲什麼要保留一個List表?這是使用完整的,如果該名單有一些屬性,如:isDeleted,Description,CreateTime等

最後的問題是?我們把一個列表引用到列表中的人員或引用人員列表(或創建另一個關係表格?)

它取決於: 1)人員列表是一個1-1關係? 2)誰來了? (雞蛋和雞肉的問題?) 這通常是更好的質疑:誰可以存在沒有其他。

+0

隨意假定我需要收集所有不同的列表,因爲我的需求發生了變化,List需要成爲業務對象。 –

+0

無論List-Item是一對多還是多對多,問題依然存在。如何從兩個原始表中遷移以保持所有關係並最小化列表數量? –

+0

爲簡單起見,假設每個人都贏得了一份清單1 <->。如果需要,使用select from insert創建列表表格。現在使用加入People,Item,List來填充List_Item。從我選擇的另一個插入我想。最後嘗試查找重複列表。 – jean