更好的关系数据库架构的建议 [重复]

Posted

技术标签:

【中文标题】更好的关系数据库架构的建议 [重复]【英文标题】:Suggestion for better relational DB Schema [duplicate] 【发布时间】:2010-08-02 05:46:02 【问题描述】:

我来这里是为了设计一个对轮询和用户建模的关系数据库模式。每个 类别可以有一个或多个问题。每个用户都可以参与 每个类别只能轮询一次,并且可以轮询(或不轮询)一次 每个问题。每个投票都是赞成、反对或弃权(不投票)。

我用四个表设计了我的架构:

 users, [userId, IP]
 category, [catId, catTitle]
 question, [queId, queTitle]
 polls [pollId, queId, userId, answer]

更好还是

 users, [userId, IP]
 category, [catId, catTitle]
 question, [queId, queTitle]
 polls [pollId, catId, userId]
 pollAnswers [pollAndId, queId, pollId, answer]

我想知道哪个更好,为什么?

就我而言,因为我没有任何关于民意调查的额外信息,所以我直接交叉加入用户和带有答案的问题。

我还需要找出有多少用户对 a.) 所有类别问题 b.) 特定类别 c.) 特定问题弃权

我对选择一种模式有自己的看法:

select U1.*, Q1.*, P2.*, C1.*
from 
    ( users U1, 
    questions Q1 )
    Left outer Join polls P2 on 
        Q1.queId = P2.queId AND U1.userId = P2.userId
    Left Outer Join category C1 on
        Q1.catId = C1.catId

我试图担心使用上述查询与用户之间的交叉连接和问题会降低我的性能吗?

如果第二个模式更好,你可以为我的结果推荐选项吗?

【问题讨论】:

这并不能真正帮助您的架构,但我认为缩写的字段名称是可怕的。另外,为什么要在每个字段名前加上表名?为什么不用 users(id, ip), questions(id, body), polls(id, question_id, user_id, answer)? thxn 建议删除缩写的字段名称。接下来我不让你说“这对你的架构没有帮助”这是什么意思 他们的意思是删除前缀对你的架构没有帮助,但它确实使它更具可读性。你应该使用“don't”而不是“dun”。 谢谢...我会记住的 只是另一个快速评论,您缺少问题和类别之间的任何关系。所以你需要在question 表中添加:catId。稍后我将对您的选择查询进行破解。 :D 【参考方案1】:

users:重命名为 user,以便所有实体都是单数(或将单数重命名为复数)

分类:好的

问题:您需要一个从问题到类别的外键

pollAnswers:重命名为pollAnswer,并使其成为一个包含三行的参考表:Yes、No、Abstain

polls:重命名为 poll,并使其成为用户轮询问题的事务,外键为 user、question 和 pollAnswer。

(选项:要么在插入时验证用户对该类别中的问题没有现有民意调查,要么使用问题的外键对 PollAnswers 进行非规范化,并对用户/问题施加唯一约束。我个人不喜欢这样选项,因为如果您更改问题的类别,它会出现问题。)

然后对特定类别的查询可能如下所示:

select *
from category c
LEFT OUTER JOIN question q ON q.catID = c.catID
LEFT OUTER JOIN poll p ON p.queId = q.queId
LEFT OUTER JOIN user u ON u.userId = p.UserID
WHERE c.catID = 'blah blah'

【讨论】:

以上是关于更好的关系数据库架构的建议 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

MYSQL一对一关系连接比个人更好[重复]

第0天SQL快速入门-了解MYSQL前世今生,为了更好探索未来(SQL 小虚竹)

第0天SQL快速入门-了解MYSQL前世今生,为了更好探索未来(SQL 小虚竹)

数据库问题与默认的一对多关系

C# nhibernate 多层架构

没有关系数据库的 ACID 属性如何帮助非关系数据库更好地执行?