蚊帳の中の日記

ゆる〜りゆるり..hoge...fuga....fu.....zzzz

rubykaigi 2日目 感想

昨日のAfterPartyの疲れもあったのか、正直眠かったけど、なんとか最初のセッションからこれ

All bugfixes are incompatibilities

これまでのBugfixの経験談を主に語ってもらい、普段Rubyコミッターやメンテナーがどうやってお仕事してるのか知れて楽しかった)これを聞いて思ったけど、redmineの動向とか追っておけば、来年のRubyKaigiとかで同じようなセッションあったときに「あ〜あの話ね〜」ってなって面白そう)。

初日にMatzも言っていたが、既存のRubyコードが壊れないことを考慮して互換性や名前を非常に考えながら取り組んでいて、感謝の気持ちしか起きなかった。こういったメンテナンスポリシーとは逆に破壊的な変更を許容してどんどんアップデートしていくと、進化は早くなるかもしれないが、こういったポリシーのほうが僕ら利用させてもらう立場的に本当に感謝しか無い(IO.readFile.readでブロック変数の最初にパイプ渡したらそれ以降に記述したコマンドを実行してしまう話を禁止するか、互換性を保つためにwarningを喚起するだけにとどまるかの議論も、聞いてて楽しかった)。

parse.yは魔境

better csv processing with ruby 2.6

終始、漫才感のある発表で、内容ともに楽しかった!
csvのパース、エクスポートを高速化した話が主。

CSV,generate_line vs CSV#<<」の話では、複数行書き出す時は<<を使うと、10倍も早くなっちゃうのよ〜〜すご〜〜〜い(each_lineが最速のパース方法らしいけど、クオートがあるとうまく出来ないという制約があるらしい)。

どうやって、これらの高速化出来たのかという話についても、Rubyのコア部分の話になるのかなと思って身構えたが、そんなことはなくて、普段僕レベルでも知っているメソッドのたちが登場した。

例えば、複雑なクオートを利用しているcsvだとsplitを使うと遅くなってしまうらしいので、StringScanner(.scan)を利用したらしく、split使うと遅くなるし、コードも汚くなるけど、scanならコードきれいになりやすくて、メンテナンスしやすいし、性能が劣化がないというメリットを説明してくれて、なるほど〜となった。 ただ逆に、複雑なクオートではなく、単純なクオートを使ったcsvだと、StringScannerでは遅くなってしまうらしく、そっちはsplitを利用していた。ケースバイケースで使い分けてる。

他にも、CSVオブジェクトを作成するタイミングを遅延化(lazy)して、毎回オブジェクトを初期化する無駄を省いて高速化したという話もあった。これも、僕らが普段使うような@a ||= objectみたいなコードが出てきて、ふむふむってなれた。

今後もこれらの高速化に取り組むらしくが、まだutf-8などへの文字エンコーディングの速度が問題らしく、これが今後の主な課題らしい。 お手頃なKEN.CSVみたいなcsvを、どっかから取ってきてcsvいじってみたくなった。

メモ
  • quate_char:オプション
  • parse_column_value
  • liberal_parsingオプション
  • backslashオプション
  • stripオプション
  • gem install csvでとりあえず早い方の使えるぜ!
  • RedDataToolsの取組の一環

Ovto: Frontend web framework for Rubyists

「自給自足プログラミング」これ好き。

OvtoというHyperAppというJS製のFWに強く影響してて、更にOpalによってRubyでフロントエンドもかけちゃうフロントエンドフレームワークを紹介してもらった。単純に楽しそう。

普段、VueとかReactは趣味で触っていたので、VirtualDOMやReduxは知っていたが、その辺りの基礎的な説明から入ってくれて、それらを機能が使えるHyperappについて紹介から始まった。その後、Rubyからjsコードを生成してくれるOpalも紹介してもらい、その後それらを使った表題のFWの説明とデモを見せてくれた。

jsは嫌いじゃないけど、普段使っているrubyでフロントも書きたい...無いから、作った...まさに自給自足プログラミングを体現していた。本当楽しそう。

早速触ってみました。東京帰ったら、もっと弄ってみようっと。

