More Related Content Similar to BPStudy32 CouchDB 再入門 (20) More from Yohei Sasaki (18) BPStudy32 CouchDB 再入門2. 自己紹介 Yohei Sasaki (yssk22) developerWorks のCouchDB連載記事 CouchDB基礎文法最速マスター CouchDB-JP People on the Couch: UTC+9 今年から某ECサイトの開発 3. はじめに / お願い 質問は随時... というのは大変なのでハッシュタグ #bpstudyを添えてつぶやいてください。 つぶやきに 半角?または全角? をいれていただければ回答します。 ハンズオン用URL http://bit.ly/6rXbn5 14. 例:請求書 請求元: hogehoge株式会社 請求先: 郵便番号: 123-4567 住所: 神奈川県川崎市... 氏名: 佐々木庸平 請求金額: 2,345 明細: 商品数量金額小計AAAA 1 1,980 1,980 BBBB 3 1,210 3,630 ... CouchDBにおける1つの保存単位- ドキュメント 15. 例:請求書 (RDBの場合) 請求元: 1 請求先: 3 請求金額: SUM(小計) 明細 商品数量金額小計1 1 1.P 1 * 1.P 2 3 2.P 3 * 2.P 1, hogehoge株式会社 3, 123-4567, 神奈川県..., 佐々木庸平 10, 1, 1 1, AAAA, 1,980 10, 2, 3 2, BBBB, 1,210 正規化!正規化!正規化! 23. ドキュメント指向的アプローチ 請求元: hogehoge株式会社 請求先: 郵便番号: 123-4567 住所: 神奈川県川崎市... 氏名: 佐々木庸平 請求金額: 2,345 明細: 商品数量金額小計AAAA 1 1,980 1,980 BBBB 3 1,210 3,630 ... hogehoge株式会社 佐々木庸平 AAAA, 1,980 BBBB, 1,210 台帳から書き写す、という事務処理 32. 通勤経路の稼働率 稼働率 24min/30min : 80% 具体的なサービスの例: gmail, google reader, twitter, hatena.ne.jp, ... サービス提供側としては100%を目指しているのを十分承知しているものの... 34. ここまでのまとめ CouchDB = Relax 当たり前のことを当たり前に。 データモデルに対するアプローチ ドキュメント指向 スケールに対するアプローチ スケールダウン レプリケーション 36. CouchDBの使い方 HTTP で使う 使い方 = Web で当たり前の使い方 GET : ドキュメントを取得する POST : ドキュメントを作成する PUT : ドキュメントを更新する DELETE : ドキュメントを削除する Web の常識をしっていれば、どの言語/ランタイムでもCouchDBは簡単 「Webを支える技術」参照 38. Futon による確認 GUI Tool http://localhost:5984/_utils/ Firefox + Firebug を使うのがbetter デモ 40. HTTP API 一覧 後でリファレンス的に利用できるようにSphinx Document にまとめみました http://bit.ly/b008oP HTTPメソッドは省略 慣習に従えばよいので。 XXを実行する 系はPOST ハンズオンで curl を使って試します。 41. HTTP Header も活用しよう Request X-Couch-Full-Commit true レスポンス前に確実にディスクに書き込む 帳票などのドキュメントに使う false ディスクに書き込む前に HTTP 201 を返す ポストイット的なドキュメントに使う Response ETag ドキュメントの _rev と同じ値が入る JSONのparseをしなくても_revを入手できる 46. デザインドキュメントの構成 { "_id" : "_design/app", "_rev" : "3-XXXXXX", "language" : "text/javascript", "views" : { "count_by_name" : { "map" : "function(doc){ ... }", "reduce" : "function(k,v,r){ ... }" } }, "shows" : ... "lists" : ...} これ 47. ビューの用途 基本 ドキュメントのフィルタリング 並び替え 内部的にはインデックスを作る作業 ドキュメントを効率的に見つけるために! 様々な計算 SUM とか。 応用 (データ構造の)フォーマット "正規化", "非正規化" も含めて 覚えておくべきこと: クエリではありません。 "クエリ"の機能 ... URLにクエリ文字列っていうものがありますよね? 49. サンプルデータ ハンズオンでやります。 http://search.twitter.com/?q=%23bpstudy { "_id": "479ce1c32f79d7864730ecbae60d6610", "_rev": "1-f45bf5f71b84692d0acc4b196849c2d7","iso_language_code": "ja", "type": "tweets", "keyword": "#bpstudy", "text": "1時間遅れたけど終わった。これであとは資料の残り半分を完成させればOK #bpstudy (といってハッシュタグのテスト)", "created_at": "Sat, 17 Apr 2010 19:07:16 +0000", "profile_image_url": "http://a3.twimg.com/profile_images/427387065/speedland_normal.png", "source": "<ahref="http://sites.google.com/site/yorufukurou/" rel="nofollow">YoruFukurou</a>", "from_user": "yssk22", "from_user_id": 3749810, "to_user_id": null, "geo": null, "id": 12356675615, "metadata": { "result_type": "recent" }} 50. map 関数 の書き方 function(doc){ emit(key, value);emit(key, value); ...} emit(key, value) 51. 発言者ごとにemitする function(doc){ function format_date() { ... }; // 省略 if( doc.type == ''tweets'' ){var t = format_date(t); emit([doc.from_user, t], null); }} emit(key, value) で出力を定義 key はobject以外の任意の値 value は null でもよい。 undefined はJSONの仕様外なのでだめ 52. 結果 /{db}/_design/{app} /_view/{viewname} で確認可能 {"total_rows":169,"offset":0,"rows":[ {"id":"...","key":["AE35","2010/04/02 01:36"],"value":null}, {"id":"...","key":["albuk","2010/04/01 15:36"],"value":null}, {"id":"...","key":["ali_lin5757","2010/04/05 20:02"],"value":null}, {"id":"...","key":["Amoreeeee","2010/04/06 15:45"],"value":null}, {"id":"...","key":["aodag","2010/04/02 01:57"],"value":null}, ... ]} 56. 発言数をカウントする map 関数の定義 function(doc){ function format_date() { ... }; // 省略 if( doc.type == ''tweets'' ){var t = format_date(t); emit([doc.from_user, t], 1); }} 57. 発言数をカウントする reduce 関数の定義 function(keys, values, rereduce){ if( rereduce ){ return sum(values); // sum([2,5,3,4, ...]) }else{ return values.length; // [1,1,1,1,...].length }} 61. ちょっと前のWeb+DB Web Server Web Server Web Server Web Server App Server App Server App Server App Server RDB Server RDB Server 62. 最近の Web+DB Web Server Web Server Web Server Web Server App Server App Server App Server App Server DB Server DB Server DB Server DB Server RDBだったりKVSだったり... 75. tweet の表示 function(doc, req){ var t = require('vendor/crayon/lib/template');if(doc && doc.type == 'tweets'){ bindings["page.title"] = "@" + doc.from_user + ": " + doc.text; bindings["tweet.id"] = doc.id; bindings["tweet.text"] = doc.text; ... returnt.render(ddoc.templates.site.header, bindings) + t.render(ddoc.templates.tweet, bindings) + t.render(ddoc.templates.site.footer, bindings); } ... URLからドキュメントを変数にマップ 3rd party ライブラリの利用 コンテンツを文字列で返す 77. timeline の表示 function(head, req){ provides(''html", function(){ bindings["page.title"] = keyword; send(t.render(ddoc.templates.site.header, bindings)); send(t.render(ddoc.templates.timeline.header, bindings)); while(row = getRow()){ var doc = row.doc; if( doc && doc.type == 'tweets'){ $.extend(bindings, h.bind_tweet(doc)); send(t.render(ddoc.templates.timeline.row, bindings)); } } send(t.render(ddoc.templates.timeline.footer, bindings)); return t.render(ddoc.templates.site.footer, bindings); }); } Content Negotiation Content-Length: chunked で送信開始 Viewの結果を1行ずつ取得して処理 79. Server Side JavaScript Impl CouchDBの場合は Spidermonkeyベースの実装 CGIのように動作する couchjsというProcess Poolが都度実行 CouchDBのメインプロセスとPipeで通信 それほど早くないので注意 Server Side で実装してみて、遅ければブラウザに実行させるのもあり。 ドキュメントモデルと画面の差異が大きいほどJSで処理する量が多くなるので、その場合は設計を疑うのも○。 実際どこまでできる? sandbox になっているので、ファイルを読んだり、外部リソースにアクセスすることはできない。 JSの実装が気に入らなければ、Python, Ruby など他の実装に切り替えることもできる。