【问题标题】:SQL Database Column with Variant Data Type具有 Variant 数据类型的 SQL 数据库列
【发布时间】:2014-12-23 03:09:02
【问题描述】:

我正在编写一个应用程序,用户可以在其中向表单添加“输入”。这些输入可以是多种不同的类型,包括文本框或复选框。

在文本框与复选框的情况下,数据类型是字符串与布尔值。

关于我的申请的更多信息

1) 用户能够创建一个“表单”,其中可能包含多种不同类型的输入供客户填写。这里有些例子。这些输入可以是动态的,由用户创建。

  • 可能要求输入用户名的输入。
  • 由一个复选框组成的输入,询问用户是否希望注册新闻通讯。

2) 用户保存表单,并在数据库中根据类型保存新创建的输入。

3) 新用户进入应用程序并填写刚刚创建的新表单。他们填写原始管理员创建的输入,例如他们的姓名,然后他们回答“是”以注册时事通讯。然后他们点击提交。

4) 数据库然后保存输入的答案。这就是我的问题所在。

我的问题是如何在 SQL 中将输入值存储在一行中。我将提供几个解决方案,但我希望就在这种情况下通常采取的措施达成共识。

  1. 解决方案 #1

输入名称

输入布尔值 -(如果不是布尔类型的输入,则为 NULL)

输入字符串值 -(如果不是字符串类型的输入,则为 NULL)

  1. 解决方案 #2

输入名称

输入类型

输入值(字符串类型,我会根据类型进行转换)

  1. 解决方案 #3

输入名称

输入类型

输入值键 - (表的弱外键取决于输入类型。这不是真正的外键,因为它可能指向多个不同的表)

【问题讨论】:

  • 我不建议根据您的前端做出数据库设计决策。它们应该由它们所代表的数据的现实驱动。
  • 我同意你的看法。但在这种情况下,输入表示输入名称和该输入的值。该值可以是多种不同的类型,一个布尔值还是一个字符串,无论哪个 UI 使用数据。您是否建议将所有值作为字符串处理并根据输入类型将它们转换为各自的类型?
  • 我想我需要更好地了解您的应用程序才能提出任何建议。听起来您正在尝试以与上下文无关的方式执行此操作,而对我来说,在设计数据库时,上下文就是一切。关于“Input1”的数据有什么用?如果开发者对前端的输入进行重新排序/重命名,数据库与前端的关系就会丢失。
  • 我在帖子中添加了更多信息。请参阅“有关我的应用程序的更多信息”

标签: sql sql-server


【解决方案1】:

对于每种数据类型的表,其中每一行都指向包含表单,该怎么办?例如:

FormTable
FormId      SomeOtherFields
1           Blah
2           Bleh

BooleanFieldsTable
BooleanFieldId     FormId     DisplayName     Value
1                  1          Married         True
2                  2          Finished        False

IntFieldsTable
IntFieldId         FormId     DisplayName     Value
1                  1          Age             35
2                  1          Amount          4

DateTimeFieldsTable
DateTimeFieldId    FormId     DisplayName     Value
1                  2          Purchase Date   2014-12-15 16:25:56.187

VarcharFieldsTable
VarcharFieldId     FormId     DisplayName     Value
1                  1          Name            John

【讨论】:

  • 这不是一个坏主意。我唯一不喜欢的是我目前遇到的同样的问题。对于 FormId 1,我怎么知道我应该在 BooleanFieldsTable 而不是 IntFieldsTable 中查找值。我想我可以说,是 InputType == "Boolean",去 BooleanFieldsTable
  • 当然,您应该LEFT JOIN 所有表格。我不认为这应该是一个问题。无需在任何地方存储任何“InputType”,您在关系本身中就有该信息。
【解决方案2】:

当我几年前实施这样的系统时,我选择了选项 2。我经常后悔并希望我完成了选项 3。我希望如果我选择了选项 3,我可能也会后悔。

选项 2 使一些事情变得更容易......链接中的链接和逻辑更少,但转换中的逻辑更多。

选项 3 使一些事情变得更容易...避免强制转换和强制转换中的逻辑更少,但链接中的逻辑更多。

当时 SQL Server 存在一个错误,导致选项 2 在许多情况下难以实施。我不知道他们是否修复了这个错误。

这是一个错误示例(请注意,它并不总是会出现,取决于表格大小和许多其他因素):

  SELECT CAST(field as int) 
  FROM table1 
  WHERE selectorField = 5

在某些情况下,如果行(不是 selectorField = 5)无法转换为 int 类型,此查询将失败并出现非法转换错误。

如果此问题仍然存在,您希望使用选项 3。

【讨论】:

    猜你喜欢
    • 2020-03-29
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-14
    • 2018-02-17
    • 2012-04-17
    相关资源
    最近更新 更多