メモ
  • runtime.rb: OvtoApp -> ovtoが変換 -> JS(VirtualDOM -> hyperappcoreに送る。アプリ側の処理が重くない限り、ある程度の速度は担保できる?
  • wired_actions.rb???
  • You might not need redux
  • SSR, routeも欲しいという話がでたら、作る予定。

The fastest way to bootstrap Ruby on Rails

uzuraさんのセッション。
CRIUは初めて聞いたし興味津々だった。linuxのプロセス情報をimageでdumpしてくれるらしく、dumpしたimageは別ホストでrestoreすれば、同じコンテナを簡単にマイグレーションできる優れものらしい。

また、CRIUを利用することで、例えばモノリシックで大きなRailsアプリケーションとかでも、linuxのプロセス初期化をうまいことスキップしてくれるので、その初期化分の時間をreduceできて、結果的にbootstrap処理時間が早くなるというものだった。また、一つのホスト上のコンテナが死んでも、自動で別ホストでリスタートしてアクセスもそっちに流すようこともしてくれる。コンテナスケールアウトのコストも削減。

ほえ〜と思いながらここまで聞いていたが、ここからが本題で。 これらはコンテナ環境で利用できるが、VM環境をサポートしたものが無いので、同じようにmigration,checkpoint,restoreを実現するGrenadineを紹介していただいた。

英語もわかりやすかったし、Grenadine触ってみたい!ってなったけど、正直コンテナとか園周辺の知識というが個人的に乏しかったので、こういった機能とかワードがあるんだな〜というのも知れてよかった。dockerにも既にcheckpointの機能は既にあるらしいのだが、まだまだ出たばかりということもあり、Grenadineを作るきっかけにももなったらしい。作ってしまうのですごい。。。

CloudNativeバンザイ!!!!

Benchmarking your code, inside and out

いままで聞いたセッションとは毛色が違う内容だった。。。と思う、、、英語リスニング力が弱くてわからなかった...。 多分、Micro benchmarkingに関する取り組みとか、rallyなどを利用した計測のベストプラクティスとか話してくれたのかな...。くっ...、英語リスニング力付けたい


最後のLT大会も楽しかった〜〜〜。。。。明日は最終日....あっという間だ。

rubykaigi 1日目 感想

「鉄は暑いうちに打て」ってよく言うし、忘れないうちに今日受けたセッションの感想とか思ったことを自分なりに書き残しておく。 (間違ってる!とか補足情報とかあればコメント欲しい :pray:)

Matz session

内容は大別するとパフォーマンス、Static Typing、Concurrency、あとちょっとだけ2.7や3.0の新機能の話をしてくれた。

世の中の言語進化のトレンドはStatic Typing

あまり多言語は詳しくないが、PHPだったらtype hintingpythonだったらtype annotation、jsだったらtypescriptといった元々は動的型付けなプログラミング言語にも静的型付けと同様の機能を後付で付与するリリースが頻発していて、Rubyでもそれらの導入が検討されているらしいという話。 個人的には多いに賛成だし、開発していて型を指定できる安心感を得られるな〜という気持ちになるのだけど、Matz自身は「型を指定するというのは、機会に余計な指示をしているようで、DRYではないので、正直あまり導入はしたくない」と嘆いてた。この考え方について「なるほどな〜」と思いつつ、でも実際のRubyを使う開発者サイドとしては「うーむ、それでもサポートしてくれないかな〜」という気持ちが正直なところではある。今後の動向に注目したい。

この機能をサポートする技術は色々検討はされているらしく、なんかeslintのlineチェックを明示的に外すコメントアウトみたいに、rubyコードの右に型の指定を記述したコメントアウトみたいなのを追加するとか、rbiファイルみたいな別の型情報を持ったファイルを用意するとか、はたまた真新しいことをしなくてもサポートしようとしていたりとか、sorbet or steepとかをつかってtype checkするとか、、、、色々紹介してくれた。 (余談だけど、Matzの「テスト角の嫌いなんですよ。僕らはプログラムを書きたいわけで、テストを書きたいわけではない。でも人類は正常なプログラムを書けないので仕方なくテストを書いている。」って説明がなんか良かったし、ほっこりした。)

後は、よくテーマになるPerformanceの話

RubyコンパイラとしてJITとかMJITという言葉は聞いたことあるけど、Rubyって2.6は昔の2.0よりも実行速度が2.8倍も早くなったいたらしい。ただ、Railsなどのフレームワークかますと何故か処理速度が遅くなってしまうらしい。。。この辺り、正直「なんで?」ってなってよくわからないのだけど、この辺りの疑問をもう少し自分たちなりに深掘りして調査してみると、実務でRailsサービスの速度を早く出来たりするのかな〜と逆に興味が湧いた。

あと、そういったコンパイラの実行速度改善以外に、パフォーマンス改善の手段として並列性(Concurrecy)の話も出てきた(どうでもいいけど、Falcon使ったことも触ったこともない)。
話によると、RubyElixirなどの並列処理してもそれぞれのプロセスがデータを共有しない(Shared Nothing)ような設計になっていないので、その問題を解決しないといけないらしかった。で、この問題を解決してくれるのがGuildというものらしく、Goのgorouting、ElixirのprocesssのようにShared Nothingを実現してくれるらしい。この辺りも今後の動向に注目したい(この話を聞いた後、スポンサーブースの同人誌コーナーにあった並列処理大全って書籍がめっちゃ気になって買いたくなってしまった)。あと、Guildって名前がゲーム業界から予約語として指摘されたのおもろかった。

あと、諸々気になったワードをメモ
  • Deep Fronzen Object
  • ? Literal wwwwww
  • メソッドオブジェクトを取り出す???
  • Proc.curry
  • ::でメソッド呼び出しができるの知らんかった
  • Ruby Pattern Matching
  • keyword extension

あと、とにかく、RubyGemsアカウントは乗っ取られないように、2段階認証やパスワード共有禁止などして、みんなで安全な世界をRuby世界を作りましょう!って気持ちになった。

How to use OpenAPI3 for API development

実務で使えそうなお話かな〜と思い聞きに行った。そもそも知らなかったのが、SwaggerとかOpenAPIとか名前が自分の中で混在してたのだけど、「あ、一緒なんだ」、、、という感じの僕みたいな知識レベルでもわかりやすかった。

OpenAPIなどのこういったJSONスキーマを定義しておくツール?は、あくまでjsonymlでリクエスト・レスポンスのルール書いて、それに基づいてフロント・バックエンド・アプリなどの多方面のプラットフォームがそれを念頭に開発するというメリット持ったルールになる。なので、これ自体が実装するプログラミング処理に直接関わるというのはちょっと違う(あんまりJSONスキーマを定義してから、開発するという経験が薄いので、改めてメリットを知れてよかった。ちなみこういったschema first developmentと言ったりする)。

そして、更にそれらルールをmachine readableにすることで、色々とメリットはある模様。そのmachine readbleなメリットを持っているのでOpenAPI3らしい(json hyper schema, graphqgRPCなども類似としてあるけど、それぞれ違いやメリデリはある。) OpenAPI3は幾つかStructureがあって、紹介してたSecurity Object schemaは、Oauth2とかベーシック認証などもぱっとymlに書くだけでいいのが良かった。(別に定義したからと言って、それがすぐ使えるようになるわけではないです。)

あと、リクエスト・レスポンスの両方をRack層でvalidationしてくれるcommittee gemも紹介してもらい、スキーマ通りの実装が出来ているかどうかを担保することができるんだな〜スゲ〜、ってなった。

~あと、openapi-parserみたいなどを使えば、ymlのネストをRubyで読み込むとオブジェクトが入れ子になってて見づらい問題を解決してくれるらしい。~

あと、諸々気になったワードなどをメモ

Pragmatic Monadic Programing in Ruby

日本語だったのに、1日目で一番「僕の知識では追いつけない...うまく咀嚼して理解できない...」と思ってしまった。有名なjokerさんのセッションだったのと、モナドという未だによく理解していない概念を知れるきっかけになればいいと思って聞いたが、僕にはまだ早かった...。

話の流れ的には、AST実装を例に、関数型言語にある概念?の一つにあるモナド的な動きをする処理をRubyで黒魔術を使って書いてみたという話...と解釈したけど、あってるかな...。 https://rubykaigi.org/2019/presentations/joker1007.html#apr18

とにかく、覚えて帰ったのが、「monad はある法則に基づいて動く flatMap

あと、諸々気になったワードなどをメモ
  • Fanctor
  • Applicative fanctor
  • bind operator >>=
  • moand 計算チェーン??
  • RubyVM::AST.of

Ruby for NLP

自然言語処理でよく出るMeCabもあるけど、RubyでもNLPNatural Language Processing)できるやで!っていうのを形態素解析の基礎から説明してくれたセッション。大学生の時ニューラルネットワークやら自然言語処理やらをちんぷんかんぷん状態で聞いていて、まったく知識がない状態だったけど、めっちゃわかりやすい説明で良かった。最後のDemoをもっと見たかった...。

