4: 2015-07-13 (月) 06:40:05 njf |
5: 2015-07-14 (火) 10:19:20 njf |
| *GAEのデータ保存 [#v7706534] | | *GAEのデータ保存 [#v7706534] |
| | | |
- | GAEではデータはBigtableというものに保存されます。通常のリレーショナルデータベースに似ていますが、集計や表の結合などは自分でスクリプトを書かないと基本的には出来ません。1レコードごとに検索のためのキーがついているだけのデータの集まりの様な物で、どちらかというとファイルに近いかも知れません。公式ではリレーショナルデータベースと区別するためか1データの事をエンティティと呼んでいます。リレーショナルデータベースに慣れている人には分かりづらいと思うので、このWikiでは基本的にデータはレコードと呼んでいます。他の資料に当たるときには注意してください。 | + | GAEではデータはBigtableというものに保存されます。通常のリレーショナルデータベースに似ていますが、集計や表の結合などは自分でスクリプトを書かないと基本的には出来ません。1レコードごとに検索のためのキーがついているだけのデータの集まりの様な物で、どちらかというとファイルに近いかも知れません。公式ではリレーショナルデータベースと区別するためか1データの事をエンティティと呼んでいます。また、テーブル定義に当たる物はモデルと呼びます。リレーショナルデータベースに慣れている人には分かりづらいと思うので、このWikiでは基本的に1データはレコードと呼んでいます。モデルもテーブルと呼ぶかも知れません。他の資料に当たるときには注意してください。 |
| | | |
| カジュアルゲームのデータ保存の場合、集計や表結合は普通無いのであまり問題ないと思います。しかし、ランキングだけはちょっと面倒です。これについては別途機会を設けて解説する予定です。 | | カジュアルゲームのデータ保存の場合、集計や表結合は普通無いのであまり問題ないと思います。しかし、ランキングだけはちょっと面倒です。これについては別途機会を設けて解説する予定です。 |
| また、GAEはデータの排他処理があまり得意ではありません。同時に1つのデータに大量にアクセスするような、たとえばアクセスカウンターのような物だとエラーが出る場合があります。これを回避する方法もまた別途解説する予定です。ただ、こちらもカジュアルゲームではそれほど使わないと思うのでさほど問題では無いでしょう。 | | また、GAEはデータの排他処理があまり得意ではありません。同時に1つのデータに大量にアクセスするような、たとえばアクセスカウンターのような物だとエラーが出る場合があります。これを回避する方法もまた別途解説する予定です。ただ、こちらもカジュアルゲームではそれほど使わないと思うのでさほど問題では無いでしょう。 |
| | | |
- | 一方、リレーショナルデータベースと違って、後からテーブルの列を加えたりするのは簡単にできます。また、データが分散されていて互いにバックアップされているので、サーバーの不具合でテーブルまるごと消えたりすることはまずありません。テーブルのサイズにも制限はありません。 | + | 一方、リレーショナルデータベースと違って、後からテーブルの列を加えたりするのは簡単にできます。また、データが分散されていて互いにバックアップされているので、サーバーの不具合でテーブルまるごと消えたりすることはまずありません。テーブルのサイズにも制限はありません。このあたりが1データがあたかもファイル的に扱われている所です。 |
| + | |
| + | では、テーブル定義にあたるモデルの定義を見てみましょう。ユーザーIDとパスワードとユーザーデータを保存するためのモデルは以下のようになります。 |
| + | |
| + | from google.appengine.ext import ndb |
| + | |
| + | class UserData(ndb.Model): |
| + | userId = ndb.IntegerProperty() |
| + | password = ndb.IntegerProperty() |
| + | data = ndb.JsonProperty() |
| + | |
| + | これでユーザーIDとパスワードが整数、dataがJSONであるようなモデルとなります。 |
| + | どんな型が使えるかはGAEのリファレンスで調べられます。 |
| + | ( |
| + | https://cloud.google.com/appengine/docs/python/ndb/properties |
| + | ) |
| + | よく使うのは上記の整数とJson型、あとは以下の日付とString型ぐらいです。 |
| + | |
| + | ndb.DateTimeProperty() |
| + | ndb.StringProperty() |
| + | |
| + | 使い方は、保存はインスタンス化して値を設定してputするだけです。 |
| + | |
| + | userData = UserData() #インスタンス作成 |
| + | userData.userId = 1 |
| + | userData.password = 12345 |
| + | userData.data = jsonData |
| + | userData.put() #保存 |
| + | |
| + | 読み出しはいろいろな方法がありますが、IDが1のものを1つだけ取り出すなら、 |
| + | |
| + | userDatas = UserData.query(UserData.userId==1).fetch(1) |
| + | |
| + | とすると長さ最大1のUserData型の配列として取り出せます。 |
| + | |
| + | 集計や結合などをしないなら、ほぼ通常のリレーショナルデータベースと同じです。 |
| + | |
| + | 以前にも書きましたが、GAEでは1レコード取り出す毎に課金されます。また、取り出すレコードの数が多いとパフォーマンスも悪くなります。なるべく少ないレコード数で処理が終わるように、正規化などはせず少々重複があっても1レコードにデータを多く詰め込んだ方が良いです。そのようなことを踏まえてデータ設計を行いましょう。 |
| + | |
| + | *データモデル [#g6b90e90] |
| | | |
| 準備中 | | 準備中 |