妈妈:使用MySQL在Mongo的视图上是可以的

最近,重新思考(或者说大约3周之后),DB混合使用会不会更好的话,也有些许传闻。不管那些高尚的谈话如何,这个Mongo开始的SQLer项目是出于「精神健康」(或者说为了精神健康)、「在紧急情况下也能使用SQL」之类的心态而创建的。

Artboard 1.png

如果只想查看代码,请访问Momy存储库。

首先

有几个动机对于MongoDB来说是重要的

    • がしがし集計したい

 

    • さくっとテーブル間のJOINをしたい

 

    Microsoft Accessや、Libre Office Baseから接続したい

在考虑MEAN(指MongoDB、Express.js、AngularJS和Node.js的开发技术堆栈)或SPA(单页应用)等情境时,尽管这是一种常见情况,但实际上相当麻烦。尤其是最后一项,更是个意外的难点。

注1: ここでは、一応、MongoDB→MySQL同期の方向に話を持って行きますが、もっといい方法があったら是非教えてください。

注2: ちなみにMEANの「A」はanythingの略ですよ?

寻找解决方案

ODBC是什么?

虽然有一个初步的开放选项存在,但由于它仍然处于“实验性”的状态已经过去了三年,所以仅供参考。嗯,哎呀,如果用MySQL的话就可以简单连接了……但是直接连接到NoSQL可能有些困难。

sp13_10g – mongoDb ODBC Driver EXPERIMENTAL

商用的话,从这里或者那里似乎也有可用的驱动程序,但是不要过多追问,因为它们可能很贵。

莫SQL?

Stripe发布了一个名为”MoSQL”的开源工具。这是一个可以直接将MongoDB与SQL进行同步的工具,它是用Ruby编写的。GitHub上的星标大约有1K。然而,它仅支持PostgreSQL。虽然一度有将其扩展至支持MySQL的动向,但似乎最终没有实现。遗憾。

    https://github.com/stripe/mosql

尽管如此,在能够转向PostgreSQL的情况下,这是一个选择。在MEAN的背景下,确实很难处理…

然而,如果可以转向PostgreSQL,那是一个选项。在MEAN的环境下,确实不容易处理…

在Node的世界里不存在吗?

我在这里看了那么多候选人,但还差一步。不知道有没有什么办法可以在Node的世界中解决呢?我试着仔细搜寻,找到了一些看起来不错的东西。这…这难道就是正确的答案吗?

    MongoDB-to-MySQL

尽管在npm上也发布了,但它总是给人一种没有完成的感觉。事实上,当我尝试使用它时…它根本无法运行,让我非常苦恼。看来,它也停留在”三年前”,大家已经对Mongo感到厌倦了…这让我感受到了历史的沉重。

没办法,只能靠我自己了。

当时虽然迷茫不解,但是只要阅读代码,不管是MoSQL还是MongoDB-to-MySQL,它们所做的事情都很简单。

    • MongoDB間のReplication機能をうまく流用する

 

    • Tailable Cursor(追尾カーソル?)でMongoDBの変更を監視

 

    変更箇所のログを取ってきて、SQLなデータベースに反映

这些东西,大部分都可以通过MongoDB本身的功能来解决。如果只是这些需求的话,我觉得我可以做出来。

妈妈

我做了。

最初,我们打算对MongoDB-to-MySQL进行修改,但是最终几乎没有原始代码留下,所以我们决定给它取了一个别名。现在它叫做Mongo to MySQL,简称为”Momy”。据说在法国有一个地方叫这个名字。

momy.png

利用副本套装的日志

核心代码是以下部分吗?(稍微变形)

tail () {
  const
    filters = {
      // 前回のタイムスタンプより新しいログを監視
      ts: { $gt: Timestamp.fromNumber(ts) }
    },
    curOpts = {
      // 追尾モードを設定
      tailable: true,
      awaitdata: true
    }
  mongodb.connect(url)
    .then(db => {
      db.collection('oplog.rs')
        .find(filters, curOpts)
        // 検索結果はストリームとして取得
        .stream()
        .on('data', log => { /* MySQLに保存 */ })
    })
}

在MongoDB中进行复制相关设置时,会添加一个名为local的数据库(在独立使用时不存在,有时在GUI应用中会被隐藏)。

最新的MongoDB通常使用副本集(replica set)实现多台服务器之间的复制和故障转移。本来用于MongoDB之间同步的日志信息会保存在之前提到的local内的oplog.rs集合中。通过监视并提取它作为流,就可以得到前面展示的这样的代码。太方便了。MongoDB的API真是太方便了。

