年末年始にデータ指向アプリケーションデザインを読み進めた。リレーショナル・データベースとドキュメント・データベースの違いについてランダムにメモ。
データの多重度 🔗
1:N 🔗
ドキュメント・データベースは多重度が1:Nのデータを1レコードで表現できる。
{
"name": "tomotargz",
"work_experience": [
{
"company": "Awesome company",
"position": "Software engineer"
},
{
"company": "Great company",
"position": "Manager"
}
]
}
対してリレーショナル・データベースは複数のレコードを結合しなければならない。
user table
id | name |
---|---|
1 | tomotargz |
work_experience table
id | company | position | user_id |
---|---|---|---|
1 | Awesome company | Software Engineer | 1 |
2 | Great company | Manager | 1 |
1:Nのデータを扱う場合、ドキュメント・データベースはlocalityを活かせるので読み取りのパフォーマンスが高い。
N:1, N:N 🔗
多重度がN:1やN:Nのデータを扱う場合、ドキュメント・データベースは結合をエミュレートするか非正規化しなければならない。
結合 🔗
ドキュメント・データベースは結合のサポートが弱い。多くの場合、データベースではなくアプリケーション側で結合しなければならない。通常、アプリケーションによる結合はデータベースによる結合よりも時間がかかる。
スキーマ 🔗
ドキュメント・データベースはスキーマレスと言われることがあるが正確ではない。アプリケーションはスキーマを暗黙のうちに想定してデータを読み取る。そのため、正確にはドキュメント・データベースはスキーマオンリードであると言える。対して、リレーショナル・データベースはスキーマ・オンライトである。
ドキュメント・データベースはデータのフォーマット変更に対応しやすい。例えばnameフィールドをfirst_nameとlast_nameに分けなければならないとき、リレーショナル・データベースでは一般的にスキーマの変更が必要になるが、ドキュメント・データベースではアプリケーションが読み取り時に動的にfirst_nameとlast_nameを作成する(first_namtとlast_nameが存在しなかったらnameを元に作成する)アプローチを取れる。もっとも、リレーショナル・データベースでも同様のことが可能なので、大きな違いとは言いにくい。
何らかの理由でデータのフォーマットが統一されていないときは、ドキュメント・データベースを使うメリットが生まれる。以下のようなケースが考えられる。
- 多くの種類のオブジェクトがあり、それぞれに専用のテーブルを作成することが現実的でない場合。
- データのフォーマットが外部のシステムに決定され、いつ変更されるかわからない場合。
インピーダンスミスマッチ 🔗
多くのアプリケーションはオブジェクト指向で設計されている。オブジェクト指向におけるデータモデルはリレーショナル・データベースとは異なる。そのため多くの場合、リレーショナル・データベースとアプリケーションの間に変換レイヤーが必要になる。このデータモデルの違いはインピーダンスミスマッチと呼ばれることがある。
アプリケーションの扱うデータがドキュメントのような構造(多重度が1:Nのツリー構造を持ち、ツリー全体が一度にロードされる)を持っている場合、ドキュメント・データベースを使うことでアプリケーションコードを単純化できる。そうでない場合、アプリケーションで結合をエミュレートしなければならない。結合を避けるために非正規化すると、データの整合性を保つためのコードが必要になる。ドキュメント・データベースがインピーダンスミスマッチを軽減するとは一概には言えない。