选择哪种数据库结构?

时间:2013-02-05 02:03:14

标签: sql database-design relational-database

我想实现一个通知系统。我有用户,每个用户都有通知设置

结构1:

 Users                Notification_settings                Notifications
 -id (pk)             -id                                   -id (pk)
 -username            -user_id (fk) references Users        -user_id (fk)
 -password            -receive_email (boolean)              -message
                                                            -is_read

结构2:

 Users                                               Notifications_settings
 -id (pk)                                             -id (pk) 
 -setting_id (fk) references Notifications_settings   -receive_email
 -username                                            
 -password            

 Notifications
 -id (pk)
 -user_id (fk)
 -message
 -is_read

要为通知系统选择哪种数据库结构或任何其他数据库结构?

3 个答案:

答案 0 :(得分:2)

好像应该是用户<通知(一对多),但也许你有一个特定的原因,它应该是1-1。在这种情况下,我会使父表(没有FK列的那个)表与更多的一对多关系。因此,自然地,在通知表中使用存储用户ID是有意义的。

似乎通知总是有用户,但反之亦然。因此,您应该将外键存储在通知表中的UserID中 - 而不是相反。

编辑 - 正如其他人所建议的那样,如果你真的想要一个1-1关系,你可以只在User表中添加通知字段。这些似乎一目了然地违反了规范化规则,但如果它真的是一种1-1的关系,那么无论如何都要有它

编辑2-由于您明确声明没有用户时通知不存在,我明确表示您应该在通知表中将外键存储到用户,没有例外(除非您想要在用户表中存储通知信息:)

编辑#2937:

您应该将用户的通知偏好存储在用户表中 - 除非您有一些模糊的设计并且有256列,否则无需将其拆分为不同的表您的用户已经是限制。

您应该将通知存储在单独的表中,其中包含从用户到通知的一对多关系。那是我最后的回答,瑞吉斯:)

答案 1 :(得分:2)

现在是Joe Celko quote

  

一个强大的实体是一个以其自身的优点存在的实体。弱实体是由于强大的实体而存在的实体。典型的例子是销售订单;订单标题很强,订单详细信息很弱。如果订单被删除,那么所有订单详细信息都应该消失。

那么,用户是否可以在没有通知的情况下存在?然后通知表应具有用户的外键。相反的是真的吗?然后换另一种方式。这些都不是真的吗?那么也许你的模型是不正确的,它们之间应该有junction table(即使它有唯一的约束),或者它们真的属于同一个表。我并不特别喜欢将它们放在同一个表中的最后一个选项,因为你已经自然地想出了两个名词来描述不同的实体。

除用户以外的其他实体“是否有”通知?也许这种想法可以帮助你模拟这个领域。

更新 - 其他一些想法:

如果您要将所有这些列放入一个表中,那么它们中的哪一个(如果有的话)现在看起来会包含冗余数据?我们假设现在只有几条不同的消息。也许你不需要Notifications表,而是一个Messages表,以及它和Users之间的联结表,它可以存储随时间发送给用户的消息,包括它们是否被读过。此时,receive_email可能是用户的更好属性,但可能只是将消息映射到用户就足以说明此用户应该接收电子邮件。这些只是我可能想到的一些事情,希望能够更好地理解应用程序。

另外,请注意bit / boolean数据类型不是ANSI SQL,通常可以从其他数据派生,或者甚至可以转化为映射到多个状态的int。

答案 2 :(得分:0)

如果您的网站流量不大,请将其全部放在同一个表格中(用户和设置)。这是OP的相关答案。
通常,当几个条件发生时(一起),你将1:1分成不同的表:

  1. 每组字段与您应用中的其他模块相关
  2. 每组字段都以不同的费率访问(每次登录的用户名/密码,一周一次/两次结算设置,例如)
  3. 您的网站有大量流量,您需要从系统中提取任何性能
  4. 正如你从上面可以看到的,大多数人不需要将它分开。