データベースの質問:単純なリレーショナル テーブルを非リレーショナル テーブルに変更しますか?
-
06-09-2019 - |
質問
MySQL データベース上で実行されている Web アプリケーションがあります (開発中)。アプリケーションを Google App Engine に移行することを検討しており、単純なリレーショナル データベース モデルを非リレーショナル アプローチにどのように変換できるかをより深く理解したいと考えています。
私は長年リレーショナル データベースに携わってきましたが、BigTable などの列ベースの DB の経験はありません。Google もリレーショナル データベースの小規模な展開をサポートしている場合に備えて、私の質問は一般的なものであり、Google に固有のものではないことを述べておきたいと思います。単純なリレーショナル モデルを非リレーショナル DB でどのように表現できるかを理解したいのです。
私のデータベース(簡略化)は次のとおりです。
Items Table
------------
ItemID ItemName ItemPriority
1 "Car" 7
2 "Table" 2
3 "Desk" 7
ItemProperties Table
---------------------
ItemID Property Importance
1 "Blue" 1
1 "Four Wheels" 2
1 "Sedan" 0
2 "Rectangular" 1
2 "One Leg" 1
アイテムがたくさんあり、それぞれに名前と ID が付いています。各項目には複数のプロパティがあり、各プロパティには複数のパラメーターがあります (各プロパティの名前と「重要性」のみを述べましたが、他にもあります)。私には数千万のアイテムがあり、それぞれに数百のプロパティがあります。
使用シナリオ:ItemName を入力として受け取り、items テーブルでその ID を検索し、その ID ですべてのプロパティを取得します。次に、(メモリ内にある) プロパティのリストに対して分析を実行し、結果を返します。
作業の 90% はパラメータに基づく検索であり、これが (私の理解が正しければ) 非リレーショナル DB の問題点です。
推奨されるアプローチは何ですか?
解決
あなたの二つの表は、非リレーショナルDBに翻訳することは本当に簡単にする必要があり、しばらくの間、非リレーショナルDBの者と協力してきた人から。
2つのテーブルを取り、1つのオブジェクトにそれらを回します。
アイテム: - イド - 名前 - プロパティ - PROP1 - PROP2
あなたのデータ・ストアの列(ビッグ表)、ドキュメント(CouchDBの)、または任意の他それが使用中で全体を保管します。
あなたはID、名前、またはプロパティのいずれかによってアイテムを検索することができます。何の非リレーショナルDBの大きな痛みのポイントの一つである加入はありません。私はあなたがそれで何を意味するか理解していないよない限り、パラメータのルックアップは、本当に痛みのポイントではありません。あなたは問題ではないとそれがないRDBMSよりもずっといいスケールの複数のルックアップが、ほとんどの時間を行う必要があります。
あなたの例では、私は実際には非リレーショナルモデルは単純で実装し、理解しやすいと考えてます。
各非リレーショナルデータストアは、それが難しい一般的な意味でのガイダンスを与えていますけれども異なる規則や制約を持つ。 CouchDBのは、例えば、それの見解を持つオブジェクトの任意の部分にインデックスを作成することができます。 BigTableのを使用すると、高速なインデックス付き検索を取得するために非正規化データの複数のコピーを保存する必要があります。他の人はあなたがデータを格納する方法を決定する際に考慮すべき別のものを持っています。あなたはSQLの世界を離れると分化のかなり多くはそこにあります。
他のヒント
GQL は結合をサポートしていません。これは次の 2 つの方法で回避できます。
- 自分で参加してください
項目を取得し、その項目 ID を確認し、その項目 ID で項目プロパティをクエリするだけです。テーブルは指定したとおりに表示されます。確かに、これは 2 つのクエリですが、2 つのクエリは単純です。
- Expando モデルを使用する
Expando モデルでは、実行時に新しいフィールドを作成できます。これらはインデックス付けされないため、検索する場合は遅くなる可能性がありますが、単に取得するだけであれば問題ありません。ListProperty のような複合型も使用できます。この種の柔軟性により、ItemProperties テーブルのすべてを Items テーブルに配置し、クエリを保存する方法を考えることができるかもしれません。クリエイティブに。
私は非常によく似たデータベース構造を持っており (「records」テーブルと「recordEntries」テーブルはあなたの「items」と「itemProperties」を反映しています)、非リレーショナル データベースへの同様の移行を検討しています。おそらく Google ではなく、CouchDB や memcachedb などを使用することになるでしょう。
あなたと同じように、私も非リレーショナル データベースを扱った経験がありません (開発者も同様です)。ただし、いくつかのアイデアを検討しました。私たちの現在の考えは(あなたのスキーマを使用して)次のとおりです。
- 初め:各アイテムとそのアイテムのプロパティをフィールドを含む 1 つのオブジェクト (本質的には XML ドキュメント) に折りたたみ、識別子をキーとしてデータベースに詰め込みます。アイテムを取得するたびに、すべての itemProperties も返されます。
違いは、コンテンツのインデックスをデータベースの外部 (Solr を使用) に作成するため、「name」プロパティ、つまり YMMV を使用してデータベース自体の検索を行う必要がないことに注意してください。
- 2番目:上記のモデルではサポートできない、実行中のすべての「リレーショナル」操作のリストを作成しています。これには、項目テーブルの特別なフィールドに基づいて項目をクエリするいくつかの「グループ化」操作と、最近変更されたすべての項目の検出を試みるクエリ (以前は、日付列に対するクエリによって実行されていました) が含まれます。アイテムテーブル)。私たちは、これらのそれぞれのケースに対応する代替実装を考案中です (幸いなことに、その数はわずかです)。
これが難しすぎることが判明した場合は、別のモデルで同じ演習を試みます。幸いなことに、計画を立てる時間はあります。
私たちにとって重要なポイントの 1 つは、すべてのインデックス付けを Solr を使用して外部で実行しているため、(たとえば) itemProperties 値の値に対してデータベース検索を行ったり、item テーブルで名前による検索を行う必要がないことです。
とにかく、それはおそらくあまり役に立たないかもしれませんが、より経験豊富な人々がどのような種類の解決策を考え出すことができるかを熱心に見ていきたいと思います。
追伸:プロパティテーブルには数十億の行があるはずだと推測します。MySQL サーバーは正確にいくつ、またどのハードウェアで実行されていますか?MySQL でスケーラビリティの問題がまだ発生していますか?
あなたはそれをすべてをフラット化する必要がある、私はAppEngineのは、
のような構造を可能にすると思いますID = 1、ItemNameの=車、ItemPriority = 7、施設=(青、1)、施設=(四輪、2)、施設=(セダン、0) ID = 2、ItemNameの=表、ItemPriority = 2、プロパティ=(長方形、1)、施設=(片足、1) ID = 3、ItemNameの=デスク、ItemPriority = 7
同じ「フィールド」は、複数の値を持つことができること、そしてあなたがそれに複数のアイテムを使用できることに注意してください。
あなたのサンプルデータを1つのテーブルに3行になります。