用户创建的数据库结构:非关系型或关系型数据库?

8

我希望我的数据库记录中有动态字段。

例如:我想为用户创建自己的表单应用程序。

用户可以创建以下表单:

个人资料:

  • 全名
  • 街道
  • 工作
  • 电话
    • 家庭
    • 工作
    • 移动电话
  • 兴趣
    • 兴趣1
    • 兴趣2
    • 兴趣3

工作:

  • 名字
  • 姓氏
  • 工作
    • 部门
      • 专业1
      • 专业2
    • 部门
      • 专业1
      • 专业2

国家:

  • 美国
      • 纽约
        • 城市
          • 纽约
          • Foo
      • 阿拉巴马州
        • 城市
          • 酒吧
          • Baz

正如您所看到的,这是一个非常动态的结构:

  • 没有预定义的字段数
  • 没有预定义的字段名称
  • 用户创建数据库的结构

因此,我想知道,对于这个最好的数据库是什么:关系型(mysql/postgresql)还是非关系型,例如mongodb/couchdb/cassandra,甚至是xml数据库,如xindice?

即使我选择了非关系型数据库,将安全关键信息存储在其中是否明智,例如客户和计费信息?

我听说人们说,如果您的信息需要唯一性,则使用关系数据库。 “我们不想冒险向我们的客户收取两次费用”。他们实际上指的是非关系型数据库有哪些问题?您不能在非关系型数据库中存储唯一数据吗?

我还想到了另一件事:在非关系型数据库中保存数据是否意味着我将有重复的条目?

考虑以下示例:

类别:

  • 办公室

    • 应用程序
      • Textmate
        • 作者:Foobar
        • 价格:120
      • Foo
        • 作者:Foobar
        • 价格:120
  • 办公室

    • 应用程序
      • Textmate
        • 作者:Foobar
        • 价格:120
      • Bar
        • 作者:Foobar
        • 价格:120

正如您所看到的,存在相同条目的情况。非关系型数据库如何处理这些情况?我习惯于关系型数据库。

我总结一下我的问题:

  • 哪种类型的数据库适合用户创建的数据库结构?
  • 非关系型数据库适合存储安全关键信息吗?
  • 非关系型数据库如何处理重复数据?
3个回答

3
我强烈推荐您查看CouchDB
  1. 您可以使用直观的 REST API 与 CouchDB 进行通信。换句话说,它是“Web 制造”的一部分,而不仅仅是像 MongoDB 等后端数据库。CouchDB 实际上可以提供表单并接收提交,因为它有一个内置的 Web 服务器。
  2. 作为 JSON 文档存储库,它非常适合存储结构化但无模式的数据。(表单及其提交实际上是文档,以这种方式对它们进行建模更合理,我的意见是这样的。)
  3. 您可以轻松地将描述每个 Web 表单的 JSON 文档存储在相同的“bucket”中作为表单提交。(CouchDB 甚至可以解析表单 POST 并将其转换为 JSON 文档,以任何您认为合适的方式。例如,让它自动时间戳表单提交就很简单。)
  4. 您可以编写所谓的“_show”函数,在 CouchDB 中实际生成每个表单的 HTML 代码。还可以查看“_update”和验证函数。
  5. 它具有您需要的安全功能。
  6. 文档冲突可以轻松识别。更好的是,CouchDB 自动确定文档的“获胜”版本,但您仍将继续访问“失败”的文档版本(直到您告诉 CouchDB 压缩数据库为止,这将删除旧的修订版本。)
    • 关于唯一性:与其让 CouchDB 生成唯一的文档 _id,不如为每个表单提交创建的每个 JSON 文档分配一个真正表示唯一表单提交的 _id。如果每个用户仅允许对每个表单进行一次提交,则为从表单提交创建的每个 JSON 文档使用以下内容之类的东西:submission:user:5:form:a3df2a712
使用CouchDB,您可以避免为每个用户可能创建的表动态创建唯一表的麻烦。