資料が挙がったら、発表の最後の方に紹介してもらった、RubyNLPを実現するためのツール群を調べて、色々遊んでみたい!

A Bundle of Joy: Rewriting for Performance

bundle install,bundle exec xxx、、、bundler遅いから新しく書き直して、gelというgem manager作ったよ!というお話だった。

実行速度を紹介してもらったが、installやらrmやら諸々のbundlerの実行コマンドがgelに置き換わっただけで、半分以上も短縮されてて、「とにかく、やばそう!!!!1」ってなった。

この辺り、どうやって実現していたのか、英語力が足りなくて悔しかった。bundlerからRubyGemsに完全移行する話も最初のセッションで柴田さんが言っていたけど、それらの動きと、このgem managerがどういった感じで関連してくるのかな〜というのも気になった。

気になるワードやらURLやら

Pattern matching - New feature in Ruby 2.7

Ruby2.7から導入されるPattern Maching機能について。 実用面ではjsonなどを受け取って、そのjsonパターンと一致した場合に何か処理をしたり、そのjsonの一部を変数に代入したりといった使い道が紹介されていて、早く使ってみたい!という気持ちになった。

Array,Hash,Value,String,...(後なんだっけ)などの、色々なパターンがあって、リリース時に是非ドキュメントを熟読して実務で活かせたらいいな。特に、Array patternのパターンマッチが色々説明があって、より複雑なパターンのマッチを処理したいときに有効そう。ネストした配列、マッチしたパターンの一部を取得?...etcなど、すげー!ってなったけど、ドキュメントを見て改めて整理した。

