我在这个问题上与同事有点意见不一致。首先,环境(保证,不会改变):
现在,情景:我正在开发一个应用程序,它将使用户能够收集用户的输入并将其存储起来用于以后的报告目的。收集输入的方法有各种类型的控件,可以放在页面上。收集数据不是问题;存储它是。
数据库中的数据库
我遵循这样的概念:它应该存储为键值对的集合(在本例中,名为ResponseItems
的表):
+----------+----------+----+-----+
|ResponseId|FormItemId|Name|Value|
+----------+----------+----+-----+
ResponseId
和FormItemId
构成主键的位置,与ResponseId
表相关的Response
,如下:
+----------+------+------+-------------+
|ResponseId|FormId|UserId|SubmittedDate|
+----------+------+------+-------------+
与FormItemId
表相关的FormItem
:
+----------+------+----+-----------------+
|FormItemId|FormId|Type|InstantiationData|
+----------+------+----+-----------------+
其中FormId
与FormId
表中的Response
相同,引用Form
表格,这一点并不重要。
XML序列化
我回过头来回应一下,将表单组件和响应序列化为XML更有意义,这样它在表中需要更少的批量,只留下一个Form表:
+------+--------+
|FormId|Elements|
+------+--------+
并且所有实例化数据都存储在Elements
中每个表单元素的XML数据中。然后类似地记录响应:
+----------+------+-------------+----------------+
|ResponseId|UserId|SubmittedDate|ResponseElements|
+----------+------+-------------+----------------+
长篇序后的简短问题
我认为第一个想法更清晰,更容易报道。你觉得怎么样?
作为最后一点,双方都有更多的表格,因为每次用户编辑表单时都要对表单进行版本控制。
答案 0 :(得分:3)
第一种方法称为实体 - 属性 - 值(EAV)。在我看来,永远不会存储关系数据的好方法。在采用该设计之前,您应该阅读一篇名为Bad CaRMa的文章。
我还在演示文稿Practical Object-Oriented Models in SQL和我的书SQL Antipatterns: Avoiding the Pitfalls of Database Programming中讨论了EAV的缺点。
在这两个设计中,我更喜欢XML方法。这基本上是Martin Fowler的Serialized LOB模式。
您可能还想阅读How FriendFeed Uses MySQL to Store Schema-less Data。他们的方法并不特定于MySQL;它可以在SQL Server或任何其他RDBMS中使用。