質問

一例として、Google App Engine はデータの保存に標準データベースではなく Google Datastore を使用します。データベースの代わりに Google Datastore を使用するためのヒントを持っている人はいますか?私はテーブル構造に直接マッピングされるオブジェクトの関係を 100% 考えるように心を訓練してきたようで、今では何か違う見方をするのは難しくなりました。Google Datastore の利点のいくつかは理解できます (例:パフォーマンスとデータを分散する機能)が、いくつかの優れたデータベース機能が犠牲になります(例:結合します)。

Google Datastore または BigTable を使用したことがある方で、それらを使用する上で何か良いアドバイスはありますか?

役に立ちましたか?

解決

「従来の」リレーショナル データベースと比較した場合、App Engine データストアについて慣れる必要がある主な点は 2 つあります。

  • データストアでは、挿入と更新が区別されません。エンティティに対して put() を呼び出すと、そのエンティティは一意のキーとともにデータストアに保存され、そのキーを持つものはすべて上書きされます。基本的に、データストア内の各エンティティの種類は、巨大なマップまたは並べ替えられたリストのように機能します。
  • あなたがほのめかしたように、クエリははるかに制限されています。まず、結合はありません。

理解すべき重要な点、およびこれらの違いの背後にある理由は、Bigtable は基本的に巨大な順序付き辞書のように機能するということです。したがって、put 操作は、そのキーの以前の値に関係なく、指定されたキーの値を設定するだけであり、フェッチ操作は、単一のキーまたはキーの連続範囲のフェッチに限定されます。インデックスを使用すると、より高度なクエリが可能になります。インデックスは基本的に単なる独自のテーブルであり、連続した範囲のスキャンとしてより複雑なクエリを実装できます。

これを理解すると、データストアの機能と制限を理解するために必要な基本的な知識が得られます。恣意的に見えるかもしれない制限は、おそらくより意味のあるものです。

ここで重要なことは、これらはリレーショナル データベースで実行できることに対する制限ではありますが、これらの同じ制限によって、Bigtable が処理できるように設計されている規模までスケールアップすることが実際的に可能になるということです。紙の上ではうまく見えても、SQL データベースでは恐ろしく遅いクエリを実行することはできません。

データの表現方法を変更する方法に関して、最も重要なことは事前計算です。クエリ時に結合を行う代わりに、可能な限りデータを事前計算してデータストアに保存します。ランダムなレコードを選択する場合は、乱数を生成し、それを各レコードとともに保存します。 この種のヒントやコツをまとめたクックブックがあります ここ 編集:その料理本はもう存在しません。

他のヒント

私がマインドスイッチに取り組んできた方法は、データベースのことを完全に忘れることです。

リレーショナル DB の世界では、データの正規化とテーブル構造について常に心配する必要があります。すべて捨ててください。Web ページをレイアウトするだけです。全部並べてみましょう。さあ、見てください。すでに 2/3 に到達しています。

データベースのサイズが重要であり、データは複製されるべきではないという概念を忘れてしまった場合は、コードを記述する必要すらなくなりました。あなたの意見に基づいてモデルを決定しましょう。リレーショナルの世界のように、オブジェクトを 2 次元にする必要はもうありません。オブジェクトを形状とともに保存できるようになりました。

はい、これは試練の簡単な説明ですが、データベースのことを忘れて、ただアプリケーションを作成するのに役立ちました。私はこの哲学を使用してこれまでに 4 つの App Engine アプリを作成しましたが、今後さらに多くの App Engine アプリが作成される予定です。

人々が次のようなことをカミングアウトするとき、私はいつも笑ってしまいます - それは関係性ではありません。私は django で cellectr を作成しました。以下にモデルのスニペットを示します。ご覧のとおり、ユーザーによって管理または指導されるリーグがあります。リーグからすべてのマネージャーを取得したり、特定のユーザーからそのユーザーがコーチまたはマネージャーを務めているリーグを返すことができます。

特定の外部キーがサポートされていないからといって、リレーションシップを含むデータベース モデルを使用できないというわけではありません。

私の2ペンス。


class League(BaseModel):
    name = db.StringProperty()    
    managers = db.ListProperty(db.Key) #all the users who can view/edit this league
    coaches = db.ListProperty(db.Key) #all the users who are able to view this league

    def get_managers(self):
        # This returns the models themselves, not just the keys that are stored in teams
        return UserPrefs.get(self.managers)

    def get_coaches(self):
        # This returns the models themselves, not just the keys that are stored in teams
        return UserPrefs.get(self.coaches)      

    def __str__(self):
        return self.name

    # Need to delete all the associated games, teams and players
    def delete(self):
        for player in self.leagues_players:
            player.delete()
        for game in self.leagues_games:
            game.delete()
        for team in self.leagues_teams:
            team.delete()            
        super(League, self).delete()

class UserPrefs(db.Model):
    user = db.UserProperty()
    league_ref = db.ReferenceProperty(reference_class=League,
                            collection_name='users') #league the users are managing

    def __str__(self):
        return self.user.nickname

    # many-to-many relationship, a user can coach many leagues, a league can be
    # coached by many users
    @property
    def managing(self):
        return League.gql('WHERE managers = :1', self.key())

    @property
    def coaching(self):
        return League.gql('WHERE coaches = :1', self.key())

    # remove all references to me when I'm deleted
    def delete(self):
        for manager in self.managing:
            manager.managers.remove(self.key())
            manager.put()
        for coach in self.managing:
            coach.coaches.remove(self.key())
            coaches.put()            
        super(UserPrefs, self).delete()    

