データベースではなくデータストアをどのように考えるのですか?


183

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

Google DatastoreまたはBigTableを使用した経験のある人が、それらを使用するのに役立つアドバイスはありますか?


DataSourceは古いAPIであり、徐々に削除されています-データベース接続モデルと非常に密接に関連していた。DataStoreは、低レベルのAPIであり、FeatureReadersとFeatureWriterを使用して、GISコンテンツへの「生の」ストリーミングベースのアプローチにアクセスできます。
murali

現在、Google Cloud SQLは、Google App Engineにリレーショナルデータベースサポートを提供しています。それでもデータストアのソリューションを探している場合は、Google Cloud SQLを使用できます
チャンダナ

Mungo Datastore APIをチェックアウトすることをお勧めします:bit.ly/13eSDpr
クォーク

回答:


149

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

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

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

これを吸収すると、データストアの機能と制限を理解するために必要な基本的な知識が身に付きます。恣意的に思われたかもしれない制限は、おそらくもっと理にかなっています。

ここで重要なことは、これらはリレーショナルデータベースで実行できることに対する制限ですが、これらの同じ制限により、Bigtableが処理するように設計された規模にスケールアップすることが現実的になります。紙の上では見た目は良いが、SQLデータベースではひどく遅いクエリを実行することはできません。

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


4
朗報です。インターネットはクックブックについて忘れていません。つまり、インターネットアーカイブは忘れられていません。サイトのゴーストはまだここに存在します:web.archive.org/web/20090416113704/http
//…

42

私がマインドスイッチについて行ってきた方法は、データベースを完全に忘れることです。

リレーショナルデータベースの世界では、常にデータの正規化とテーブル構造について心配する必要があります。それをすべて捨てます。Webページをレイアウトするだけです。それらをすべて置きます。今それらを見てください。すでに2/3あります。

データベースのサイズが重要であり、データを複製してはならないという概念を忘れた場合は、3/4になり、コードを記述する必要もありませんでした。ビューにモデルを指示させます。リレーショナルの世界のように、オブジェクトを取得して2次元にする必要はもうありません。形状のあるオブジェクトを保存できます。

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


2
私は「あなたの見解があなたのモデルを決定するようにさせなさい」が好きです。ビット。これはRDBMSからのハングアップだと思いますが、すべてが単純化されます。
cbednarski

23

人々が出てくるときはいつも私は笑います-それは関係ではありません。私はジャンゴで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()    

12

Relational Databaseの世界から来たのですが、このDatastoreのものが見つかりました。それに慣れるまでに数日かかりました。よく私の発見のいくつかがあります。

Datastoreはスケーリングに合わせて構築されており、それがRDMBSから分離されていることをすでに知っている必要があります。大きなデータセットでより適切にスケーリングするために、App Engineはいくつかの変更を加えました(一部は大幅な変更を意味します)。

RDBMS VS DataStoreの
構造
データベースでは、通常、データをTablesで構造化します。Datastoreにある行は、種類とエンティティになります。

関係
でRDBMSは、人々のほとんどは、1対1、多対1、多対多の関係では、データストアは、それが持っていたようなものを「いいえ結合」が、それでも私たちは、「使用して、当社の正規化を達成することができfolllows ReferencePropertyを "たとえば、1対1の関係の例

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

カウント
でRDMBSを、(*)カウントする方がはるかに簡単ですが、データストアに、それが持っている(うんカウント機能がある)通常の方法でそれを考えても、いけないしてください1000年の制限をして、それは限り費用がかかります小さなopertionどのエンティティとして良い方法ではありませんが、常に適切な選択肢があります。シャードカウンターを使用できます。


RDMBSの一意の制約この機能は気に入っていますか?しかし、データストアには独自の方法があります。プロパティを一意の:(として定義することはできません。

クエリ
GAE Datatoreは、より良い機能もはるか提供LIKE(あーもう!データストアがLIKEキーワードを持っていない)であるSQL GQLを

データの挿入/更新/削除/選択
これは私たち全員が関心を持っている場所です。RDMBSでは、RDBMSと同じように、挿入、更新、削除、選択に対して1つのクエリが必要です。置くかという点で取得書き込み、読み出し、小オペレーション(読み取りデータストアのコールのコスト)とのthatsデータモデリングは、行動に出番。これらの操作を最小限に抑え、アプリを実行し続ける必要があります。読み取り操作を削減するには、Memcacheを使用できます。



3

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


1
参照プロパティの1つの問題は、1 + Nクエリの問題をすばやく作成できることです。(100人を見つけるために1つのクエリをプルし、次にperson.addressを取得するためにそれらのそれぞれに対して別のクエリを作成します。)
0124816

おそらくJavaサポートの追加により、「参照プロパティ」へのリンクが壊れています。試してみてください:code.google.com/appengine/docs/python/datastore/...
Spike0xff

リンクが修正されました。十分な担当者がいる場合は、自由に回答を編集してください。
Mark Cidade、

0

データストアの見方は、種類はテーブル自体を識別し、エンティティはテーブル内の個々の行です。グーグルが構造を持たないその1つの大きなテーブルよりも親切である場合、エンティティに必要なものをすべてダンプできます。つまり、エンティティが種類に関連付けられていない場合、エンティティの構造を1か所に保存できます(構造のない大きなファイルのようなもので、各行は独自の構造を持っています)。

元のコメントに戻りますが、google datastoreとbigtableは2つの異なるものであるため、google datastoreとdatastore data storageの意味を混同しないでください。Bigtableはbigqueryよりも費用がかかります(主にそれを採用しなかった理由)。Bigqueryには適切な結合があり、RDBMSはSQL言語のように安価であるので、bigqueryを使用しないでください。そうは言っても、bigqueryには、データのサイズによっては、遭遇する場合と遭遇しない場合とがありますが、いくつかの制限があります。

また、データストアの観点から考えると、適切なステートメントは「NoSQLデータベースの観点から考えている」と思います。最近は多くのものが利用可能ですが、Google Cloud SQL(mySQL)以外のGoogle製品に関しては、その他はすべてNoSQLです。


-6

データベースの世界に根ざしている私にとってのデータストアは、巨大なテーブル(したがって、「bigtable」という名前)になります。BigTableは、典型的なデータベースではできない他の多くのことを行うため、悪い例ですが、それでもデータベースです。Googleの「bigtable」のようなものを構築する必要があることを知らない限り、おそらく標準データベースで問題ないでしょう。めちゃくちゃな量のデータとシステムを一緒に処理しているため、彼らはそれを必要としています。商業的に利用可能なシステムは、実際に仕事をする必要があることを示すことができる正確な方法で仕事を行うことができません。

(bigtable参照:http : //en.wikipedia.org/wiki/BigTable


質問は特にBigtableを使用するGoogle App Engineに関連しています。リレーショナルデータベースの使用はオプションではありません。
ニックジョンソン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.