東京帰ったら触ってみよっと

ref: https://speakerdeck.com/k_tsj/pattern-matching-new-feature-in-ruby-2-dot-7


After Party 最高でした!!!!1明日も楽しみ!!!!1

Nuxt.jsを初めて触った

3連休最後は公式のドキュメントを見ながらNuxt.jsで遊んだ。

ja.nuxtjs.org

github.com

yarnもしくはnpxを使ってちゃちゃっとプロジェクトの土台を作れて、始めるのはとても楽だった。 ちょい概念として予習したほうが良さそうなのが、Flux。Actionとかdispatcherとか、データをstoreに置いてviewに反映さえるとか、Fluxアーキテクチャのフローは先に知っておくと良さそう。

f:id:kayamelo151515:20190211214522p:plain

ちゃっと作って。。。

f:id:kayamelo151515:20190211214539p:plain

わーーい。すぐに画面ができた。

使ってみて

最初に触ってみて思ったのが、ファイル構造がわかりやすいということ。それぞれが何の役割を持っていて、何をするのか?をパッとディレクトリ構造を見ればわかるし、細かい設定はだいたいnuxt.config.jsを見ればわかる。
Vueを勉強し始めた時は、以下のVue.js入門を読みながら進めたのだけど、Nuxt.jsを触りながらのほうがより実践的にVue.jsの知識を習得しやすかったかな〜とか思ったりもした。

kayanaka.hatenablog.com

先程、ファイル構造がわかりやすいと言ったように、ルーティングごとにpages配下にvueファイルを置けばnuxtがファイルを読んでいって対応したルーティングを作ってくれる。基本的にRailsみたいにconfig/route.rbとか作らなくて良い。動的にルーティングも_show.vueみたいにアンスコを頭に入れれば出来る。

pages以外にも、layouts, middlewares, plugins, modules, components, static, storeといったディレクトリがある。

ディレクトリ構造 - Nuxt.js

layoutsは想像の通りデフォルトのレイアウトテンプレートを置くところ。エラーのレイアウトのテンプレートも用意しておけば、エラー時にNuxtが良しなにエラーの方のテンプレートを呼び出してくれる。

staticsはその名の通り静的ファイルを置いておくディレクトリなんだけど、webpackで扱うパターンと、単に置いておいて管理するパターンの両方が出来る。

アセット - Nuxt.js

middlewaresはルーティング前に制御したい処理を書いておく。
外部プラグインなどはpluginsに置いていき、VueのインスタンスやVueストアにInjection(注入)して使うことが可能。
modulesはNuxt.jsのコアをどんどん拡張していくことが出来る。多分、もっとサービスの機能を増やしていくとなると、このあたりのディレクトリをいじっていくことになるのかなと思う。

