这个数据库着火了……

这个数据库着火了……

让我讲一个技术故事。

许多年前,我正在开发一个内置协作功能的应用程序。 这是一个用户友好的实验堆栈,充分利用了早期 React 和 CouchDB 的潜力。 通过JSON实时同步数据 OT。 它被用于公司内部运作,但在其他领域的广泛适用性和潜力是显而易见的。

在尝试向潜在客户出售这项技术时,我们遇到了意想不到的障碍。 在演示视频中,我们的技术看起来和工作都很好,没有任何问题。 该视频准确地展示了它的工作原理,并没有模仿任何东西。 我们提出并编写了一个使用该程序的现实场景。

这个数据库着火了……
事实上,这成了问题。 我们的演示的工作方式与其他人模拟其应用程序的方式完全相同。 具体来说,即使是大型媒体文件,信息也会立即从 A 传输到 B。 登录后,每个用户都会看到新条目。 使用该应用程序,即使村里某个地方的互联网连接中断,不同的用户也可以清楚地合作完成同一项目。 After Effects 中的任何产品视频剪辑都隐含了这一点。

尽管每个人都知道“刷新”按钮的用途,但没有人真正了解他们要求我们构建的 Web 应用程序通常受到其自身的限制。 如果不再需要它们,用户体验将完全不同。 他们大多注意到他们可以通过给正在交谈的人留下笔记来“聊天”,所以他们想知道这与 Slack 等有什么不同。 唷!

日常同步的设计

如果您有软件开发经验,那么记住大多数人不能只看界面图片并了解它在与之交互时会做什么,这一定是令人伤脑筋的。 更不用说程序本身内部发生的事情了。 知识表明 может 发生的情况很大程度上是因为知道什么不能发生和什么不应该发生。 这需要 心理模型 不仅包括软件的功能,还包括其各个部分如何协调和相互通信。

一个典型的例子是用户盯着 spinner.gif,想知道这项工作什么时候才能完成。 开发人员会意识到该过程可能会被卡住,并且 gif 永远不会从屏幕上消失。 该动画模拟作业的执行,但与其状态无关。 在这种情况下,一些技术人员喜欢翻白眼,对用户的困惑程度感到惊讶。 然而,请注意其中有多少人指向旋转的时钟并说它实际上是静止的?

这个数据库着火了……
这就是实时价值的本质。 如今,实时数据库仍然很少被使用,许多人对它们持怀疑态度。 这些数据库中的大多数都严重依赖于 NoSQL 风格,这就是为什么它们通常使用基于 Mongo 的解决方案,而这些解决方案最好被遗忘。 然而,对我来说,这意味着能够轻松地使用 CouchDB,以及学习设计结构,而不仅仅是一些官僚可以填充数据。 我想我更好地利用了我的时间。

但这篇文章的真正主题是我今天使用的。 不是出于选择,而是因为公司政策的冷漠和盲目应用。 因此,我将提供两个密切相关的 Google 实时数据库产品的完全公平和公正的比较。

这个数据库着火了……
两人的名字中都有“火”这个词。 我记得一件事。 对我来说第二件事是不同类型的火。 我并不急于说出他们的名字,因为一旦我说出了,我们就会遇到第一个大问题:名字。

第一个叫做 Firebase 实时数据库和第二个- Firebase 云 Firestore。 两者都是来自 Firebase 套件 谷歌。 分别调用他们的API firebase.database(…) и firebase.firestore(…).

发生这种情况是因为 实时数据库 - 这只是原来的 火力地堡 2014 年被谷歌收购之前。 然后谷歌决定创建一个并行产品 一份副本 Firebase基于大数据公司,并称之为Firestore with a cloud。 我希望你还没有感到困惑。 如果你还是一头雾水,别担心,我自己把文章的这一部分重写了十遍。

因为你需要表明 火力地堡 在 Firebase 问题中,以及 火店 在一个关于 Firebase 的问题中,至少让你了解几年前在 Stack Overflow 上的情况。

如果要评选最差软件命名体验奖,那么这绝对是竞争者之一。 这些名称之间的汉明距离是如此之小,以至于即使是经验丰富的工程师也会感到困惑,因为他们的手指键入一个名称,而他们的头脑却在思考另一个名称。 这些都是善意的计划,但却惨遭失败。 他们实现了数据库将着火的预言。 我根本不是在开玩笑。 提出这个命名方案的人引起了血、汗和泪水。

