MySQL数据库设计问题

时间:2010-09-21 11:35:39

标签: mysql database-design

场合
说我有以下内容:

  • items
  • 可以链接这些项目的表格lists
  • users

条件:列表可以属于所有一个特定的用户

我想做的是创建为所有用户而存在的“全局”列表。但应该有可能用一个特定于用户的列表“覆盖”这个全局列表。随机用户的示例:

  • 一个名为 books
  • 的全球列表
  • 用户特定列表 cds

现在,当检索此用户的列表时,我应该获得全局书籍列表和用户特定的cds列表。但是如果这个用户有一个特定的书籍列表呢?

  • 一个名为 books
  • 的全球列表
  • 用户特定列表图书
  • 用户特定列表 cds

所以现在它应该检索名为books的用户特定的列表而不是全局列表,当然还有用户特定的cds列表。

可能的解决方案
最简单的事情就是这样:

table: lists
- id
- name
- userId

如果userId IS NULL它意味着它是一个全局列表,但是当它是NOT NULL时它属于特定用户。所以第一个例子是userId = 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

这里第一个列表“books”是全局的,但是这个用户还有一个用户特定的列表“books”。在这种情况下可以忽略全局列表,只返回用户特定的列表吗?

另一种可能性是创建一个lists_users表,将所有用户链接到所有全局列表,并在创建与这些全局列表之一具有相同名称的用户特定列表时删除此链接。这似乎并不是非常有效,并且在添加新用户时需要做更多的工作。

问题
在数据库中设置它的最佳和最有效的方法是什么,以便我可以轻松地为特定用户检索正确的列表?

3 个答案:

答案 0 :(得分: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)

即。选择用户特定的列表和用户未重新定义的全局

答案 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

答案 2 :(得分:0)

在我个人看来,当你开始在数据库中使用NULL值来解决一个概念问题时,这是因为你需要改变你的表..

我建议:(抱歉凌乱的UML图表)

List diagram

这背后的想法是你可以使用“遗产”来分离两种类型的列表:UserDefinedList和DefaultLists。如您所见,只有UserDefinedLists与Users相关,DefaultLists对任何想要使用它们的用户开放。当然,当有人想要创建列表书籍时,您可以告诉用户该列表已经创建,但实际上您没有在数据库中插入任何内容。

如果要显示用户列表,请显示UserDefinedLists和所有DefaultLists。

这可能听起来令人困惑,但故事的寓意是,当你有不同类型的元素(如列表)时,遗产在数据库中很有用,并且每种类型与其他表有不同的关系(即UserDefinedLists与用户和DefaultLists不是,但它们都是List的类型

希望这有帮助