store(VuexStore)についてはクラシックモードとモジュールモードの2つがある。サーバサイドから初期値などを取得したい時はnuxtServerInitとかに処理を書くと良さそう。

nuxt.config.jsが肥大化していきそうな予感

初めて触ってみて、middlewareやpluginを読み込んだり、ヘッダー情報を書き込んだり、グローバルなcssを読み込んだり、環境ごとのビルドを設定したりと、いろんなことを設定できるコアのファイルとしてnuxt.config.jsってのがあって、これがプロジェクトルートに置いてある。 結構これの設定が重要で、アプリーケーションが大きなるに連れて、このconfigファイルを大きくなりそう。。。

railsでMySQLのIndex Hintを使う

たまにMySQLオプティマイザが上手いことやってくれなくて、インデックスを貼っているのにそのインデックスを使ってくれなかったり、意図しないインデックスを使っていたりする場面に以前遭遇した。

で、こういうときどうするのだろうと思ったのだけど、明示的にRails側で利用するインデックスを指定するscopeを用意するのが、よくある方法らしい。

Index Hintを指定したscopeを用意

MySQLで利用するインデックスを指定するにはUSE INDEXとかFORCE INDEXIndex Hint)を使う事になる(Index HintはMySQLの一機能になる)。

で、RailsでIndex Hintを使ってクエリを発行したいとき、modelにuse_indexみたいなscopeを用意して、それを使ってindex指定したクエリを発行するのが、よくあるやり方っぽい。

scope :use_index, ->(index_name) { 
  from("#{self.table_name} USE INDEX(#{index_name})")
}

※ 以下のリンクのコードを引用にさせてもらった

qiita.com

Vue filterで表示テキストなどをフォーマット

Vue.jsのfilterが便利だった。

jp.vuejs.org

Railsのhelperみたいな感じ

Railsのhelperみたいな感じで、filterを定義すれば渡された値に対して処理を加えてその結果を返す。モデルから渡されたテキストをそのまま表示するのではなく、ちょいユーザーの見やすい形にフォーマットして表示したいときとかに重宝しそう。

例えば、APIから返ってくる日付情報が 2019-02-03T12:12:57.134Zだったとして、これをviewに表示するとなると、ちょい味気がない。そこでVueのfilterの出番。

以下のような感じ。

// 日付の変換処理にはdate-fnsというライブラリを使ってみた
import format from 'date-fns/format'

export default {
  filters: {
    dateFormatter: function (date) {
      return format(date, 'YYYY/MM/DD')
    }
  },
...
}

これで、dateFomatterという関数が出来る。入力値は{{ }}の中身をパイプで区切って左側に置いておけば、引数として読み取ってくれる。

<small>{{ date | dateFormatter }}</small>

※ モデルから取得したデータ以外にも、inputタグに入力された値に対してフィルター処理を加えた結果を表示するのにも便利。 ※ 公式のドキュメントにもあるように、入力値を関数から関数に受け渡すことも出来るし、複数引数を渡すことも可能。

ただ、複数引数を渡すとき、

{{ message | filterA('arg1', arg2) }}

みたいになるらしい。だけど、直感的に見て一瞬どれが引数だよ?ってなりそう。{{ (message, 'arg1', arg2) | filterA }}みたいに出来ないのか?と思ったけど。。。

とはいえ、良さげな変換ライブラリと組み合わせれば、Railsのhelperみたいに便利なフィルターを定義できるのは素晴ら。

ゆっくり…順序立てて…慌てない…

仕事でペアプロを主体にしてタスクを進めていく開発スタイルになって暫く経つのだけど、その上で結構自分に問題があるな〜と思った点があったので書き留める。

タスクを状況の共有がうまくいかない時がある

今のペアプロの体制は、二人一組になって、一つのタスクを担当して進めていっている。タスクを進めていき1時間程度経ったらペアを交代して、また別の人とタスクを進めていく。 こうすることによって、お互いの知識を補填し合えるので、行き詰まることも少なくなってくるし、お互いの知識の共有や取り組むタスクの範疇も広がっていくので、ひとりひとりの知識や出来ること増えていって、組織メンバーの技術のレベルアップにも繋がる。すごく良い取り組みだと思うし、こういう環境で色々なタスクに取り組めるのは、大変なときもあるけれど、有意義でやりがいがある。

で、このペアを切り替える時に新しく組んだ相手に、タスクの進捗状況を説明して、次に何をやるべきなのかを伝えない。これが上手くいかないと、タスクの目的やゴールがモヤッとした状態で進んでうまくいかない時がある。