数据库的准备工作 de

首先,让我们启动一个空的mongod。在此过程中,加入–replSet和–oplogSize选项。前者类似于复制集的“组名”,后者用于设置日志的大小(以MB为单位)。

注: すでに手元で運用中のmongodがある場合は、別ポート–portかつ別ディレクトリ–dbpathにしたほうが良いかもしれません。

$ mongod --replSet "rs0" --oplogSize 100

在另一个窗口中打开终端,启动mongo shell。

$ mongo
....
> rs.initiate()

如此一来,当执行rs.initiate()命令时,将生成所需的数据库和集合。

接下来,按照平时的方式/照常进行。

    • MongoDB: アプリケーション用のデータベースを作成

 

    MySQL: 受入れ用のデータベースを作成

只要准备好就行了。数据库名称可以任意,但在接下来的说明中,我们都使用”myapp”。

一种基于模式的东西

可以复制MongoDB上的所有字段,但也可以选择只保留“必要的部分”。可以考虑“只导入用于统计的数值,跳过备注栏等”等方法。

即使是无模式的NoSQL,实际上在应用程序中应该具有一定的结构。限定主要项目和必要的分析项目,可以避免频繁跟随MongoDB的模式变更,更现实可行。从思考的角度来看,

    • ドキュメント (帳票データとか) – MongoDB

 

    メタデータ (共通項目、集計項目) – MySQL

如果我们这样说会更容易理解吗?我们可以将前者比作“文件”,将后者比作“文件系统”。

在Mommy中,您需要准备以下类型的json文件,并定义模式。建议文件名为momyfile.json。

{
  "src": "mongodb://localhost:27017/myapp",
  "dist": "mysql://root@localhost:3306/myapp",
  "prefix": "t_",
  "collections": {
    "collection1": {
      "_id": "number",
      "field1": "number",
      "field2": "string",
      "field3": "boolean"
    },
    "collection2": {
      "_id": "number",
      "field1": "number",
      "field2": "string",
      "field3": "boolean"
    }
  }
}

src: MongoDBサーバのURL

dist: MySQLサーバのURL

prefix: MySQLのデータベース名に共通の接頭辞をつけたい場合に設定 (省略可)

collections: 同期するコレクションごとのフィールド定義

在字段定义中,我们简单地指定了数字(number)、字符串(string)和布尔值(boolean)。

"<コレクション名>": {
  "<フィールド名>": "<フィールド型>"
}

试着动一下

请从npm进行安装。

$ npm install -g momy

假设MongoDB服务器已经包含了某种数据。在首次执行时,我们将先导入这些数据,然后开始进行监视。请指定 “–import” 选项。

$ momy --config momyfile.json --import

如果数据数量较大,可能会需要一些时间。我们需要确认MySQL端是否已经复制了数据。停止时,请使用Ctrl + C。之后,应该只需要差异数据,不需要使用任何选项。

$ momy --config momyfile.json

或者也可以使用“永远”这个词。

$ forever momy --config momyfile.json

注: –configオプションを外すと、ワーキングディレクトリのmomyfile.jsonを使います。

用中文翻译以下内容,仅需一个选项:

通过API

大概我会把它设计成可以通过API使用的。

总结

BaaSが当たり前になっていく中、こうやってデータベースで遊べるのもあと数年の話でしょうか。はやくRelay的な世界に移行しますように。

とはいえ、現場レベルだとMicrosoft Accessはまだ幅を利かせているので、そこからBaaSにどうやって繋げるの? とかはまだ不透明だったりします。ログの解析ツールはオンラインで色々ありますが、社内での解析方法自体が秘伝のタレ化し、オンライン化不可能案件になっていることもしばしば。ビッグデータになったとたん、Accessだとどうしようもなくなるという話はそれはそれ。

使用Aggregation Framework来操作和分析MongoDB数据也逐渐改进了很多,掌握这个技能是很重要的。

    • SQL慣れしているほど、覚えるのがめんどくさい

 

    多機能になった集計機能(aggregation)をどのようにAPIに晒すか

有时候我会这样考虑。后一个问题相当复杂。

    • 定型の集計以外

 

    設計時には想定外のテーブルと複雑にJOINさせつつ、傾向を探るとか

我不太清楚该如何通过API来解决这个问题,没有很明确的落脚点。

在这种情况下,在找到答案之前,我的主要功能是使用MongoDB灵活地构建,用于聚合等后台操作,则放置一个只读的MySQL(或其他RDS)是合理的想法。

广告
将在 10 秒后关闭
bannerAds