关于将 MongoDB 与 MySQL 混合用于 Web 应用程序的建议
Posted
技术标签:
【中文标题】关于将 MongoDB 与 MySQL 混合用于 Web 应用程序的建议【英文标题】:Advice on mixing MongoDB w/ MySQL for a web application 【发布时间】:2012-02-14 16:55:59 【问题描述】:我有一个使用关系数据库 (mysql) 的 Web 应用程序。我们正在添加一项新功能,允许某些用户从可选表单元素池中动态构建“表单”,并将这些表单分发给其他用户完成/提交。
问题在于存储完成的表单提交。每个表单都可以并且会在表单元素的数量和组合方面有所不同,并且对于关系数据库,我的选择在一定程度上仅限于动态创建一个新表来保存每个表单的提交(似乎是一条不好的路径)或存储在 TEXT 列中以 JSON 格式提交的每个表单(失去 RDBMS 的所有有用查询能力)
我以前从未在生产项目中实际使用过 MongoDB,但我认为使用我的 MySQL 关系数据库存储由我的应用程序的某些用户创建的所有表单可能是个好主意,然后存储所有MongoDB 中的提交,每个文档都引用 MySQL 中表单的 UUID。
我能想到的第一个缺点是表单提交和 MySQL 中的表单之间没有参照完整性。如果我在 MySQL 中删除一个表单,则必须手动删除所有表单提交(如果我想复制“级联”效果)
我是否会将我所有表单的所有表单提交存储在单个 MongoDB 集合中作为单独的文档?任何意见是极大的赞赏。 :)
编辑 1 基于此处的文档:http://www.mongodb.org/display/DOCS/Using+a+Large+Number+of+Collections
我现在正在考虑创建一个新集合来保存来自每个独特表单类型的所有提交。
编辑 2
经过仔细考虑和其他人的建议后,我决定放弃解决此问题的双数据库方法,转而使用我认为可以解决创建动态表单和保存表单提交的问题的关系数据库模式这样他们就可以轻松查询复杂的报告。
基本上,“表单”中的每条记录都代表用户构建的唯一表单。 'forms_fields' 有一个引用表单的外键和一个带有选项的枚举类型: 1.复选框 2. 文本字段 3.文本区域 4.选择 5.多选 6.日期
'forms_fields_options' 包含一个选择字段将具有的所有'选项'。 通过这三个表,用户可以创建自定义表单。
当其他用户填写并提交表单时,会在 forms_submissions 中创建一条记录。对于每个字段,将在“forms_submissions_fields”中创建一个引用表单提交和 forms_fields_id 的相应记录。最终表“forms_submissions_options_multiselect”本质上是一个连接表,用于指示用户选择了多选表单字段中的哪些选项。
【问题讨论】:
使用您提供的架构,对其中一个自定义列进行简单搜索的查询是什么样的? 【参考方案1】:我认为您忽略了这样一个事实,即 RDBMS 将允许诸如 EAV(实体-属性-值,如果您过度使用它会很糟糕,但在适度时可以很好)或连接表之类的东西来构建多个有序关系从单个表单到各种表单元素。
我并不是说 RDBMS 对所有事情,甚至你的情况都是完美的,但我知道我必须构建类似的系统,并且从来不需要使用 noSQL 来以合理的方式支持它们。
编辑:更重要的是...存储实际字段值会使您与原始表单元素产生更多关系,但如果您的 UI 保持一致,您可以通用地执行此操作。我想说的是,进一步研究哪些 noSQL 解决方案允许您需要的特定类型的基于值的查询可能会更清楚您的选择。
【讨论】:
感谢您的建议。我试图构建一个数据库模式,我相信它只使用 MySQL 就能解决我的问题。介意看看并告诉我你的想法吗?它现在发布在“编辑 2”下的我的问题中【参考方案2】:这绝对可以在 SQL 中使用EAV 完成。所以 NoSQL 绝对不是必需的。
使用像 MongoDB 这样的工具可能非常适合您想要保存的灵活结果,但是,这里有一些取舍,但它们可能并不完全符合您的预期。
...将每个提交的表单作为 JSON 存储在 TEXT 列中(失去 RDBMS 的所有有用查询能力)
您计划提交多少表单?您打算进行哪种类型的查询?
我使用 MongoDB 的经验是,当您查询未编入索引的数据时,它的性能很差。此外,聚合通常使用 Map/Reduce(或新的聚合框架)分批完成。
如果您比较进行汇总的复杂性或进行查询的效率,并不清楚 MongoDB 在这方面明显优于 EAV。
如果我在 MySQL 中删除一个表单,所有的表单提交都必须手动删除
奇怪的是,我很少将此视为问题,因为您可能永远不会删除 SQL 中的表单。您可能会进行逻辑删除,而永远不会真正删除任何内容。所以这可能是一个有争议的问题。
我是否会将所有表单的所有表单提交存储在单个 MongoDB 集合中作为单独的文档?
再次取决于您计划获得多少表单和提交。如果两者都有很多,那么以后使用集合/提交将很难分片。
老实说,我会使用单个集合,然后将 _id
字段覆盖为可以合理用作分片键的内容。您可以在这里玩一些花哨的技巧,但这超出了这篇小文章的范围。
总结
最后,您绝对可以使用 MongoDB 来解决这个问题,但这不是“本垒打”。如果您不熟悉 MongoDB,这绝对是一个公平的“学习项目”,但预计会在查询和聚合方面遇到一些障碍。
【讨论】:
感谢您的建议。我试图构建一个数据库模式,我相信它只使用 MySQL 就能解决我的问题。介意看看并告诉我你的想法吗?它现在发布在“编辑 2”下的我的问题中【参考方案3】:我的一位同事最近主持了一个关于这个主题的网络研讨会,题为“使用 MongoDB 和 RDBMS 的混合应用程序”。你可以在这里查看: http://www.10gen.com/events/hybrid-applications
从 cmets 看来,您似乎已经决定走 RDBMS 路线,但希望这可以为您未来的项目提供一些想法,或者对阅读此主题的其他人有所帮助。
祝你申请顺利!
【讨论】:
感谢@Marc,网络研讨会的示例在将 MySQL/SQL 与 MongoDB/NoSQL 配对时使用 Doctine 保持直截了当看起来不错。我还在研究这个。以上是关于关于将 MongoDB 与 MySQL 混合用于 Web 应用程序的建议的主要内容,如果未能解决你的问题,请参考以下文章