【问题标题】:Design SQL Server database correctly正确设计 SQL Server 数据库
【发布时间】:2017-04-27 22:52:58
【问题描述】:

我有简单的注册表单,但有 3 个复选框,例如:

Name:   [        ]
Email:  [        ]
Pass:   [        ]
What do you like at free time?  
  Reading:    [ ]
  Travelling: [ ]
  Sport:      [ ]

如上例所示,您会看到“您在空闲时间喜欢什么?”有 3 个复选框。有多个选项,人们可以只选中阅读复选框或阅读和旅行或所有复选框等。

如何在数据库中正确存储?

例如,如果我将在下面创建Users 表:

CREATE TABLE #User
(
    Id INT IDENTITY,
    Name NVARCHAR(60),
    Email NVARCHAR(60),
    Password NVARCHAR(60),
    FreeTime INT
)

我只能从复选框中插入 1 个选项。逗号分隔的解决方案是不好的做法。

我不知道在用户表中插入多个具有相同UserId 的记录以将所有复选框值作为单独的行插入是否是一种好习惯?

或者创建新表FreeTime 之类的更好方法?

CREATE TABLE #FreeTime
(
    Id INT IDENTITY,
    UserId INT,
    Description NVARCHAR(60)
)

【问题讨论】:

  • 创建一个单独的表和链接表,这样你就可以简单地在 FreeTime 表中插入新行,你可以在不改变架构的情况下链接东西
  • 逗号分隔值不好的做法。更好的方法是,就像您已经说过的那样,创建另一个表空闲时间来存储每个用户分隔的每个值。

标签: sql sql-server database tsql checkbox


【解决方案1】:

你快到了!如果您希望数据标准化,则需要 3 个表。

CREATE TABLE #User
(
    Id INT IDENTITY,
    Name NVARCHAR(60),
    Email NVARCHAR(60),
    Password NVARCHAR(60)
)

CREATE TABLE #FreeTime
(
    Id INT IDENTITY,
    Description NVARCHAR(60)
)

CREATE TABLE #UserFreeTime
(
    UserId INT,
    FreeTimeId INT
)

复选框中的数据存储在#UserFreeTime 表中。

【讨论】:

  • 如果有多个问题,再增加一层(2 个表格)
  • 是的。这就是我要做的。将删除我的答案。
  • 谢谢,这正是我要找的。​​span>
【解决方案2】:

我会推荐一个简单的用户表:

CREATE TABLE #User
(
    UserId INT IDENTITY,
    Name NVARCHAR(255),
    Email NVARCHAR(255),
    Password varbinary(128)
)

然后是一个复合键表:

CREATE TABLE #UserFreeTime
(
    UserID INT NOT NULL,
    FreeTimeID INT NOT NULL
)

还有一个单独的表格中的空闲时间活动列表:

CREATE TABLE #FreeTime
(
    FreeTimeID INT IDENTITY(1,1),
    Description NVARCHAR(50)
)

【讨论】:

    【解决方案3】:

    您可以使用两种方法来实现这一点:

    1. 创建第二个表UserFreeTime,如下所示:

      CREATE TABLE UserFreeTime
      (
        Id INT IDENTITY,
        UserId INT,
        FreeTimeId, 
      )
      

      然后在代码中针对每个选项定义枚举,就像使用 C# 一样:

      public enum {
         Reading,
         Traveling,
         Sport
      }
      

      上面的枚举是你的FreeTimeId

    2. 在第二种方法中,您可以定义第三个表,包括方法一中提到的上述两个。

      此表将具有以下结构:

      CREATE TABLE FreeTime
      (
         Id INT IDENTITY,
         FreeTimeDescription varchar(100),
         IsActive bit, 
      )
      

      您可以不使用枚举,而是将您的空闲时间偏好存储在上表中,并可以在UserFreeTime 表中引用其 ID。希望对你有帮助

    【讨论】:

      【解决方案4】:

      只是给你一个选择,如果你的表格永远不会改变,那么添加额外的表格实际上只是试图设计一些你并不真正需要的具有灵活性的东西,或者试图满足“好的设计”原则没有真正的好处。

      这是最简单的解决方案:

      CREATE TABLE #User
      (
          Id INT IDENTITY,
          Name NVARCHAR(60),
          Email NVARCHAR(60),
          Password NVARCHAR(60),
          FreeTime_Reading BIT,
          FreeTime_Travelling BIT,
          FreeTime_Sport BIT
      )
      

      我想很多人不会喜欢这个解决方案,但它对于开发来说是最简单的,对于任何报告也是如此,并且由于它只使用一个表而具有最佳性能。

      【讨论】:

        【解决方案5】:

        干净的模型是 TrustNo_1 的提议,有 3 个表(在其他表之间的关系表上)。

        Richard Hansell 和 Muhammad Qasim 提供了一种快速而肮脏的方法。

        硬编码的列很难更改,但它们可以完成这项工作。

        您还应该考虑添加检查约束或触发器以防止错误数据(如果有)。

        例如,如果 Sport 和 read 不能一起检查:

        CREATE TABLE #User
        (
            Id INT IDENTITY,
            Name NVARCHAR(60),
            Email NVARCHAR(60),
            Password NVARCHAR(60),
            FreeTime_Reading BIT CHECK (FreeTime_Reading + FreeTime_Sport <> 2),
            FreeTime_Travelling BIT,
            FreeTime_Sport BIT
        )
        

        您不能将 CHECK 约束与 3 个表模型一起使用,您将需要一个触发器来检查是否存在用于 Sport 的记录以及在更新和创建时读取的记录...

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-21
          • 1970-01-01
          • 2010-12-01
          • 2011-05-09
          • 2010-12-12
          • 1970-01-01
          • 2011-01-06
          • 1970-01-01
          相关资源
          最近更新 更多