【问题标题】:Database design and large tables?数据库设计和大表?
【发布时间】:2012-03-29 09:34:05
【问题描述】:

包含大量列的表格是否表明设计不佳?例如,假设我有下表存储用户信息和用户设置:

 [Users table]
    userId
    name
    address
    somesetting1
    ...
    somesetting50

随着站点需要更多设置,表格会变得更大。在我看来,这个表是标准化的,所有的设置都依赖于 userId。

我对有很多列的表有一个想法,这对我来说似乎是错误的,但后来我记得你可以选择从表中返回哪些数据,所以如果表很大,我仍然可以将它分成几个不同的代码中的对象。例如

[User object]
[UserSetting object]

并仅返回填充这些对象的数据。

以上是常见的做法,还是他们的其他技术可以处理更适合使用的具有大量列的表?

【问题讨论】:

    标签: sql-server database-design normalization


    【解决方案1】:

    我认为你应该像这样使用多个表:

    [Users table]
       userId
       name
       address
    
    [Settings table]
       settingId
       userId
       settingKey
       settingValue
    

    这些表由 userId 列关联,您可以使用该列来检索您需要的用户的设置。

    【讨论】:

    • 我宁愿放弃settingId 列(大概是您的主键)并使用自然键(userId, settingKey)
    【解决方案2】:

    我会说这是糟糕的桌子设计。如果用户没有这 50 个设置中的 47 个条目,那么您将在表中拥有大量 NULL,这不是好的做法,也会降低性能(NULL 必须以特殊方式处理) .

    取而代之的是:

    用户表 ID, 名 姓 等等

    设置 ID, 设置名称

    用户设置 ID, 设置标识, 用户身份, 设置值

    然后你有一个多对多连接,并消除 NULL's

    【讨论】:

      【解决方案3】:

      首先,不要在表名中添加空格!所有的 [牙套] 将是一个真正的痛苦!

      如果您有 50 列,那么所有这些数据对每个用户的意义如何?会有很多空值吗?大多数数据甚至可能不适用于任何给定的用户。考虑 1 对 1 表,将“设置”分解为逻辑组:

      Users:              --main table where most values will be stored
          userId
          name
          address
          somesetting1    ---please note that I'm using "somesetting1", don't
          ...             --- name the columns like this, use meaningful names!!
          somesetting5
      
      UserWidgets         --all widget settings for the user
          userId
          somesetting6
          ....
          somesetting12
      
      UserAccounting      --all accounting settings for the user
          userId
          somesetting13
          ....
          somesetting23
      
      --etc..
      

      您只需要为每个用户设置一个Users 行,然后在每个表中将数据应用于给定用户的一行。如果用户没有任何小部件设置,则该用户没有行。您可以根据需要 LEFT 连接每个表,以根据需要获取所有设置。通常您只需要根据正在运行的应用程序的哪个部分来处理一组设置,这意味着您不需要加入所有表,只需加入您当时需要的一个或两个表。

      【讨论】:

      • 那么上面的表在数据库中会是一对一的关系吗?我正在考虑做类似的事情,但有一个大表(它们不会是任何空字段)并将其分解为不同的类,并且只查询填充类所需的数据。在这种情况下使用单独的表还是一个表会更好吗?
      【解决方案4】:

      你可以考虑一个属性表。只要你的索引是好的,那么你就不会有太多的性能问题:

      [AttributeDef]
         AttributeDefId int (primary key)
         GroupKey varchar(50)
         ItemKey varchar(50)
         ...
      
      [AttributeVal]
         AttributeValId int (primary key)
         AttributeDefId int (FK -> AttributeDef.AttributeDefId)
         UserId int (probably FK to users table?)
         Val varchar(255)
         ...
      

      基本上,您将包含许多列的表“转换”为 2 个列较少的表。您可以围绕此结构编写视图和表函数,为您提供一组相关项目或仅特定项目等的数据。您还可以在属性定义表中添加其他内容以指示所需的数据元素,对数据元素的限制等。

      您对这种类型的设计有何看法?

      【讨论】:

      • 也许我不是太了解它,但我对这种方法并不疯狂:(
      【解决方案5】:

      使用多个具有匹配索引的表以获得最佳的 SELECT 速度。使用索引作为一种通过 JOIN 关联表之间信息的方式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-17
        • 1970-01-01
        • 1970-01-01
        • 2012-02-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多