Couch db 浅漫游.

60
CouchDB 浅浅浅 jinyuan@taobao. com

Transcript of Couch db 浅漫游.

Page 1: Couch db 浅漫游.

CouchDB 浅慢游

[email protected]

Page 2: Couch db 浅漫游.

website with CouchDB

•http://www.elyservice.co.uk/ 这个个人网站使用 CouchDB的技术资料 http://www.jasondavies.com/blog/2009/05/08/couchdb-on-wheels/

•https://github.com/langalex/boom_amazing

•https://github.com/hpoydar/processing-js-studio

•https://github.com/quirkey/swinger

•https://github.com/jchris/couchdb-twitter-client

•https://github.com/langalex/boom_amazing

Page 3: Couch db 浅漫游.

Boom Amazing

Page 4: Couch db 浅漫游.

CouchDB Twitter Client

Page 5: Couch db 浅漫游.

Let's give it a try on windows

How to install couchDB on windows

安装地址

How to install cygwin on windows( 辅助工具 )

安装地址

Page 6: Couch db 浅漫游.

RESTful API

What is REST? See REST简介

• GET: retrieve data from the database

• PUT: insert new data and modify existing data

• POST: equate to put, but it is not recommended in most cases

• DELETE: delete data from the database

• COPY: copy documents in the database

标准的 HTTP 方法:

Page 7: Couch db 浅漫游.

How to Creating your first database using the HTTP API

Creating the database is simple curl -X PUT http://127.0.0.1:5984/contacts

Get databases are currently available on the server curl -X GET http://127.0.0.1:5984/_all_dbs

delete special database on the server curl -X DELET http://127.0.0.1:5984/contacts

fetch some information about the contacts database curl -X GET http://127.0.0.1:5984/contacts

Page 8: Couch db 浅漫游.

Creating doucuments in your Contacts Database

// 创建名字为 kevin 的文档curl -X PUT http://127.0.0.1:5984/contacts/kevin -d '{}‘

// 获取刚创建的文档curl -X GET http://127.0.0.1:5984/contacts/kevin

// 逻辑删除文档curl -X DELETE http://127.0.0.1:5984/contacts/kevin?rev=?

// 是不是逻辑删除我们可以重新激活它 , 在这个删除的版本上更新操作curl -X PUT http://127.0.0.1:5984/contacts/kevin -d '{"_rev":"?","email":["[email protected]","[email protected]"],"age":"23"}'

//copy 数据库(备份数据库)curl -X COPY http://127.0.0.1:5984/contacts/kevin -H "Destination: xiaoqiang"

Page 9: Couch db 浅漫游.

Getting started with CouchDB views

查询详细的生存的文档视图 curl -X GET http://127.0.0.1:5984/contacts/_all_docs (?include_docs=true) 可选

how to get some meaningful data out of your CouchDB database, using the built-in JavaScript view engine.

Using views, you can aggregate and report on the documents in your CouchDB database

there is no restriction on the number of views you can have of any one document

视图本身就是一个特殊的文档

Page 10: Couch db 浅漫游.

Traditional RDBMS BMM_USER table

you wanted to retrieve the name, e-mail address, and fax number of all your users

SELECT name, email, fax FROM BMW_USER

Page 11: Couch db 浅漫游.

same data but in a CouchDB database

Page 12: Couch db 浅漫游.

在进一步地了解视图之前,让我们先看个简单的 map 函数编写

If we wanted to know all the information for user "Alice" we would write a SQL query similar to the following:

SELECT * FROM users WHERE username = "Alice"

Getting started wit CouchDB views

let's translate this data into something that would make sense for CouchDB “Map function document”.

Page 13: Couch db 浅漫游.

{ "type": "user", "username" : "Alice", "password" : "kittycat"}

the information for user “Alice” 的 JSON 数据结构

Page 14: Couch db 浅漫游.

