用于存储表单字段和字段值的数据库架构建议

时间:2011-11-18 18:53:28

标签: asp.net sql-server sql-server-2000 database-schema

我的任务是创建一个应用程序,允许用户将数据输入到将保存的Web表单中,然后最终用于填充pdf表单字段。

我在尝试考虑将字段值存储在数据库中的好方法时遇到了麻烦,因为表单将是动态的(基于pdf字段)。

在应用程序本身中,我将在哈希表(fieldname,fieldvalue)中传递数据,但我不知道将哈希值转换为db值的最佳方法。

我正在使用MS SQL server 2000和asp.net webforms。有没有人在做过类似的事情?

3 个答案:

答案 0 :(得分:4)

您是否考虑过在这里使用文档数据库?这只是他们解决的问题,比传统的RDBMS解决方案更好。就个人而言,我是RavenDb的忠实粉丝。另一个相当不错的选择是CouchDb。我会避免使用MongoDb,因为它在当前的实现中并不是一个安全的数据库。

即使你不能使用文档数据库,你也可以通过设置表来使SQL假装成一个,以便在传统列中包含一些元数据,其中有效负载字段是序列化的XML或json。这将让您在远离EAV-land时搜索元数据。 EAV-land是一个可怕的地方。

更新

我不确定是否存在好的指南,但这个概念非常简单。基本思想是将要查询的部分分解为表中的“普通”列 - 这使您可以按标准方式进行查询。当您找到所需的记录时,您可以抓取CLOB并根据需要反序列化它。在你的情况下,你会有一个看起来像这样的表:

SurveyAnswers
  Id INT IDENTITY
  FormId INT
  SubmittedBy VARCHAR(255)
  SubmittedAt DATETIME
  FormData TEXT

一些提示:
a)使用基于文本的序列化例程。为您提供解决数据错误的绝佳机会,真正有助于调试 b)对于SQL 2000,您可能需要考虑将CLOB(保存有效负载数据的TEXT字段)分解为单独的表。自从我使用SQL 2000以来已经很长时间了,但我的回忆是使用TEXT列对表格做了坏事。

答案 1 :(得分:2)

你所描述的解决方案被称为Entity Attribute Value(EAV),这个模型可能是一个很难处理的问题。所以你应该尽可能地限制你对此的使用。

例如,是否存在几乎总是在表单中的字段(名字,姓氏,电子邮件等),那么您应该将它们作为字段放在表格中。

这样做的原因是因为如果你迟早没有人意识到他们有这些名字和电子邮件并要求你建立这个查询

     SELECT 
        Fname.value fname,
        LName.Value lname,
        email.Value email,
        ....
     FROM  
         form f
         INNER JOIN formFields fname
         ON f.FormId = ff.FormID
            and AttributeName = 'fname'      
         INNER JOIN formFields lname
         ON f.FormId = ff.FormID
            and AttributeName = 'lname'
         INNER JOIN formFields email
         ON f.FormId = ff.FormID
            and AttributeName = 'email'
         ....

你可以写这个

    SELECT 
        common.fname,
        common.lname,
        common.email,
        ....
     FROM  
         form f
         INNER JOIN common c
         on f.FormId = c.FormId

尽快离开SQL 2000,因为你真的会错过UNPIVOT条款

查看之前的SO EAV questions以了解人们过去遇到的问题也可能不是一个坏主意

答案 2 :(得分:1)

我建议镜像相同的结构:

Form
-----
form_id
User
created

FormField
-------
formField_id
form_id
name
value