这个数据库着火了……

不成功的胜利

人们可能会认为 Firestore 是 更换 Firebase,它的下一代后代,但这会产生误导。 不保证 Firestore 是 Firebase 的合适替代品。 看起来有人从中剔除了所有有趣的内容,并以各种方式混淆了其余的大部分内容。

然而,快速浏览一下这两个产品可能会让您感到困惑:它们似乎通过基本相同的 API,甚至在相同的数据库会话中执行相同的操作。 这些差异是微妙的,只有通过对大量文献的仔细比较研究才能揭示出来。 或者当您尝试移植在 Firebase 上完美运行的代码以使其与 Firestore 兼容时。 即使如此,您也会发现,当您尝试用鼠标实时拖放时,数据库界面就会亮起。 我再说一遍,我不是在开玩笑。

Firebase 客户端是礼貌的,因为它会缓冲更改并自动重试优先于上次写入操作的更新。 但是,Firestore 限制每个用户每秒每个文档 1 次写入操作,并且此限制由服务器强制执行。 使用它时,您需要找到解决方法并实现更新速率限制器,即使您只是尝试构建应用程序也是如此。 也就是说,Firestore 是一种没有实时客户端的实时数据库,它使用 API 伪装成实时数据库。

在这里,我们开始看到 Firestore 存在理由的最初迹象。 我可能是错的,但我怀疑 Google 管理层的某个高层在购买 Firebase 后查看了 Firebase,然后简单地说:“不,天哪,不。 这是无法接受的。 只是不在我的领导下而已。”

这个数据库着火了……
他从他的房间里出现并宣布:

“一个大的 JSON 文档? 不。 您将把数据分割成单独的文档,每个文档的大小不超过 1 兆字节。”

似乎这样的限制在第一次遇到任何有足够积极性的用户群时都不会存在。 你知道是这样。 例如,在工作中,我们有超过一千个演示文稿,这是完全正常的。

由于这一限制,您将被迫接受这样一个事实:数据库中的一个“文档”与用户可能称为文档的任何对象都不相似。

“可以递归包含其他元素的数组数组? 不。 正如上帝的意图,数组将只包含固定长度的对象或数字。”

因此,如果您希望将 GeoJSON 放入 Firestore 中,您会发现这是不可能的。 任何非一维的东西都是不可接受的。 我希望您喜欢 JSON 中的 Base64 和/或 JSON。

“通过 HTTP、命令行工具或管理面板导入和导出 JSON? 不。 您只能将数据导出和导入到 Google Cloud Storage。 我想现在就是这么称呼的。 当我说“你”时,我只是针对那些拥有项目所有者凭证的人。 其他人都可以去创建门票。”

如您所见,FireBase 数据模型很容易描述。 它包含一个巨大的 JSON 文档,将 JSON 键与 URL 路径关联起来。 如果你写的是 HTTP PUT в / FireBase 如下:

{
  "hello": "world"
}

GET /hello 将返回 "world"。 基本上它的工作原理完全符合您的预期。 FireBase 对象的集合 /my-collection/:id 相当于JSON字典 {"my-collection": {...}} 在根目录中,其内容可在 /my-collection:

{
  "id1": {...object},
  "id2": {...object},
  "id3": {...object},
  // ...
}

如果每个插入件都有一个无碰撞 ID(系统对此有一个标准解决方案),那么这种方法就可以正常工作。

换句话说,该数据库 100% JSON(*) 兼容,并且与 HTTP 配合良好,例如 CouchDB。 但基本上,您可以通过抽象 Websocket、授权和订阅的实时 API 使用它。 管理面板具有这两种功能,允许实时编辑和 JSON 导入/导出。 如果您在代码中执行相同的操作,当您意识到 patch 和 diff JSON 解决了​​处理持久状态的 90% 的常规任务时,您会惊讶地发现浪费了多少专门代码。

Firestore 数据模型与 JSON 类似,但在一些关键方面有所不同。 我已经提到过数组中缺少数组。 子集合的模型是让它们成为一流的概念,与包含它们的 JSON 文档分开。 由于没有现成的序列化,因此需要专门的代码路径来检索和写入数据。 要处理您自己的集合,您需要编写自己的脚本和工具。 管理面板仅允许您一次对一个字段进行少量更改,并且不具有导入/导出功能。