私はリレーショナル データベースの世界から来て、このデータストアというものを見つけました。コツを掴むまでに数日かかりました。まあ、私の発見がいくつかあります。

データストアはスケールに合わせて構築されており、それが RDMBS との違いであることはすでにご存知のはずです。大規模なデータセットでより適切にスケーリングするために、App Engine にはいくつかの変更が加えられました (一部の変更は多くの変更を意味します)。

RDBMS VS データストア
構造
データベースでは通常、データストアにあるテーブル、行でデータを構造化します。 種類とエンティティ.

関係
RDBMS では、ほとんどの人は 1 対 1、多対 1、多対多の関係に従います。データストアでは、「結合なし」であるため、それでも「」を使用して正規化を実現できます。参照プロパティ「例: 1 対 1 の関係の例 .

インデックス
通常、RDMBS では、検索を高速化し、データベースのパフォーマンスを向上させるために、主キー、外部キー、一意キー、インデックス キーなどのインデックスを作成します。データストアでは、種類ごとに少なくとも 1 つのインデックスを作成する必要があります (自動的に作成されます)。 生成する 好むと好まざるにかかわらず) データストアはこれらのインデックスに基づいてエンティティを検索するため、これが最良の部分であると信じています。RDBMS では、インデックス以外のフィールドを使用して検索することができますが、多少時間はかかりますが、確実に実行されます。Datastore では、インデックス以外のプロパティを使用して検索することはできません。

カウント
RDMBS ではカウントするのがはるかに簡単です(*) が、データストアでは、カウント機能があるため、普通に考えないでください(そう、カウント関数があります)。 1000制限 そしてそれは同じくらいの費用がかかります 小さな操作 良くはないが、常に良い選択肢があるエンティティとして、次のように使用できます。 シャードカウンター.

固有の制約
RDMBS では、この機能が大好きですよね?ただし、Datastore には独自の方法があります。プロパティを一意として定義することはできません:(。

クエリ
GAE Datatore はより優れた機能を提供します のように(なんてこった!データストアには LIKE キーワードがありません) SQL GQL.

データの挿入/更新/削除/選択
これは私たち全員が関心のあるところです。RDMBMS と同じように、RDMBBS では挿入、更新、削除、選択に 1 つのクエリが必要です。データストアは put、delete、get を実行します (あまり興奮しないでください)。 書き込み、読み取り、小規模な操作(読む データストア呼び出しのコスト) そこでデータ モデリングが活躍します。これらの操作を最小限に抑え、アプリを実行し続ける必要があります。低減用 読み取り動作 使用できます メムキャッシュ.

Objectify のドキュメントを参照してください。ページの下部にある最初のコメントには次のように書かれています。

「なるほど、これは Objectify について説明するために書かれたものですが、これは私が今まで読んだ Appengine データストア自体についての最も簡潔な説明の 1 つでもあります。ありがとう。"

https://github.com/objectify/objectify/wiki/Concepts

ORM マップされたエンティティについて考えることに慣れている場合は、基本的に、Google の App Engine のようなエンティティベースのデータストアがどのように機能するかがわかります。結合のようなものについては、次のように見ることができます 参照プロパティ. 。バックエンドは GQL および Datastore API インターフェイスによって抽象化されているため、バックエンドに BigTable を使用するか他のものを使用するかを実際に気にする必要はありません。

私のデータストアの見方は、種類はテーブルそのものを識別し、エンティティはテーブル内の個々の行です。Google が構造を持たない単なる 1 つの大きなテーブルよりも優れたものを削除した場合、エンティティに必要なものを何でもダンプできます。言い換えれば、エンティティが種類に関連付けられていない場合は、エンティティに任意の構造を持たせて 1 つの場所に保存できます (構造を持たない大きなファイルのようなもので、各行が独自の構造を持ちます)。

元のコメントに戻りますが、Google データストアと bigtable は 2 つの異なるものであるため、Google データストアとデータストアのデータ ストレージの意味を混同しないでください。Bigtable は bigquery よりも高価です (これを採用しなかった主な理由)。BigQuery には SQL 言語のような適切な結合と RDBMS があり、その方が安価なので、bigquery を使用しない手はありません。そうは言っても、bigquery にはいくつかの制限があり、データのサイズに応じて、制限が発生するかどうかが決まります。

また、データストアの観点から考えるという点では、「NoSQL データベースの観点から考える」というのが適切な表現だったと思います。最近では利用できるものが多すぎますが、Google 製品に関して言えば、Google Cloud SQL (mySQL) を除いて、その他はすべて NoSQL です。

データベースの世界に根ざしている私にとって、データ ストアは巨大なテーブルです (したがって、「bigtable」という名前が付けられています)。ただし、BigTable は悪い例です。なぜなら、BigTable は、典型的なデータベースが実行しない可能性のある他の多くのことを実行しますが、それでもデータベースであることに変わりはありません。Google の「bigtable」のようなものを構築する必要があることがわかっていない限り、おそらく標準のデータベースで問題ないでしょう。彼らは、膨大な量のデータとシステムを一緒に処理しているため、これが必要であり、市販のシステムでは、実際にジョブを実行する必要があることを実証できる正確な方法でジョブを実行することはできません。

(重要な参考文献: http://en.wikipedia.org/wiki/BigTable)

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