在开发软件大约5年后,我花了大约20%,也许高达40%的时间只是让RDBMS能够保存和检索复杂的对象图.很多时候,这导致了不太理想的编码解决方案,以便从数据库端更容易做到.在学习NHibernate和作为其一部分的会话管理模式花费了大量时间之后,这最终结束了.使用NHibernate,我终于避免了大部分100%浪费的时间来编写CRUD第1000次,并使用我的域模型中的数据库的前向生成.
然而,所有这些工作仍然导致一个有缺陷的模型,我的数据库只是SQL模仿我的实际对象的最佳尝试.对于文档数据库,不再是这种情况,因为对象变为文档本身而不是仅通过表和列模拟对象.
在这一点上,我真的开始质疑为什么我会再次需要SQL?
有什么可以真正做到实质上与SQL比文档数据库更好?
我知道这有点像苹果到橙子的比较,特别是当你考虑到具有广泛不同的特征集的各种类型的NoSQL数据库时,但为了这个论点,它基于NoSQL数据库的概念本身可以正确地查询对象而不是关键值存储的限制.还要忽略报告方面,因为通常应该在OLAP数据库中处理,除非您的答案包含不使用OLAP数据库的特定原因.
在亚马逊,我使用了大量代码.我工作过的大部分代码都是代码,没有人真正理解了.它充满了特殊的案件处理,但是很难理解,因为它在很长一段时间内都是快速补丁.如果你想完全理解你所做的改变的影响,那你就是运气不好.从本质上讲,你被迫增加了吸积.
我还处理了大量数据.SQL中表的结构为数据提供了出色的长期文档.数据库相对容易直接使用,数据结构很有意义.有些人的工作是管理数据的结构和完整性.
我担心NoSQL数据库缺乏记录良好的结构,会慢慢获得我所使用的代码的所有邪恶特性.它最终将充满旧结构的数据,而这些数据已经没有人真正理解了,并且变成了大多数无用垃圾的庞大拼凑.
我认为SQL数据库的主要好处是维护数据库结构和一致性规则所需的强制文档.这些好处没有简单的短期措施,如查询速度或事务一致性.它们是长期的好处,会在很长一段时间内影响数据的有用性.
作为第二个相关点,我发现在使用ORM等时,映射我的数据然后决定如何将其转换为我正在编写的应用程序中的对象更有用.数据及其关系代表了可用于各种目的的长期档案结构.
应用程序中对象关系的结构是出于该应用程序的目的.SQL表和关系约束中表示的给定数据集将具有许多可能在应用程序中表示它的对象模型,并且每个对象模型将反映该特定应用程序的目标.但是数据及其结构独立于可能由它们构成的任何给定的短暂使用.
我认为人们对"报告"的论证是不同的应用程序可以以非常不同的方式有用地查看同一组数据的论据.
就个人而言,我认为SQL是一个很好的模型,可以直接用于存档数据,不经常修改的数据或具有极高一致性要求的数据.而且我认为我将继续使用关系代数来定义我的数据的整体结构,即使我将它存储在NoSQL数据库中.如果不先修改描述它的关系结构,我就不会改变NoSQL数据库中数据的结构.这将允许我将我的NoSQL数据库映射回SQL,因此我仍然可以使用SQL进行长期存储和仓储,并迫使我以一个记录良好的形式维护数据结构.
当我必须从NoSQL数据库中提取数据以用于创建数据库时未设想的应用程序时,以这种方式执行操作也会对我有所帮助.
当然,有些数据的结构自然适合NoSQL,而为它生成关系模式则毫无意义.例如,存储实际文档,存储图片或其他媒体,或其他没有可能有用的结构的大数据.但这种区别非常棘手.图片和电影确实具有结构,只是通常不需要存储在数据库中的结构.如果你有一个旨在试图阅读和理解它的系统,博客文章也可能有结构,这可能是你想保持记录的结构.
关系数据建模是一种形式化的数学解决方案,用于表示没有冗余且不允许异常的复杂数据.您可以从数据关系本身设计最佳数据库设计.这是关系数据库规范化的过程.
非关系数据建模没有正式的方法来从数据中定义最佳数据库结构.您可以根据预期的使用情况设计数据库; 也就是说,您的查询确定最佳数据组织,而不是数据本身.
在非关系数据库中,您永远无法确定数据是否符合某个文档结构.您可以从早期版本的数据库中保留文档.因此,您的应用程序代码最好能够"发现"每个文档的结构,在必要时执行转换,并希望数据集合之间的引用得到满足.
在关系数据库中,您可以依赖数据完整性作为模型的组成部分.如果你设计标准化并正确设置约束,你就知道你永远不会有孤儿或数据异常.
在设计数据库时,非关系数据库为您提供了一种效率.当您使用数据库时,关系数据库为您提供了另一种效率.
也就是说,您使用的特定类型的问题 - 对象图 - 使用纯SQL可以有效地完成.但我认为你会发现使用NoSQL数据库并不容易.
重新评论:当然,一致性不是每个应用程序的优先级.对于重要的应用程序而言,这并不会使一致性的价值"非实质性".
您询问了为什么要使用关系数据库 - 当关系数据库的好处符合项目的优先级时,您就会使用它们.
不要用螺丝刀钉钉子,也不要用锤子拧螺丝.有一个合适的工具来解决每种类型的问题.
这取决于你想要做什么.当你需要在对象的不同字段上进行搜索时,SQL就是好的.如果您不需要进行搜索,并且您具有非常复杂的多态树状结构,则SQL非常糟糕.
我已经开发了应用程序,允许用户通过将小片段连接在一起构建网页,原始序列化使用键/值SQL表.所有片段都具有存储的属性(片段,属性,值).如此无模式,但仍然很繁重.可能是两个世界中最糟糕的,因为你没有从数据库中获得太多的数据验证,很难查看表并理解发生了什么,并且仍然有很多工作要将它写入数据库并且读回来.
我们也做了类似的应用程序,但是我们吸取了教训,我们只使用普通的java类并使用JSON对它们进行编码.用户只需在富有的ui中编辑前面的页面.单击"保存",整个页面将作为json对象发送回服务器.然后服务器对对象进行验证,以确保所有约束都是正确的,除非用户已被篡改或代码中存在错误,否则应始终为真.然后通过编码将对象写入一行以返回到json.
这对我们很有用,因为我们从不想处理部分对象.我们总是处理整个对象,所以JSON不仅更容易,而且比每次读取的40多个查询更快,如果它被正确规范化我们必须做的.