他们采用了实时 NoSQL 数据库,并将其转变为具有自动连接和单独的非 JSON 列的慢速非 SQL。 类似 GraftQL 的东西.

这个数据库着火了……

热门爪哇

如果 Firestore 应该更可靠和可扩展,那么具​​有讽刺意味的是,普通开发人员最终会得到比选择开箱即用的 FireBase 更不可靠的解决方案。 脾气暴躁的数据库管理员所需的软件需要一定程度的努力和人才,这对于该产品应该擅长的利基市场来说是不切实际的。 这类似于如果没有开发工具和播放器,HTML5 Canvas 根本无法替代 Flash。 此外,Firestore 陷入了对数据纯度和无菌验证的渴望,这与普通企业用户的方式不符 热爱工作:对他来说一切都是可选的,因为直到最后一切都是草稿。

FireBase 的主要缺点是客户端的创建比当时的时代提前了几年,当时大多数 Web 开发人员都还没有意识到不变性。 因此,FireBase 假设您将更改数据,因此不会利用用户提供的不变性。 此外,它不会重用传递给用户的快照中的数据,这使得 diff 变得更加困难。 对于大型文档,其基于差异的可变事务机制根本不够。 伙计们,我们已经有了 WeakMap 在 JavaScript 中。 很舒服。

如果您为数据提供所需的形状并且不使树木体积太大,则可以避免此问题。 但我很好奇,如果开发人员发布了一个非常好的客户端 API,使用不变性并结合一些关于数据库设计的严肃实用建议,FireBase 是否会更有趣。 相反,他们似乎试图修复未损坏的部分,但这使情况变得更糟。

我不知道创建 Firestore 背后的所有逻辑。 猜测黑匣子内部出现的动机也是乐趣的一部分。 两个极其相似但又无法比较的数据库并列是相当罕见的。 就像有人想的那样: “Firebase 只是我们可以在 Google Cloud 中模拟的一个功能”,但尚未发现识别现实世界需求或创建满足所有这些需求的有用解决方案的概念。 “让开发者考虑一下。 把UI弄漂亮点就好了……能加点火吗?”

我了解一些有关数据结构的事情。 我确实将“一切都集中在一个大 JSON 树中”的概念视为从数据库中抽象出任何大规模结构的尝试。 期望软件能够简单地处理任何可疑的数据结构分形简直是疯狂的。 我什至不必想象事情会有多糟糕,我已经进行了严格的代码审核并且 我看到了你们做梦也想不到的事情。 但我也知道好的结构是什么样的, 如何使用它们 и 为什么要这样做。 我可以想象这样一个世界:Firestore 看起来很合乎逻辑,并且创建它的人会认为他们做得很好。 但我们并不生活在这个世界上。

从任何标准来看,FireBase 的查询支持都很差,而且几乎不存在。 它肯定需要改进或至少修改。 但 Firestore 也好不了多少,因为它仅限于普通 SQL 中的一维索引。 如果您需要人们对混乱数据运行的查询,则需要全文搜索、多范围过滤器和自定义用户定义的排序。 仔细观察就会发现,普通 SQL 本身的功能太有限了。 此外,人们可以在生产中运行的唯一 SQL 查询是快速查询。 您将需要一个具有智能数据结构的自定义索引解决方案。 对于其他一切,至少应该有增量映射缩减或类似的东西。

如果您在 Google 文档中搜索相关信息,您将有望找到 BigTable 和 BigQuery 之类的方向。 然而,所有这些解决方案都伴随着大量密集的企业销售术语,您很快就会回头并开始寻找其他东西。

对于实时数据库,您最不希望看到的东西是由管理人员薪资级别的人员创建并为他们服务的。

(*)这是一个笑话,没有这样的事情 100% JSON 兼容.

由于宣传

寻找 VDS 用于调试项目、用于开发和托管的服务器? 您绝对是我们的客户 🙂 各种配置的服务器的每日定价、反 DDoS 和 Windows 许可证已包含在价格中。

这个数据库着火了……

来源: habr.com

添加评论