質問

最近、DBクエリでの結合によって処理速度が低下することについて多くのことを読んでいます。明らかに、Google App Engineはそれらを許可していません。

私は、人々が結合なしでアプリを設計する方法を疑問に思っています。たとえば、 contacts organizations を持つアプリを開発しています。連絡先は多くの組織に所属でき、組織は多くの連絡先を持つことができます。 2つのエンティティを接続する3番目のテーブルなしで、その関係をどのように実現できますか...

contacts --< contacts_organizations >-- organizations

GAEでは、多対多の関係を確立できないということですか?結合が必要な機能をそのまま残しますか?

各連絡先の組織IDのスペース区切りリストを含む contacts テーブルにTEXT organizations 列があると思います。それは少し奇妙に思えます。

役に立ちましたか?

解決

通常、データベースで結合が許可されていないということは、必ずしも1つのサーバーに収まらない非常に大きなデータベースのことです。最近の例は、 AmazonのSimpleDB MicrosoftのSQLデータサービス、および GoogleのApp Engineデータストア。制限された結合機能を提供するものもありますが、大きな困難は&quot; パーティションで結合することです。 &quot;。このような大規模なデータベースでは、データを同じサーバーに配置する必要がないようにデータをパーティション分割します。パーティション分割の正しい方法を決定する必要があります。

あなたの例では、組織のキーのリストを連絡先テーブルのフィールドに保存します。逆の場合も同様です。これらのデータベースの設計は、通常の正規化されたデータベースとは異なります。テーブルは通常「スパーステーブル」であり、これは基本的に各レコードが基本的に名前/値のペアであるフィールドをいくつでも持つことができることを意味します。 Amazonの製品表と、さまざまなタイプの製品に対していくつの異なるフィールドがあるかを考えてください。書籍にはページ数がありますが、MP3には期間があります。スパーステーブルでは、これらのレコードは同じテーブルに格納されます。

他のヒント

これは、アプリケーションコードでループを記述することでソフトウェアをスローダウンすることを主張するのと同じように、スローダウンソフトウェアに関連する神話です。

つまり、なぜループを書くのですか?同じコード行を何度も繰り返し実行するだけです!一度では足りませんでしたか?それは途方もない無駄です!

上記の記述は皮肉なものです。

私のポイントは、正しい答えを得るという目的のために、クエリに結合が含まれていることです。結合を非効率的または不必要に使用することは、ループ不変コードをループ内に配置するなど、設計が悪いことはもちろんです。

一般的なポリシーとしての結合の回避は、早期最適化の例です。効率的なコードを記述するためのアプローチがそのような包括的なルールを考え出すことである場合、結合を回避することは役に立ちません。


Google App Engineに関しては、エンティティ間の関係をサポートしますが、厳密にはリレーショナルデータベースモデルではないため、結合の概念は実際にはありません。代わりに、特定の参照から関連エンティティを取得できます。これは、モデルへのORMインターフェイスのようなもので、SQLの結合とは異なります。

ここで詳細を読むことができます: http://code.google.com/appengine/articles/modeling.html

(そのリンクはこのスレッドの別の回答にありましたが、削除されました)

重要な点:Googleは、ユーザーが「高額」を実行するのを防ぐために、データベースへのJOINを禁止していません。クエリ;データベースはリレーショナルではないため、「JOIN」はそもそもSQL動詞は実際には適用できません。

この方法では、BigTableは AmazonのSimpleDB と同じです-データは非正規化され、削除されますバケットに許可された任意のデータを含む巨大で効率的なハッシュテーブルを効率的に作成するためのスキーマ。

これらのハッシュテーブルは、特にリレーショナルデータベースと比較して、非常に簡単にスケーリングできます。 GAEなどのアプリケーションの場合、完全な機能セットよりも極端なスケーラビリティが優先されます。

db.ReferenceProperty を使用してオブジェクトをリンクします。 Google App Engine:詳細と例については、1対多の参加をご覧ください。

Googleはいくつかの計算量の多いメカニズムをリッピングしているので、他の種類のリソースをより多く利用する方法を探します。たとえば、CPUサイクルの代わりに参照テーブルを維持したり、テーブルをカウントしたりするハードディスク結合および集計計算。

それは不可能ではありません。その他の種類のリソースを使用して回避する必要があります。

各テーブルから結果を個別にフェッチし、それらを結合することにより、DBサーバーの代わりにアプリケーションで結合を実行できますが、ほとんどの結合では、複数のデータベースの往復の遅延のために速度が低下します1つではなく

しかし、正直なところ、結合はあなたの問題ではないということです。彼らがそうである時までには、この質問をする必要さえないでしょう。指(主にEbay)でこの時点に到達する実際のプロジェクトの数を数えることができ、これらのプロジェクトをスケーリングするための唯一の方法は、結合を完全に削除することだけであったという証拠はありません。

あなたが言及するデータベースは、せいぜい、複数のサーバーにわたって非常に大量のデータを格納するように設計されたバージョン付きレコードストアです。それらを「データベース」と呼ぶのはストレッチです。結合、ACIDトランザクション、ロールバックなどはサポートしていません。これらを使用せずにアプリケーションを作成できますが、多くの場合、機能を提供するためにさらに作業が必要になります。

For:

contacts --< contacts_organizations >-- organizations

連絡先や組織の連絡先に組織を非正規化して保存できます。ただし、両方のテーブルの同時更新を処理するアプリケーションでは、参照整合性を強制する必要があります。

より良い解決策は、データを3つのテーブルに保存し、自分で「結合」することです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top