Let's write a very quick and dirty Map function that will allow us to lookup a user from our user documents based on username. The skeleton of a Map function is just a single Javascript function that takes a single argument of a document (JSON object).

function(doc){}

Map function

Page 15: Couch db 浅漫游.

Firstly,let's add in the equivalent of the FROM clause. Since this function will be applied to every document in our system, including non-user documents, we'll need to distinguish which documents we will actually want to pull from.

function(doc){

if(doc.type == "user"){ //Now we know we have a user document}

}

Map function

Page 16: Couch db 浅漫游.

Map function

Now let's add in the SELECT * and WHERE username = 'Alice' parts together

the key in our table will be the criteria we use to lookup the data we're interested in. Thus, we need to emit the user document's username as the key, and the entireDocument as the value.

function(doc){

if(doc.type == "user"){ emit( doc.username, doc );

//Map functions convert documents into a hash table-like structure, and that's what this function will need to do. It will perform this task through a function called emit

}} 这样一个简单 map 函数编写完成了

Page 17: Couch db 浅漫游.

introduction to CouchDB views

Temporary viewfunction(doc) {

if(doc.fax && doc.name && doc.phone)emit(doc._id, {Name: doc.name, Phone: doc.phone});

}execute a temporary view ( 限制使用 )

curl -X POST http://127.0.0.1:5984/bmw_users/_temp_view -d '{"map":"function(doc) {emit(doc._id, doc); }"}' -H 'Content-Type:application/json’

execute a permanent viewcurl -X GET

http://127.0.0.1:5984/bmw_users/_design/users/_view/get_fax_users

curl -X GET

http://127.0.0.1:5984/bmw_users/_design/users/_view/get_email_users

当然我们可以合并这二个视图,如既要按 fax 或 email 查询用户,取这 2 个视图的并集curl -X GET http://127.0.0.1:5984/bmw_users/_design/users/_view/get_fax_or_email

有时候我们需要过滤文档,找到我们所关心的文档curl -X GET http://127.0.0.1:5984/bmw_users/_design/users/_view/get_name_users

Page 18: Couch db 浅漫游.

浏览器查询

Page 19: Couch db 浅漫游.

浏览器查询

Page 20: Couch db 浅漫游.

浏览器查询

Page 21: Couch db 浅漫游.

看个小例子

The raw view of the contacts database

http://127.0.0.1:5984/bmw_users/_design/users/_view/get_email_users( 页面输出标准的 json 格式,我们可以方便的 ajax来获取数据 )

如采用 YUI 封装的 ajax 写法, IE 下打开测试页面 http://zhengke.org/project/test/ajax.html 等待页面加载完成后直接获取数据渲染页面

Page 22: Couch db 浅漫游.

浏览器查询

Page 23: Couch db 浅漫游.

Map/Reduce

how CouchDB uses map/reduce views instead of SQL statements to interact with data ?

Page 24: Couch db 浅漫游.
Page 25: Couch db 浅漫游.

看图

如何归并相同的 key 数据? See Reduce Function

点击 Run 按钮执行

Page 26: Couch db 浅漫游.

Reduce Function

function(key, values, reduce){}

we know the reduce function works after the map function,this reduce function will process data from the Map function'shash table.

"key" argument is a singular key from the hash table "value" is whatever we emitted as the value under that

particular key.

Page 27: Couch db 浅漫游.

let's take a look at how a Reduce function could potentially change this hash table down into a different form of data.

the Reduce function is responsible for reducing the values under a particular key in the hash-table down into a smaller result set, potentially a single record.

Making the Map a little more useable with Reduce

Page 28: Couch db 浅漫游.

One SQL comparison:

SELECT count(*) FROM users

Map for reducefunction(doc){

if(doc.type == "user"){emit( 1, doc );}

} Reduce counting users

function(key, values, rereduce){

return values.length;}

If we had 20 user records(documents), then the result would be {"1" : "20"}.

Page 29: Couch db 浅漫游.

看图当我选中下图 reduce 这个选择框时,就归并了相同的 key 记录,我这里的归并函数是 sum 函数(注,按照自己的需求函数都可以自定义)

Page 30: Couch db 浅漫游.

Reduce as a funnel that takes a view

Page 31: Couch db 浅漫游.

这个函数的语义分析

•Contain both an e-mail address and a fax number•Contain only an e-mail address•Contain only a fax number•Contain neither an e-mail address nor a fax number

function(doc) {if(doc.email && doc.fax)

emit("Both", 1);else if(doc.email)

emit("Email", 1);else if(doc.fax)

emit("Fax", 1);else

emit("Neither", 1);}

Page 32: Couch db 浅漫游.

Map/Reduce

how you can aggregate this data to produce a count of the contacts for each key.

The Reduce Function for the Aggregate View

function(key, values, reduce) {return sum(values);

}更新 doucument ,视图也会自动更新

// 查看视图curl -X GET http://127.0.0.1:5984/bmw_users/_design/users/_view/count_by_type

根据 key 分组curl -X GET http://127.0.0.1:5984/bmw_users/_design/users/_view/count_by_type?group=true

Page 33: Couch db 浅漫游.

Map/Reduce vs. SQL Queries

SELECT id, name, email FROM contacts WHERE country = 'USA' ORDER BY name

function(doc) {if(doc.type != "contact") return;emit([doc.country, doc.name], {name: doc.name, email:

doc.email});}

http://127.0.0.1:5984/bmw_users/_design/users/_view/get_complex_key

http://127.0.0.1:5984/bmw_users/_design/users/_view/get_complex_key?startkey=["USA"]&endkey=["USA",{}]

SELECT COUNT(*), country FROM contacts GROUP BY country ===>

map: function(doc) {emit(doc.country, 1);

}reduce: function(key, values, rereduce) {

return sum(values);}

Page 34: Couch db 浅漫游.

word count Example

http://127.0.0.1:5984/doucuments/_design/words/_view/count_word?group=true

Page 35: Couch db 浅漫游.

usering Futon

让我们图形化管理,爽!告别 API , Codeing!

access Futon HomePage

http://127.0.0.1:5984/_utils

Page 36: Couch db 浅漫游.

Create a database through Futon

Page 37: Couch db 浅漫游.

Example JSON output of database statistics

http://localhost:5984/couchdb_in_action

Page 38: Couch db 浅漫游.

Modeling data in documents

If SQL is based on a rigid type system enforced by tables, then CouchDB is best described as a ducktyped system. Ducktyping comes from the expression "if it looks like a duck, talks like a duck, then it's probablya duck."

Page 39: Couch db 浅漫游.

{ "doc_type" : "Person", "name" : "Chris Chandler", "login" : "cchandler", "address" : "1234 N. Here St."}

look like a Person

Page 40: Couch db 浅漫游.

• one-to-one

• one-to-many

• many-to-many

Transitioning more complex relationships to documentsThe three principal relationships

Page 41: Couch db 浅漫游.

We know that JSON supports both objects(hashes) and arrays, so we know we can store arbitrarily

complex types within a document.

JSON

Page 42: Couch db 浅漫游.

/* User */{"username" : "chris"}

/* Address */{"type" : "shipping""address1" : "1234 N. Here St.","city" : "Phoenix","state" : "Arizona","zip" : "85005""country" : "us"}

two relation document

Page 43: Couch db 浅漫游.

we can easily perform by moving the entire contents of the address document underneath a key called "addresses" in the user document

document of merged one-to-many with type on the sub document

/* Combined document */{

"username" : "chris","addresses" : [{"type" : "shipping""address1" : "1234 N. Here St.","city" : "Phoenix","state" : "Arizona","zip" : "85005""country" : "us"}]

}

Combined document one to one

Page 44: Couch db 浅漫游.

/* Combined document */

{ "username" : "chris","addresses" : { "shipping" : { "address1" : "1234 N. Here St.", "city" : "Phoenix", "state" : "Arizona", "zip" : "85005" "country" : "us" }, "billing" : { "address1" : "7890 N. There St.", "city" : "Phoenix", "state" : "Arizona", "zip" : "85006" "country" : "us" } }

Example document of merged one-to-many relationship with specific keys Combined document one to many

Page 45: Couch db 浅漫游.

many-to-many relationship

/* Denormalized many-to-many document{"username" : "chris", "followers" : [ {"user_id" : "", "username" : "trent"}, {"user_id" : "", "username" : "eve"} ], "following" : [ {"user_id" : "", "username" : "alice"}, {"user_id" : "", "username" : "bob"} ]}

Page 46: Couch db 浅漫游.

反规范化

Page 47: Couch db 浅漫游.

function(newDocument) {

if(!newDocument.addresses){ throw( { forbidden : 'User document requires an addresses key!' }); } if(!newDocument.addresses.length < 1){ throw( { forbidden :'User document requires at least one address!' }); }}

Validating your data

Page 48: Couch db 浅漫游.

Developing CouchDB Applications with CouchApp

安装所需要的组件

CouchApp—a set of scripts that allow complete, stand-alone CouchDB applications to be built using just HTML and JavaScript. These applications are housed in the CouchDB database, meaning that when the database is replicated, any applications stored in that database are also replicated

Page 49: Couch db 浅漫游.

A Simple Task Manager

在命令行中进入 F 盘,敲 Couchapp generate couchtasks ,生成如图所示

在 _attachments 子目录中存放我们的 web 资源文件,我们可以加以修改

上传到服务器 couchapp push . http://127.0.0.1:5984/couchtasks

Page 50: Couch db 浅漫游.

CouchApp

Page 51: Couch db 浅漫游.

client-side application

Advantages : flexibility and portability

Page 52: Couch db 浅漫游.

Serverside Application

using CouchDB as a traditional database back end to a serverside application developed in Python , Ruby, Django

Page 53: Couch db 浅漫游.

Creating a CouchDB Database in Python

from couchdbkit.client import Serverserver = Server()server.create_db(“python_test”)Couchdbkit 的目标是为您的 Python 的应用提供调用和管理 Couchdb 的框架。网站地址: http://couchdbkit.org/

Page 54: Couch db 浅漫游.

Python IDE

这个工具我也是用了一会 , 我打算统一使用jetBrains  提供的

Python IDE: pycharm下载链接http://www.jetbrains.com/pycharm/

Page 55: Couch db 浅漫游.

Creating a CouchDB Database in Ruby

Couchrest 是一个 CouchDB RESTful Ruby 客户端

网址地址: https://github.com/couchrest/couchrest/wiki/couchrest-core

Page 56: Couch db 浅漫游.

Ruby IDE

RubyMine 下载链接地址:

http://www.jetbrains.com/ruby/download/index.html

Page 57: Couch db 浅漫游.

Django

网址 : http://www.djangoproject.com/

Page 58: Couch db 浅漫游.

杂谈

我们需要在服务器上进行逻辑处理和创建网页,但现在这种需要将会大幅下降,在极端情况下,服务器可能只需提供数据库服务即可。

当然这只是假设在极端的情况下会如此。对于复杂的、需要协调大量服务的、或对浏览器处理应用程序的安全性不放心的企业应用程序,服务器软件将继续发挥不可或缺的作用。但对服务于大众消费者的主流商业应用程序而言,“客户端为重,服务器为轻”的前景似乎已无可置疑。

Page 59: Couch db 浅漫游.

学习资料

•http://couchdb.apache.org/

•http://wiki.apache.org/couchdb

Page 60: Couch db 浅漫游.

That is all

Thanks ,BYE-BYE!