FirestoreとNoSQLについて

Firestoreについて

FirestoreはNoSQLモデルのデータベースです。 公式サイトは以下です。 https://firebase.google.com/docs/firestore?hl=ja

FirestoreってRDBと何が違うの?というとデータを保持する構造が全く異なります。
RDBに詳しい人ほど取っ付きにくいかもしれません。
windowsエクスプローラーのような感じでフォルダの中にファイルが入っていたり、さらにフォルダが入っているような構造です。

f:id:room01:20210731183815p:plain:w300
公式サイトから引用

フォルダに該当するものはコレクションと呼ばれ、ファイルに該当するものはドキュメントと呼ばれます。
具体例:
RDBで会社テーブルがあって、会社テーブルの中に各会社のレコードがある+会社IDに紐づく従業員テーブルが別にあるとします。
この場合をFirestoreで再現しようとすると
会社コレクションの中に各会社のコレクションがあり、各会社のコレクションの中に会社名などのドキュメントと、従業員コレクションが存在する形になります。

f:id:room01:20210731185243p:plain
Firestore
f:id:room01:20210731185718p:plain ※従業員コレクションを会社コレクションと別にして、会社IDと紐付けて管理することも可能ですが、イメージのために会社コレクションの下に作成しました。

普段GUIで使っているディレクトリ構造なので、RDBより学習コストは 低いと思います、多分。
また執筆時点ではコレクション間のjoinが出来ないので、複雑なSQLを書くことはありません。
逆にRDBのような使い方をしたい場合は、プログラム側で頑張る必要があります。 例えば一旦各コレクションを取得して、各コレクションから関連するIDをプログラム側で引っ張るなど。

NoSQLでデータを取得する

処理は公式から引用します。
firebase.google.com

// データの書き込み
var citiesRef = db.collection("cities");

citiesRef.doc("SF").set({
    name: "San Francisco", state: "CA", country: "USA",
    capital: false, population: 860000,
    regions: ["west_coast", "norcal"] });

コレクションのオブジェクトを取得して、そのコレクションのドキュメントに書き込みたいデータをセットしています。
なおcreate文やカラムの概念はなく、今まで定義されていないドキュメントもセットする事ができます。
柔軟な一方で、書き込まれるドキュメントを制限することは出来ません。
例えば上の例でareaをいきなり入れてもsetは通ります。

db.collection("cities").where("capital", "==", true)
    .get()
    .then((querySnapshot) => {
        querySnapshot.forEach((doc) => {
            // doc.data() is never undefined for query doc snapshots
            console.log(doc.id, " => ", doc.data());
        });
    })
    .catch((error) => {
        console.log("Error getting documents: ", error);
    });

こちらが取得の例です。 SQLと同じくwhereで条件を指定しています。
NoSQLはNot only SQLと解釈されているようで、SQLに似たことを書く必要はあります。SQLが存在しないわけではありません。

所感

簡単なアプリケーションであればFirestoreで十分に感じます。
ただ、Webアプリケーションがある程度複雑で、データが色々と相互参照されている場合は、RDBで管理したほうが楽であると感じました。
特にjoinでデータを引っ張ってこれないのは痛いと思いましたが、これは自分がRDBに慣れているからかもしれません…。 あくまで個人の感想です。