この伝えるのが個人的にうまく伝えられなくて、相手が首を傾げてしまうパターンが結構多いな〜と感じるときがあり、どうしたもんかな〜となっていた。

なんで伝わらないのか?

色々思いつくのだけど、今一番個人の問題だと思っているのは「できるだけ今の状況を早く伝えようとして、途中過程や状況を少し飛ばして話してしまうこと」かな〜と思った。

うまい問題例が思い浮かばないので、あまり深く書かないが、ここ最近、この問題の解決のために、安直だけど「ゆっくり慌てず順序立てて話す」ということが良いかなと感じている。 今の状況に至った過程や理由を知れるほうが相手も納得しやすいし、理解もしやすいのだと思う。また、その先の新たな問題意識に目を向けてもらいやすくなる感じもしている。


他にも色々問題はあるだろうし、上の対策は超当たり前の事かもしれないけれど、ちょっと意識するだけでもいいかもしれない。

Firebase Realtime DatabaseのデータモデルはデカイJSON

去年モモンガ本を見ながら作った Vue.js + Firebase製のマークダウンエディタを作って、その後もVue.jsの勉強も兼ねてちょっとずつ機能を追加していた。

kayanaka.hatenablog.com

で、「メモにもカテゴリタグ的なもの付けて、それで検索とかもできると便利そう!」と思ったので、データベースにカテゴリカラムを追加しよう!とか思ったのだけど、データを管理しているFirebase Realtime database(以下 realtime)のデータモデルがちょっと余り触ったことない感じで取っ付きにくかったのでメモ。

とりあえずデカイJSON

f:id:kayamelo151515:20190129231639p:plain

公式のドキュメントを見ればわかるのだけど、NoSQLデータベースでredisのようなキーバリュー指向ではなくて、JSONを使った所謂ドキュメント指向的なもの。つまり、でかいJSONになっている。 データ構造もできるだけJSONのネストを深くせず平坦に保つとか、RDBみたいな正規化でなくむしろ非正規化をしてデータを冗長な形にしたほうがフェッチするときに効率的になるとか、色々書いている。 これが普段RDBとか使ってる身としては、結構取っ付きにくかった。realtimeのデータ構造についてググってみると「RDBのようなデータ構造の考え方は一旦忘れたほうがいい」的なことも出てきたりして、普段のDBの扱い方とは勝手が違う。

migrationとかそういうのは無い

で、最初に話していた「カテゴリ機能」を追加したいので、普段Railsに慣れ親しんでいる自分としては「なんかmigration的なことをするのかな?」とか思ってたのだが、実際はそういうことはしない。 クライアント側で、新しくカテゴリのparameterに追加してrealtimeのapiにpostするようにすれば、それ以降に追加したメモにはカテゴリが追加されることになる(こういうデータ構造は多分はスキーマレスDBとか言ったりすると思う)。 それより前に保存されていたメモたちについても、再度保存したタイミングでカテゴリが追加されて更新される。つまり、クライアント側でpostするデータを書き換えれば、それに合わせたデータ構造でレコードも更新してくれるということ。事前にmigration的なことしてデータ定義を設定するという前処理はない。

なんか一つ手間が省けた感があって、いい感じだと思うが以下のような問題も出てくるかなと思う。
例えば、途中でクライアント側からpostするattirbute Aを追加したために、参照しようとしたときにあっちのレコードにはAがあるけど、過去のこっちのレコードにはAがないということが起きたり、途中追加したattributesを使って全データを集計したいとき、そのattributesが無いレコードもあって集計が単純にいかない、とかはありそうだな〜と思った。なので、そのあたりをクライアント側で上手いことしてあげる必要が出てきそう(このあたりは類似形式のDBの特性とか運用方法を勉強すると楽しくなりそう 👨🏼‍💻)。

もしかしたら、FireStoreのほうがいいのかも…

realtime databaseと一緒に似たような Cloud Firestoreってのもあって、こっちはコレクションとかドキュメントという概念でデータを構造化する仕組みになっている。まだ内容をちゃんと読んでないので、よくわかっていないが、もしかしたらrealtime databaseより場合によっては運用がしやすいのかもしれない。こっちも追々触ってみたい。

firebase.google.com


こんな感じで暇な時にVueと一緒にFirebaseでも遊んでいる 🧔