1
我已经研究了MongoDB和CouchDB。它们似乎是这种动态结构的好解决方案。你也尝试过前者吗? - never_had_a_name
MongoDB非常不同。对于您想要做的事情——涉及提供和处理Web表单响应——couchdb似乎更加合适。MongoDB没有内置的Web服务器,也无法在内部处理表单。当然,您始终可以仅使用MongoDB来存储JSON数据。但是CouchDB为您提供了许多内置工具,否则您必须自己编写这些工具。 - BenD
您可能想了解一下CouchApps的工作原理。(http://www.couchapps.org)CouchApps是一个完美的例子,MongoDB无法提供这样的功能,因为它“只是”数据库。 - BenD

2
如果您的数据非常适合关系模型,但需要存储一些动态格式的数据而不是海量数据,那么最好将JSON、XML或类似内容存储到列中。虽然这样做会失去一些SQL类型的优势(索引、外键约束检查、类型检查等),但对于存储动态结构文档并且查询不太关心其内部结构时很有用。
如果您想存储大多数关系数据和少量JSON/XML等数据,则建议使用PostgreSQL。PostgreSQL具有XML数据类型,但我不建议使用它,因为我讨厌XML :P。没有人阻止您将JSON存储在TEXT字段中,但PostgreSQL很快就会有支持函数的JSON数据类型。hstore contrib模块提供了一种有效的存储键/值对的方法,并提供全文索引支持。
尽管将JSON或类似内容塞入SQL数据库列与关系模型相悖,但通常情况下仍然应该这样做(当有意义时!)。否则,您必须向数据库解释整个应用程序的架构,导致大量SQL和数据库映射代码实际上没有任何作用。

PostgreSQL不是很快就要推出JSON数据类型吗?我记得在9.0或9.1版本中听说过这方面的消息。 - xenoterracide
从数据存储的角度来看,将JSON存储为文本字段似乎毫无意义。然后您必须进行序列化和反序列化以确保JSON有效。我不喜欢这个解决方案。根据要求,似乎像MongoDB或CouchDB这样的noSQL解决方案更为优越。 - Amala

-1

选择数据库更多地取决于您想要查询什么和如何查询,而不是您想要存储什么。所有的数据库都可以让您存储几乎任何您想要的东西。

关系型数据库管理系统(RDBMS)在基于关系模型的查询方面特别擅长,并且可以相当随意地进行查询。通过临时过滤器和连接,您可以做各种各样的魔术。

非关系型数据库(NOSQL DBs)在查询方面往往不太灵活,但在其他任务上表现良好(例如,在“非结构化”数据上工作得更好)。

根据您在此处发布的内容,我会使用SQL数据库,并按照用户希望定义表格。设置索引,设置查询。对我来说,这听起来像是一个真正的无脑操作。 SQL数据库可以轻松处理所有“即兴定义字段”的事情,因为...那就是它们所做的。所以使用它。


真的吗?我不认为这是关系型数据库的优势。与之相比,其他替代方案更擅长处理动态数据。你想要选择关系型数据库的唯一原因就是支持——相比NoSQL替代方案,关系型数据库有更多的阅读材料和支持。 - Sasha Chedygov
SQL数据库可以轻松处理“动态定义字段”的所有操作。您能否向我展示动态定义字段/列的功能链接?NOSQL数据库在查询方面可能不太灵活,但在其他任务(例如更好地处理“非结构化”数据)方面表现良好。这不就是一个非结构化数据的例子吗? - never_had_a_name
1
你可以在用户操作时发出“ADD COLUMN”语句以“即时定义字段”,但这并不是一个好主意。SQL数据库实现并不一定能很好地处理数百列。 - Joey Adams
@joey adams。我同意!由于每个条目/行都有自己的字段/列,因此我真的不应该向整个表添加新列! - never_had_a_name
@ajsie:实际上,我不认为情况是这样的。在PostgreSQL中添加列(至少)不会通过加宽所有表行来进行,因此我怀疑新行中的许多null列将占用额外的空间。但是,PostgreSQL对于每个表的最大列数为2500-1600,具体取决于列类型。 - Joey Adams

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接