データ指向アプリケーションデザイン
- データシステムについて考えるための有益な方法を見出す
- 主にアーキテクチャについてみていく
1章 信頼性、スケーラビリティ、メンテナンス性に優れたアプリケーション
-
回復可能なフォールトを扱う
-
ヒューマンエラーもフォールト
- エラーの可能性が最小になるようにシステムを設計する
- リカバリ可能にしておく
- メトリクス・テレメトリする
-
スケーラビリティ
- ex. twitter
-
- globalなコレクションをユーザーが読み取る
-
- tweetする時に各ユーザー毎のキャッシュに追加する
-
- ex. twitter
-
パフォーマンス
- 平均
- パーセンタイル
- SLAに分類されがち
- 中央値=50パーセンタイル=p50
- p99, p999(99.9%ile)
- 計測
- 全ウインドウのレスポンスタイムを保持がナイーブな実装
- forward decay, t-digest, HdrHistgram
- elastic: 負荷を検知してリソース追加
- 全てのケースに対応できる魔法のスケーリングアーキテクチャはない
-
メンテンナンス性
- 単純さ: 複雑さの管理
- 抽象化: 偶発的な複雑さを取り除く手段
- 進化性: 変更への配慮
- 単純さ: 複雑さの管理
2章 データモデルとクエリ言語
-
ウィトゲンシュタイン
- 私の言語の限界は私の世界の限界を意味する
-
1つのデータモデルをマスターするのも大変
- ex. RDBの本がたくさんある
-
2.1 リレーショナルモデルとドキュメントモデル
- リレーショナルモデルの代替としてネットワークモデルや階層モデルが出たが流行らなかった
- 2.1.1 NoSQLの誕生
- 2.1.2 オブジェクトとリレーショナルのミスマッチ
- モデル間の断絶があり、変換コードが必要になる
- インピーダンスミスマッチという
- リレーションがない閉じているデータはJSONとして保存するのが適している
- モデル間の断絶があり、変換コードが必要になる
- 2.1.3 N:1, 1:N
- IDはユーザーにとって意味がないので変更しないときに使う
- docDBはjoinサポートしないのでapp側で複数回クエリ投げる
- 2.1.4 docDBは歴史を繰り返すのか?
- No, docにも参照があるので
- 2.1.5 今日のrDBとdocDB
- N:NはdocDBには向かない, 関係が強いならgraphDBがベスト
- docDBは動的型, rDBは静的型としてアナロジー出来る
- スキーマレス △, スキーマオンライト + スキーマオンリード
- 新しいカラムもマイグレーション不要
- 局所性は活かせるのはdocDBだけではない
- ex. Spannerのインターリーブ
- 行を親のテーブルでネストできる(?)
- ex. Oracle マルチテーブルインデックスクラスタテーブル
- ex. BigTable カラムファミリー
- ex. Spannerのインターリーブ
-
2.2 データのためのクエリ言語
- SQLは宣言的
- CSSも, 宣言的な方が命令的より優れている
- 関係代数
sharks = sigma_{family = sharks}(animals)
- 2.2.2 MapReduceでのクエリ
- MongoDBやCouchDBは限定的にサポートしている
- 10章 バッチ処理 で詳しく
- MongoDBやCouchDBは限定的にサポートしている
- SQLは宣言的
-
ex. 毎月見かけたサメの数
db.observations.mapReduce(
function map() {
emit(`${year}-${month}`, this.numAnimals)
},
function reduce(ley, values) {
return Array.sum(values)
},
{
query: { family: "Sharks" },
out: "monthlySharkReport"
}
)- MongoDB 2.2でaggregation pipelineがサポートされた
[
{ "$match": { family: "Sharks" } },
{ "$group": {
"_id": {
"year": { "$year": "$observationTimestamp" },
"month": { "$month": "$observationTimestamp" }
},
totalAnimals: { "$sum": "$numAnimals" }
} }
]- 2.3 グラフ型のデータモデル
- 2.3.1 プロパティグラフ
- 頂点
- id, outgoings, ingoings, key value map
- 辺
- id, 始点, 終点, 関係の種類のラベル, key value map
- 頂点
- 2.3.2 Cypherクエリ言語
- Neo4j用
- 2つの頂点から探索すると早い
- 任意回数の辺を辿るが
:WITHIN*0..でかけるがSQLだと困難が伴うWITH RECURSIVE文がある
- 2.3.1 プロパティグラフ
-- アメリカからヨーロッパに移住した人を探すクエリ
MATCH
(person) -[:BORN_IN]-> () -[:WITHIN*0..]-> (us:Location {name:'United States'}),
(person) -[:LIVES_IN]-> () -[:WITHIN*0..]-> (eu:Location {name:'Europe'}),
RETURN person.name- .
- 2.3.4 トリプルストアとSPARQL
- 2.3.5 礎となったもの: Datalog
- Prologのサブセット
- egglog入門
- これか
- ex. Datomic, Cascalog
- S式で書く
predicate(subject, object)と書く