【问题标题】:Sql design question - many tables or not?Sql 设计问题 - 是否有很多表?
【发布时间】:2011-03-18 17:13:43
【问题描述】:

15 ECTS 学分的数据库设计值得一试。我真的无法为我的问题想出最好的设计解决方案。

这是什么:基本上我正在制作一个收集大量有关用户信息的工具。用户最多可以填写 50 个数据字段,范围从简单的复选框到文本输入。我现在正在设计数据库(使用 mySql),无法决定是否使用包含所有这些字段的单个用户表,或者为每个输入类别设置一个表。

一个例子是“支付类型”。这个有三个选项,如果我采用“表格”方式,我会添加一个表格 paymentType 并为每种支付类型提供二进制字段。然后我需要和 id 表来识别用户选择了哪种支付类型,而如果我使用单个用户表,数据就已经存在了。

该网站可能会看到很多用户(电视、互联网和广播营销),所以我担心哪个替代方案是最好的。

如果您需要更多信息来做出决定,我很乐意提供更多详细信息。

感谢阅读。

【问题讨论】:

  • 为了结构完整性,规范化。如果您发现 SELECT 查询的性能存在问题,请回来,我们将了解非规范化。

标签: sql mysql database-design


【解决方案1】:

阅读这篇文章“Database Normalization Basics”,如果您还有问题,请回到这里。应该会有很大帮助。

正如您将在本文中看到的那样,这些决定背后的最基本理念是每个表应该代表一个且仅代表一个“事物”,并且每个字段应该直接且仅与该事物相关。

在您的付款类型示例中,如果您预计需要存储有关每种付款类型的其他信息,则将其拆分为一个单独的表可能是有意义的。

【讨论】:

  • 谢谢,我已经通读了一遍,可能会尽我所能将其标准化为 3NF。
【解决方案2】:

创建您的“付款类型”表;那里没有真正的问题。这是正确的规范化和使用关系数据库背后的力量。这样做的众多原因之一是能够更新付款类型记录,而不必触及用户表中的相关数据。您在这两个表之间的连接将允许您的应用通过仅在 1 个位置更改付款信息来查看更新的付款信息类型。

关于您的其他领域,它们可能没有那么明确。关于每个字段要问自己的问题是“这个字段是否仅与用户相关,或者它本身是否具有意义和可能的用途?”。如果您永远无法想象一个字段在用户上下文之外具有意义,您可以安全地将其作为字段留在用户表中,否则执行主键-外键关系并将信息放在自己的表中。

【讨论】:

  • 感谢您的意见。现在很难看到这些字段的含义,因此我认为更安全的方法是在我有疑问的地方创建表格。
【解决方案3】:

如果您要构建具有可变输入的表单,我不建议将其构建为一个表格。这是不灵活和肮脏的。

规范化是关键,但如果您最终使用键/值设置,或者实际上是跨多个表的标量类型实现并且无法缓存:

a) 来自表格数据的表单定义和
b) 存储的合并结果(缓存视图或其他)
c) 或者不建立适当的分片

那么您可能会遇到性能边界。

在此 KVP 设置中,您可能希望查看 CouchDB 之类的内容或较少表驱动的存储格式。

如果您的内部数据与数据库中已有的其他数据高度相关,您可能还需要查看更复杂的设置,例如序列化对象存储和缓存表

【讨论】:

    【解决方案4】:

    50 列是很多。您是否考虑过像属性表一样存储值的表?这仅在您不需要定期查询它包含的值时才有用。

    INSERT INTO UserProperty(UserID, Name, Value)
         VALUES(1, 'PaymentType', 'Visa')
    
    INSERT INTO UserProperty(UserID, Name, Value)
         VALUES(1, 'TrafficSource', 'TV')
    

    【讨论】:

    • Value 是什么类型?变量()?斑点? ... 除非小心处理,否则当大量数据被放入时,这会很快变得严峻。
    • 不管类型是什么,但字符串似乎是一个不错的选择。像这样的实现必须对表包含的内容具有容错性。但是有 50 个字段,我想并非所有这些数据都需要以表格形式提供。
    • 好主意.. 虽然如果我想确保 Value 可以是 2 和 255 个字符,这不会分配大量空间吗?
    • 不,一个 varchar 字段只有它需要的大小,直到最大值。
    • varchars 不灵活,不能替代多数据存储,也不应被视为标量;这否定了 SQL 原生数据类型的好处,意味着您还可以使用 CouchDB 或持久对象存储之类的东西
    【解决方案5】:

    我想我找到了解决这个问题的好方法。感谢我的一位朋友提出这个建议!

    我有三个表,Field {IdField, FieldName, FieldType}, FieldInput {IdInput, IdField, IdUser} 和 User { IdUser, UserName...等}

    通过这种方式,可以很容易地查看用户的回答,该解决方案具有一定的可扩展性,并且提供了一个很好的概览。我将在离数据库更远的另一层中限制替代方案。我相信这是一个值得做的权衡。

    对此解决方案有何建议或批评?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多