4

我需要在我的软件中允许通过 Web 界面创建用户设计的表单。即,他们创建一个问题、一个类型(文本、单选、复选框等)、选项(如果需要)(单选/检查),然后添加并继续此过程,直到他们在表单中创建了所有字段。

除了查看/填写/打印它们之外,不会对他们进行任何查询,即他们正在添加可以无限次填写的“问卷”(有些可能是 20 次,有些可能是数百万次)。

经过一些研究,似乎 EAV 类型的解决方案听起来不错,除了那里有很多负面看法。许多人建议在这种情况下使用 NoSQL 数据库,但我并没有真正看到它的优点——你仍然有一个包含许多字段的表单,然后是包含许多字段的结果。

某些字段(文本/文本区域/日期)将有一个可能的值,但许多字段也会有多个选项(单选按钮、选择下拉菜单、复选框)。

这是传统 SQL 中的示例设计:

形式:creator_id,名称

form_field: form_id, order, question, type (text, text_area, date, radio, select, check)

form_field_option:form_field_id、名称、值、顺序(用于单选/选择/检查)

form_result:form_id,application_id(不是我使用的名称,但所有结果都属于“应用程序”)

form_field_value:form_result_id、form_field_id、form_field_option_id、值(如果选项字段的值为空白,则文本字段 form_field_option_id 将为空白)

基于此构建表单并获得结果似乎相当容易。它可能会也可能不会完全有效,但是说典型的表格是 5-30 个问题,那会很糟糕吗?

将其放入 NoSQL 数据库(即 Mongo 或类似数据库)中是否有任何优势?如果是这样,你能给我具体的例子来说明它们是什么,并给我一个样本设计吗?我看过很多答案,比如“NoSQL 更适合这个”,但我在这方面没有经验,是因为更快地检索结果,还是什么?使用 NoSQL 会带来什么缺点?

谢谢

4

1 回答 1

9

MongoDB 可能比关系数据库更适合这个应用程序。您的基本实体,表单设计和表单结果,实际上是其内容本质上绑定在一起的文档,即表单字段在其父表单的上下文之外几乎没有意义。

MongoDB 将允许您将这些文档存储为单个结构,而不是像在关系数据模型中那样分散在各个表中。

这是 YAML 只是因为它比 JSON 更简洁。底层结构将是相同的。

_id: 12345
creator: Adrian
name: NoSQL form demonstrator

fields:
  - id: first_name
    label: First name
    type: text
    required: true

  - id: last_name
    label: Last name
    type: text
    required: true

  - id: dob
    label: Date of birth
    type: date

  - id: bio
    label: Biography
    type: textarea

  - id: drink
    label: What would you like to drink?
    type: select
    options:
      - id: tea
        label: Tea
      - id: coffee
        label: Coffee
      - id: beer
        label: Beer
      - id: water
        label: Mineral water

    - id: mailing_list
      label: Join our mailing list?
      type: check
      default: false

笔记:

您只需将键存储在需要它们的位置,而不是像在关系数据库中那样为每个上下文中的每件事都设置一个列。例如,不需要required: false-- 如果这是默认设置,则将其排除在外。

MongoDB 文档具有内在顺序,因此无需在表单设计中创建字段来保存字段的顺序。

表单结果将以相同的方式存储。只需按照您的预期自然存储它们:

_id: 545245
form_id: 12345
name: NoSQL form demonstrator

results:
  - id: first_name
    label: First name
    type: text
    value: Adrian

  - id: last_name
    label: Last name
    type: text
    value: Short

  - id: dob
    label: Date of birth
    type: date
    value: 1970-01-01

  - id: bio
    label: Biography
    type: textarea
    value: Doing things on the internet

  - id: drink
    label: What would you like to drink?
    type: select
    value: Tea

  - id: mailing_list
    label: Join our mailing list?
    type: check
    value: false
于 2012-07-04T00:33:16.373 回答