我目前的项目本质上是一个工厂文件管理系统的运行。
也就是说,有一些皱纹(惊喜,惊喜)。虽然有些问题是项目特有的,但我相信有一些普遍的观察结果和问题没有规范的答案(无论如何我可以找到)并且适用于更广泛的问题领域. 这里有很多,我不确定它是否适合 StackExchange Q&A 格式,但我认为它 a) 一个可回答的问题和 b) 不够具体,它可以使社区受益。我的一些考虑是特定于我的,但我认为这个问题对任何面临决定 SQL 还是 NoSQL 还是两者的人都有用。
我们正在构建的 Web 应用程序包含本质上具有明显关系的数据以及面向文档的数据。我们想吃蛋糕,也想吃。
TL;DR:我认为下面的 #5 通过了气味测试。你?有没有人有将 SQL 和 NOSQL 集成到单个应用程序中的经验?我试图在下面列出解决此类问题的所有可能方法。我错过了一个有前途的替代方案吗?
从本质上讲,它是关系数据(您的典型 Web 应用程序内容,如用户、组等,以及我们需要能够实时对复杂查询进行切片和切块的文档元数据)和文档数据(例如我们没有兴趣加入或查询的数百个字段 - 我们对数据的唯一用例将是显示输入的单个文档)。
我想对我的首选方法进行完整性检查(如果你检查我的发帖历史,我非常明确地说明我不是 DBA),并列举我遇到的所有选项供其他人解决涉及关系和非关系数据的广泛相似的问题。
1. 每个文档类一张表
每个文档类都有自己的表,其中包含所有元数据和数据的列。
好处:
缺点:
评估面向文档的存储,CouchDB 与 MongoDB 的优缺点是什么?
我对学习 NoSQL 数据库很感兴趣,我决定从面向文档的数据库开始。有哪些好的资源可以学习此类数据库的概念和良好的设计?
编辑: 这个问题是关于如何处理在整个系统设计中出现的许多问题,这使得系统的某些部分偏离了通用标准。例如,使用自己的程序代码管理业务模型中的所有内容,甚至关系完整性。这给数据库和持久层带来了一种糟糕设计的味道,将其用作“将某些内容转入并以某种方式再次取出”的地方,而不是结构化存储。我问了这个问题,因为在我看来,NoSQL 文档存储就像一个选项,可以将已经无模式(或非常松散的模式)数据库移动到默认情况下没有模式的数据库。此外,我必须指出,尽管这里描述了一些缺陷,但整个系统根本不是一个坏系统。此外,一些问题,例如版本控制,已经有了解决方案或已经实施。
想想你看到的一个软件系统,基于经典的关系数据库(SQL Server、Oracle)、NHibernate作为对象关系映射器(ORM)、顶部的业务逻辑模型层和大量模块(几百个) ,主要是基于 .NET 的服务和一些 Web 服务(带有客户端,每个系统/客户最多约 100 个,公司网络,非公共)。操作方式主要是OLTP,写/CUD访问是工作负载的重要组成部分。生产数据库通常大约为 10GB,但大小总是远低于 100GB(因此没有“大数据”)。它确实工作得很好,但对我来说,数据库和 ORM 实现有几种反模式(对于关系数据库)的味道。也许这些实现对于另一种数据库会更好——面向文档(“NoSQL”)或内存数据库。
省略了许多关系数据库和支持 ORM 的功能:表被强烈反规范化,外键关系丢失或不可能,例如由于元数据表引用不同的主表,列如IdInTable INT, OwnerTable INT
. NHibernate 几乎没有映射对象关系(并且通常存在不适合它的表结构的问题)。相反,这些是在业务逻辑中实现的(有时会导致孤立的子对象或低效的数据库访问,见下文)。
基础之下的非规范化:增加非 1st NF 数据的使用:带有 XML、逗号分隔列表或复合数值列的 nclob/nvarchar(max) 列(例如,任务类型 123 的 123、10123、40123,但模块配置不同由 0,1,4 * 10000 标识)。前两个包含数据库相关、逻辑“外键”和数据模型相关值,例如<UserType>AdminUser</UserType>
(要检查LIKE '%...%'
)。这主要是由于许多快速发布、短暂存在和自定义的值不应该进入主模式,或者更容易通过 XML 值实现。
非 2nd NF 数据,包括由触发器、后续存储过程或应用程序复制到其他表中的表内容。例如,将表列值复制到“垂直”元数据表,这再次复制到元数据的“水平”或“旋转”表示(每个元数据类型为一列),因为某些应用程序只能使用元数据或水平元数据. 经常要求使用“垃圾箱结构”(将从各种来源收集的数据转储到一个 nclob/nvarchar(max)“垃圾箱”列中,并让应用程序搜索它,而不是许多不同的来源)。
业务逻辑模型和应用程序中的“单一对象疾病”: 单个对象的迭代和立即加载/保存:业务层主要使用 Load/Save() 方法来处理单个对象和少量基于批量/集合的操作。一个常见的工作是通过 SQL 或者它的 NHibernate 表示来获取对象 ID,然后遍历所有检索到的 Id 并以foreach (oneId in Ids) { myObjects.Add( BizModel.GetMyObjectById(oneId) ); }
. 这包括所有元数据、依赖对象集合等,这是典型的 SELECT N+1 情况。此外,大多数 NHibernate …
nosql document-oriented orm relational-theory denormalization