2010-09-21 115 views
3

形勢
說我有以下幾點:MySQL數據庫的設計問題

  • items
  • lists到這些項目可以鏈接
  • users

條件:列表可以屬於全部一個具體用戶

我想要做的是創建「全局」列表,永遠用戶存在。但應該有一種可能性,即用特定用戶「覆蓋」這個全局列表。例如,對於一個隨機的用戶:

  • 全局列表稱爲
  • 用戶特定列表CDS

現在檢索列出了該用戶時,我應該得到雙方的全球書籍列表和用戶特定的CD列表。但是,如果這個用戶有特定的書目列表呢?

  • 一個名爲
  • 用戶特定列表
  • 用戶特定列表CDS

所以現在全局列表,應該檢索用戶特定列表調用書籍,而不是全球列表,當然還有用戶特定的CD列表。

可能的解決方案
最簡單的事情將是這樣的:

table: lists 
- id 
- name 
- userId

如果用戶id IS NULL那就意味着它是一個全球性的列表,但是當它的NOT NULL它屬於一個特定的用戶。因此,第一個例子是對用戶id = 1:

id name userId 
1 books NULL 
2 cds  1

要檢索列出了該用戶:

SELECT * FROM lists WHERE userId = 1 OR userId IS NULL

但後來我被堵在接下來的部分:

id name userId 
1 books NULL 
2 cds  1 
3 books 1

這裏的第一個「書籍」列表是全球性的,但這個用戶也有一個用戶特定的列表「書籍」。在這種情況下,可以忽略全局列表,只返回用戶特定的列表?

另一種可能性是創建一個lists_users表,將所有用戶鏈接到所有全局列表,並且每當使用與這些全局列表相同的名稱創建用戶特定列表時,刪除此鏈接。雖然這看起來效率不高,並且在添加新用戶時需要進行更多的工作。

問題
什麼是數據庫中設置此最好和最有效的方式,讓我可以輕鬆地獲取正確的列出了一個特定的用戶?

回答

0

對於當前的設計,您可以通過以下方式獲得用戶的列表:

SELECT * FROM lists 
WHERE userId = 1 
UNION ALL 
Select * from lists g 
Where userId IS NULL 
AND NOT EXISTS (SELECT 1 from lists l where g.name = l.name and userid = 1) 

即選擇特定於用戶的名單和全球用戶不能重新定義

0

如果你是不是篩選項目列表?

Select distinct -- items from user-specific lists 
     ItemName 
    , ItemType 
from User  as u 
join UserList as x on x.UserId = u.UserId 
join List  as t on t.ListId = x.ListId 
join ListItem as y on y.ListId = t.ListId 
join Item  as m on m.ItemId = t.ItemId 
where ListType = 'custom' 
and u.UserId = some_user_id 
UNION 
Select distinct 
     ItemName -- items from global lists 
    , ItemType 
from List  as t on t.ListId = x.ListId 
join ListItem as y on y.ListId = t.ListId 
join Item  as m on m.ItemId = t.ItemId 
where ListType = 'global' 

order by ItemType, ItemName 
; 

alt text

0

我非常個人的看法,當你開始在DB與NULL值打解決觀念問題,那是因爲你需要改變你的表..

我提出這個(對不起,凌亂的UML圖)

List diagram

這背後的想法是,你可以使用「遺產」來分隔兩種類型的列表:UserDefinedList和DefaultLists。正如您所看到的,只有UserDefinedLists與用戶相關,並且DefaultList對於想要使用它們的任何用戶開放。當然,當有人想要創建一個列表你可以告訴用戶該列表已經創建,但實際上你不會在數據庫中插入任何東西。

如果要顯示用戶的列表,請顯示UserDefinedLists和所有DefaultLists。

這聽起來可能聽起來很混亂,但故事的寓意是,當你有不同類型的元素(如列表)時,數據庫中的遺產是有用的,每種類型與其他表格有不同的關係(即UserDefinedLists與用戶有關和DefaultLists不是,但他們都是列表的類型)

希望這可以幫助