Keeping DRY with NoSQL



在过去的几年里,我一直在从事出版行业中使用NoSQL数据库的项目。作为一个程序员,作为一个从设计SQL数据库起家的人,我努力做到DRY。

在以文档为中心的数据库中,DRY似乎是被回避的东西,它甚至可能对性能和可伸缩性有害。当然,这是我的同事们的看法,他们与一些NoSQL供应商合作过,甚至为一些NoSQL供应商工作过。他们应该知道。

尽管如此,我还是很难做出精神上的飞跃,因为我发现很难接受DRY和NoSQL是不相容的。生活中有太多的事情开始于一种过分的推动,然后以最有效的妥协来解决。

数据经常重复,我一直看到完整性问题。我对程序员和高级管理人员的态度是拥抱它,拥抱它的生命。消费服务必须处理它,否则这是上游团队的问题。

我想知道为什么文档不是由许多小的子文档组成,并被引用,拼接在一起,就像一个视图,我猜。

"打印"到每个文档中的数据只能通过编写自定义的"查找替换"来更新,就像必须跨tb的操作一样。因此,这些特性增加了成本,并且对敏捷故事没有明确的需求,因此不会被构建。数据变得更加不一致

将文档分解成子文档的问题是,本机数据库搜索停止工作,因为它不知道文档-子文档的关系。因此,搜索必须是一个自定义过程,搜索子文档,然后整理它们链接到的主文档的外键。

是否有一个中间地带,或者真的是接受权衡的情况?关于这个问题的讨论并不多。

《路加福音》

不确定您在哪个平台上,但是您是否看过在DB和客户端之间放置一层?

举个例子,我喜欢feathersjs的架构,它允许你在DB查询之前/之后运行钩子。在文档和子文档上下文中,查看包含的钩子populate和dePopulate。

下面是1:1关系的文档示例:

// users like { _id: '111', name: 'John', roleId: '555' }
// roles like { _id: '555', permissions: ['foo', bar'] }
import { populate } from 'feathers-hooks-common';
const userRoleSchema = {
  include: {
    service: 'roles',
    nameAs: 'role',
    parentField: 'roleId',
    childField: '_id'
  }
};
app.service('users').hooks({
  after: {
    all: populate({ schema: userRoleSchema })
  }
});
// result like
// { _id: '111', name: 'John', roleId: '555',
//   role: { _id: '555', permissions: ['foo', bar'] } }

PS: feathers支持多种数据库,也支持SQL数据库

最新更新