私は非リレーショナル DB を使い始めたばかりで、まだ頭を抱えて最善のモデルを見つけようとしています。そして、私は CouchDB についてしか話せません。
それでも、いくつかの暫定的な結論があります。
非リレーショナルの世界でよりうまく機能する別の設計を思いついたことがありますか?
設計の焦点が変わります: ドキュメント モデル (DB テーブルに対応) の設計はほとんど無関係になり、すべてはビュー (クエリに対応) の設計にかかっています。
ドキュメント DB は複雑さを入れ替えます。SQL には柔軟性のないデータと柔軟なクエリがあり、ドキュメント DB はその逆です。
CouchDB モデルは、"JSON ドキュメント" (基本的にネストされたハッシュ テーブル) のコレクションです。各ドキュメントには一意の ID があり、ID で簡単に取得できます。その他のクエリについては、map/reduce 関数の名前付きセットである「ビュー」を記述します。ビューは結果セットをキーと値のペアのリストとして返します。
秘訣は、SQL データベースにクエリを実行するという意味でデータベースにクエリを実行しないことです。ビュー関数を実行した結果はインデックスに格納され、インデックスのみをクエリできます。(「すべてを取得する」、「キーを取得する」、または「キー範囲を取得する」として。)
SQL の世界で最も近い類推は、ストアド プロシージャを使用してのみ DB をクエリできる場合です。サポートするクエリはすべて事前定義する必要があります。
ドキュメントのデザインは非常に柔軟です。私が見つけた制約は 2 つだけです。
- 結合に対応するものがないため、関連するデータを同じドキュメントにまとめます。
- ドキュメントが更新されるたびにインデックスの再作成がトリガーされるため、頻繁に更新されるほどドキュメントを大きくしないでください (その年のすべての会社の売上を同じドキュメントに入れるなど)。
しかし、すべてはビューの設計にかかっています。
私が見つけた代替設計は、ストレージ レベルではなくシステム レベルで、どの SQL データベースよりも CouchDB の方が桁違いにうまく機能します。いくつかのデータがあり、それらを Web ページに提供したい場合、システム全体の複雑さは少なくとも 50% 軽減されます。
- DB テーブルの設計なし(軽微な問題)
- ODBC/JDBC 中間レイヤーなし、すべてのクエリとトランザクションは http 経由(中程度の問題)
- JSON からの単純な DB からオブジェクトへのマッピング。これは、SQL での同じものと比較してほとんど自明です (重要!)
- アプリケーション サーバー全体をスキップできる可能性があります。ドキュメントが AJAX を使用してブラウザーによって直接取得されるように設計し、HTML として表示される前に JavaScript の洗練を少し追加できるからです。(巨大!!)
通常の Web アプリケーションの場合、ドキュメント/JSON ベースの DB は大きな利点であり、柔軟性の低いクエリとデータ検証用の追加コードの欠点は、支払う代償が小さいように思えます。
不可能に思えることに頭をぶつけたことがありますか?
まだ。データベースにクエリを実行する手段としての Map/Reduce はなじみがなく、SQL を記述するよりも多くのことを考える必要があります。プリミティブの数はかなり少ないため、必要な結果を得るには、主にキーの指定方法を工夫する必要があります。
クエリが同時に 2 つ以上のドキュメントを参照できないという制限があります。結合やその他の種類の複数ドキュメントの関係はありませんが、これまでのところ克服できないものはありません。
制限の例として、カウントと合計は簡単ですが、平均は CouchDB ビュー/クエリでは計算できません。修正: 合計とカウントを別々に返し、クライアントで平均を計算します。
たとえば、あるパターンから別のパターンに変換するなど、設計パターンでギャップを埋めましたか?
それが実現可能かどうかはわかりません。これは、機能的なスタイルのプログラムをオブジェクト指向のスタイルに変換するような、完全な再設計です。一般に、ドキュメントの種類は SQL テーブルよりもはるかに少なく、各ドキュメントにはより多くのデータがあります。
これを考える 1 つの方法は、挿入と一般的なクエリの SQL を調べることです。たとえば、顧客が注文したときにどのテーブルと列が更新されるかなどです。そして、月次売上報告はどれですか? その情報はおそらく同じドキュメントに含まれているはずです。
つまり、クエリを簡素化するために、必要に応じて複製されたフィールドを持つ、顧客 ID と製品 ID を含む注文用の 1 つのドキュメントです。ドキュメント内のすべてのものを簡単にクエリできます。たとえば、Order と Customer の間で相互参照が必要な場合は、クライアントが実行する必要があります。したがって、地域別の売上に関するレポートが必要な場合は、地域コードを注文に入れる必要があります。
現在、明示的なデータ モデル (UML など) を行っていますか?
申し訳ありませんが、ドキュメント DB の前にあまり UML を行ったことはありません :)
ただし、どのフィールドがどのドキュメントに属し、どのような値が含まれているかを示す何らかのモデルが必要です。後で参照するためと、DB を使用するすべての人が規則を知っていることを確認するための両方です。たとえば、テキスト フィールドに日付を格納してもエラーが発生しなくなり、誰でも好きなフィールドを追加または削除できるため、検証コードと規則の両方が必要です。特に外部リソースを扱う場合。
RDBMS が提供する主要な追加サービスを見逃していませんか?
いいえ。しかし、私のバックグラウンドは Web アプリケーション開発者であり、必要な範囲でのみデータベースを扱います :)
私が働いていた会社は、複数のベンダーの SQL データベースで実行するように設計された製品 (Web アプリケーション) を作成しました。「追加サービス」は DB ごとに非常に異なるため、DB ごとに個別に実装する必要がありました。そのため、機能を RDBMS から移動する作業は簡単でした。これは全文検索にまで及びました。
ですから、私があきらめているものは、そもそも私が本当に持っていなかったものです. 明らかに、あなたの経験は異なるかもしれません。
警告: 私が現在取り組んでいるのは、財務データ、株価などの Web アプリケーションです。これはドキュメント DB に非常に適しています。私の観点からは、DB のすべての利点 (永続性とクエリ) を手間をかけずに得ることができます。
しかし、これらのデータは互いに独立しており、複雑なリレーショナル クエリはありません。ティッカーで最新の相場を取得し、ティッカーと日付範囲で相場を取得し、会社のメタ情報を取得します。これでほとんどすべてです。私が見たもう 1 つの例はブログ アプリケーションで、ブログは非常に複雑なデータベース スキーマによって特徴付けられることもありません。
私が言おうとしているのは、私が知っているドキュメント DB の成功したアプリケーションはすべて、そもそもあまり相互関係のないデータであったということです: ドキュメント (Google 検索のように)、ブログ投稿、ニュース記事、財務データなどです。 .
ドキュメント モデルよりも SQL に適切にマッピングされるデータセットがあると予想されるため、SQL は生き残ると思います。
しかし、単純な方法でデータを保存および取得したいだけの私たちにとっては (CouchDB のような) ドキュメント データベースは天の恵みです。