Вы находитесь на странице: 1из 148

NoSQL: la siguiente generacin

de bases de datos
19 Abril de 2012, 9:00-14:30
Miramon Enpresa Digitala. Paseo Mikeletegi 56, 1. 20009 San
Sebastin
Dr. Diego Lz. de Ipia Glz. de Artaza
DeustoTech-INTERNET2, DeustoTech Deusto Institute of Technology, Universidad de
Deusto

dipina@deusto.es
http://paginaspersonales.deusto.es/dipina
http://www.morelab.deusto.es
1

Agenda
1. Introduccin a las bases de datos NoSQL (60)

Concepto y campos relacionados


Principales caractersticas
Arquitectura de las bases de datos NoSQL
Taxonoma de soluciones NoSQL
Empresas que usan bases de datos NoSQL

2. Ejemplo de almacn de datos clave-valor NoSQL:


Apache Cassandra (90)

Introduccin: caractersticas y arquitectura


Instalacin sobre diferentes sistemas operativos
Programacin de Cassandra desde Java y Python
La API Thrift y otras caractersticas avanzadas
Desarrollo de una aplicacin avanzada en Cassandra

Descanso (20)
2

Agenda
3. Ejemplo de almacn de base de datos
orientada a documentos: CouchDB (90)
Introduccin: caractersticas (vistas, modelado sin
esquemas) y arquitectura
Instalacin sobre diferentes sistemas operativos
La API HTTP de CouchDB HTTP
Programacin de aplicaciones desde Python y Java
Desarrollo de una aplicacin avanzada con CouchApp

4. Conclusiones (40)
Comparativa entre las diferentes soluciones de NoSQL
Otras alternativas destacables: MongoDB, HBase
Aplicabilidad a mi empresa
3

Ejemplos de este Curso


Los ejemplos asociados al curso,
junto al software necesario para su
ejecucin, puede descargarse de:
http://dl.dropbox.com/u/2763621/Curso
NoSQL/NoSQL-cd.rar

Introduccin a NoSQL
NoSQL es un trmino utilizado para
describir un subconjunto de bases de
datos que difiere en varios modos de
bases de datos tradicionales (RDBMS).
No tienen schemas, no permiten JOINs, no
intentan garantizar ACID y escalan
horizontalmente

El trmino fue acuado en 1998 porCarlo


Strozziy resucitado en 2009 por Eric
Evans
El propio Evans sugiere mejor referirse a esta
5
familia de BBDD de nueva
generacin como

Introduccin a NoSQL
NoSQL "not only SQL es una categora
general de sistemas de gestin de bases
de datos que difiere de modelo
relacionales clsicos (RDBMS) en diferente
modos:
Estos data stores no requieren esquemas de
informacin fijas
Evitan las operaciones JOIN y escalan
horizontalmente

De hecho, tanto las bases de datos NoSQL


como las relacionales son tipos de
6
Almacenamiento Estructurado.

Introduccin a NoSQL
La principal diferencia radica en cmo guardan
los datos (por ejemplo, almacenamiento de un
recibo):
En una RDBMS tendramos que partir la informacin
en diferentes tablas y luego usar un lenguaje de
programacin en la parte servidora para
transformar estos datos en objetos de la vida real.
En NoSQL, simplemente guardas el recibo:

NoSQL es libre de schemas, t no diseas


tus tablas y su estructura por adelantado
NoSQL no es la panacea!!!
Si tus datos son relacionales, quedarte con tu RDBMS
sera la opcin correcta
7

El teorema CAP

Teorema de Brewer: es imposible para un sistema


computacional distribuido ofrecer simultneamente las
siguientes tres garantas:
Consistencia todos los nodos ven los mismos datos al
mismo tiempo
Disponibilidad (Availability) garantiza que cada peticin
recibe una respuesta acerca de si tuvo xito o no
Tolerancia a la particin (Partition) el sistema continua
funcionando a pesar de la prdida de mensajes

Equivalente a:
You can have it good, you can have it fast, you can
have it cheap: pick two.

RDBMS vs. NoSQL

Las bases de datos relacionales tradicionales nos permiten definir


la estructura de un esquema que demanda reglas rgidas y
garantizan ACID:

Las aplicaciones web modernas presentan desafos muy distintos


a las que presentan los sistemas empresariales tradicionales (e.j.
sistemas bancarios):

Atomicity
Consistency
Isolation
Durability

Datos a escala web


Alta frecuencia de lecturas y escrituras
Cambios de esquema de datos frecuentes
Las aplicaciones sociales (no bancarias) no necesitan el mismo nivel de
ACID

Algunas de las opciones de NoSQL actualmente disponibles son:


Cassandra, MongoDB, Jackrabbit , CouchDB, BigTable y Dynamo
9

Por qu necesitamos
NoSQL?

Las BBDD relacionales ofrecen bajo rendimiento ante


ciertas aplicaciones intensivas de datos:
Indexacin de un gran nmero de documentos
Servir pginas en sites de mucho trfico
Envo de datos de streaming

Las RDBMS estn optimizadas para pequeas pero


frecuentes transacciones de lectura/escritura o largas
transacciones con pocos acceso de escritura.
NoSQL puede dar servicio a grandes cargas de
lectura/escritura:
Digg mantiene 3TBde green badges (marcadores que indican
las historias votadas por otros en una red social)
Facebook que tiene que realizar bsqueda en bandejas de
mensajes de ms de 50 TB
10

Arquitectura de las
BBDD NoSQL
A menudo ofrecen slo garantas de
consistencia dbiles, como por ejemplo
eventual consistency, o transacciones
restringidas a elementos de datos simples
Emplean una arquitectura distribuida,
donde los datos se guardan de modo
redundante en distintos servidores, a
menudo usando tablas hash distribuidas
Suelen ofrecer estructuras de datos
sencillas como arrays asociativos o
almacenes de pares11 clave-valor

Qu tipo de BBDD elijo?


Algunas respuestas pueden
encontrarse en:
35+ Use Cases For Choosing Your Next
NoSQL Database
http://highscalability.com/blog/2011/6/20/35
-use-cases-for-choosing-your-next-nosql-data
base.html

Five Reasons to Use NoSQL

http://facility9.com/2010/09/five-reasons-touse-nosql/

Las ms populares son: Cassandra,


CouchDB, MongoDB, Riak, Neo4j
12

Quin usa NoSQL?


No lo usan para todo, slo para
algunas partes de sus sistemas
empresariales:
Ubuntu DesktopCouch (CouchDB)
Adobe y Mozilla (Hbase)
Twitter (
http://www.readwriteweb.com/cloud/2011
/01/how-twitter-uses-nosql.php
)
13

Taxonoma de soluciones
NoSQL
Los principales tipos de BBDD de
acuerdo con su implementacin son
los siguientes:
Almacenes de documentos
Almacenes de Clave-Valor
Grafos

14

Base de Datos orientada


a Documentos
Unabase de datos orientada a
documentoses un programa diseado para
almacenar, recuperar y gestionar informacin
semi-estructurada orientada a documentos:
Un documento encapsula informacin en un formato
estndar (XML, YAML, JSON o BSON):
Los documentos en una BBDD orientada a documentos son
similares a registros pero no requieren un esquema
estndar con la mismas secciones, huecos, partes, claves y
similar
Los documentos suelen ser direccionables por una clave
que los representa unvocamente
Adems de la bsqueda por clave de documento, estas
BBDD suelen ofrecer una API o lenguaje de consultas que
permite recuperar documentos
en base a sus contenidos
15

Caractersticas BBDD
orientadas a
Documentos

La precursora fue Lotus Notes


Modelo de datos: colecciones de
documentos que contienen colecciones de
claves-valor
Ejemplos: CouchDB, MongoDB
Buenas en:

Modelado de datos natural


Amigables al programador
Desarrollo rpido
Orientas a la web: CRUD
16

Caractersticas BBDD
orientadas a Clave-Valor
Su precursor fue Google BigTable
Modelo de datos: familia de columnas,
esto es, un modelo tabular donde cada fila
puede tener una configuracin diferente
de columnas
Ejemplos: HBase, Hypertable,
Cassandra,Riak
Buenas en:
Gestin de tamao
Cargas de escrituras masivas orientas al
stream
17
Alta disponibilidad

Distributed Hash Table


(DHT)

Undistributed hash table(DHT) es una clase de sistema


distribuido que permite un servicio de lookup similar a un Hash
Table
Almacenan pares clave valor
Cada nodo puede obtener eficientemente el valor asociado a una clave
La responsabilidad de mantener los mapeos entre claves y valores est
distribuida entre los nodos
Escalan a grandes nmeros de nodos y gestionan la llegada continua
de nodos, salidas y fallos

18

Apache Cassandra
Es un almacn altamente escalable,
eventualmente consistente y distribuido de
estructuras clave-valor.
Iniciado por Facebook
Cdigo abierto
Proyecto apache
Licencia: Apache License 2.0

Escrito en Java
Multiplataforma
Versin actual: 1.0.9
Web: http://cassandra.apache.org/

Documentacin:
http://www.datastax.com/docs/1.0/index
19

Quin usa Apache


Cassandra?
Algunos usuarios famosos de
Cassandra son:
Digg
Facebook
Twitter
Rackspace
SimpleGEO

20

Ventajas de Cassandra
para desarrolladores
Web
Cassandra est desarrollada para ser un servidor distribuido, pero
puede tambin ejecutarse como un nodo simple:
Escalabilidad horizontal (aade nuevo hardware cuando sea preciso)
Rpidas respuestas aunque la demanda crezca
Elevadas velocidades de escritura para gestionar volmenes de datos
incrementales
Almacenamiento distribuido
Capacidad de cambiar la estructura de datos cuando los usuarios
demandan ms funcionalidad
Una API sencilla y limpia para tu lenguaje de programacin favorito
Deteccin automtica de fallos
No hay un punto de fallo nico (cada nodo conoce de los otros)
Descentralizada
Tolerante a fallos
Permite el uso de Hadoop para implementar Map Reduce
Hinted hand of
21

Desventajas de
Cassandra
Hay algunas desventajas que un
sistema de almacenamiento tan
escalable ofrece en contrapartida:
No hay joins (a cambio de ms
velocidad)
No permite ordenar resultados en
tiempo de consulta
No tiene SQL
Pero desde la versin 0.8 tenemos CQL
22

Instalacin de Cassandra
Documentacin en:
Cassandra Wiki: GettingStarted,
http://wiki.apache.org/cassandra/Getting
Started

Requisitos:
Java 1.6 en adelante

Las ltimas versiones estables


disponibles en:
http://cassandra.apache.org/download/
23

Instalacin de Cassandra
Disponible desde:
http://cassandra.apache.org/download/
Descargar apache-cassandra-1.0.9-bin.tar.gz o
similar

Descomprimir en tu sistema con Winrar o usando


gzip en Linux
Asociar a la variable de entorno PATH la
localizacin de la carpeta bin dentro de Apache
Cassandra:
En Windows podra quedar en:
C:\Programming\Java\apache-cassandra-1.0.3\bin

24

Ejecutando un nodo de
Cassandra
Arrancar Apache Cassandra, ejecutando:
cassandra f
-f le dice a Cassandra que se ejecute en foreground para
ver as los logs del sistema

Tenemos un cluster con un solo nodo


ejecutndose en el puerto 9160
La configuracin de este nodo la podemos
encontrar en: conf/cassandra.yaml
Ejecutar el cliente de consola para asegurarnos
que todo est bien:
cassandra-cli

25

Comandos CLI Bsicos


help; tambin se puede user ?,
sirve para pedir ayuda
Para conectarte a un servidor, hacer:
connect localhost/9160;
Alternativamente: cassandra-cli
localhost/9160

show cluster name;


show keyspaces;
show API version;
26

Comandos CLI Bsicos

Vamos a crear un KeySpace, algo as como una base de


datos relacional:
Define un conjunto de familias de columnas
Una familia de columnas es algo as como una tabla
drop keyspace MyKeySpace;
create keyspace MyKeySpace;
use MyKeySpace;
create column family User;
describe MyKeySpace;
assume User keys as Ascii;
assume User comparator as Ascii;
set User['dipina']['lname']='Lopez-de-Ipina';
set User['dipina']['fname']='Diego';
set User['dipina']['email']='dipina@deusto.es';
count User['dipina'];
get User['dipina'];
del User['dipina']['email'];
del User['dipina'];
27
get User['dipina'];

Ring, clster y el
protocolo
Gossip
Cassandra usa un protocolo Gossip para permitir
comunicacin dentro de un ring, de tal modo que
cada nodo sabe de otros nodos
Permite soportar descentralizacin y tolerancia a la
particin

Cassandra est diseada para ser distribuida en


varias mquinas que aparecen como una simple
mquina a los ojos de los clientes
La estructura ms externa de Cassandra es el cluster o
ring
Un nodo tiene una rplica para diferentes rangos de datos,
si algo va mal una rplica puede responder
El parmetro replication_factor en la creacin de un
KeySpace indica cuntas mquinas en el clster recibirn
copias de los mismos 28
datos.

Ejecutando un Clster
Hay que repetir el paso anterior varias veces,
PERO
Necesitamos indicar qu nodo va a funcionar como
Seed, dado que los nodos en Cassandra se comunican
usando un protocolo Gossip
La idea es permitir que los nodos en un cluster se
descubran unos a otros

Adems deberemos indicar la interfaz IP para escuchar


para Gossip y Thrift

Documentacin en:
http://crlog.info/2011/07/09/setting-up-a-multi-node-cas
sandra-cluster-on-a-single-windows-machine/
http://www.datastax.com/docs/0.7/getting_started/config
uring
29

Ejecutando un Clster

Vamos a realizar un ejemplo con 4 nodos en Windows. Los pasos a seguir


sern:
1. Abrir el fichero hosts en C:\Windows\System32\drivers\etc
2. Aadir el siguiente contenido, para crear 4 nodos locales:
#cassandra nodes
127.0.0.1
127.0.0.1
127.0.0.1
127.0.0.1

node1.cassandra
node2.cassandra
node3.cassandra
node4.cassandra

3. Descomprime apache-cassandra-1.0.5-bin.tar.gz en 4 carpetas, por


ejemplo: %HOME%\apache-cassandra-1.0.5\1 a %HOME%\apache-cassandra1.0.5\4
4. Editar cada conf\cassandra.yaml con lo siguiente:

Propiedad cluster_name=PruebaCluster
Asegrate que auto_bootstrap: false en node1 y node2
Configura los dos seed nodes con la lnea: seeds: node1.cassandra, node2.cassandra
Modifica los directorios de datos: data_file_directories, commitlog_directory y
saved_caches_directory

Modifica las variables:

5.
6.

Por ejemplo, commitlog_directory: /var/lib/cassandra/1/commitlog


listen_address: node1.cassandra
rpc_address: node1.cassandra

Modicar el nmero de puerto en cassandra.bat de JMX:


-Dcom.sun.management.jmxremote.port=7199
30
Ejecutar el siguiente comando para ver los nodos en el clster:

Teorema CAP en
Cassandra
Las bases de datos derivadas de Amazon
Dynamo incluyen Cassandra, Voldemort,
CouchDB y Riak
Centradas ms en disponibilidad y tolerancia a
fallos
Permiten Consistencia Eventual
Donde eventual significa milisegundos

Por tanto Cassandra es AP:


To primarily support Availability and Partition
Tolerance, your system may return inaccurate data,
but the system will always be available, even in the
face of network partitioning
31

Modelo de Datos en
Cassandra
Est basado en un modelo clavevalor
Extiende el modelo clave-valor con
dos niveles de anidamiento
Su modelo de datos representa un
mapa de 4 o 5 dimensiones.
El modo de referirse a un registro de
datos es:
Unkeyspace, unacolumn family,
unakey, unasuper column opcional, y
32
unacolumn.

Modelo de Datos en
Cassandra

Diseado para datos distribuidos de modo escalable sacrifica


ACID por ventajas en rendimiento, disponibilidad y gestin
operacional
Los modelos que se crean son desnormalizados:
Se suele crear una column family por cada consulta (query) a realizar
Varias filas en un column family suelen dar respuesta a una consulta

Los conceptos bsicos son:


Clster: son las mquinas que componen una instancia de Cassandra
Pueden contener varios Keyspaces

Keyspace: espacio de nombres para un conjunto de ColumFamily,


asociado a una aplicacin
Suele vincularse con una BBDD en el modelo relacional

ColumFamily: contienen varias columnas


Suelen vincularse con una tabla en el modelo relacional

SuperColumn: columnas que ellas mismas tienen sub-columnas


Column: compuestas de un nombre, valor y timestamp
33

Column
Una columna es un par nombre-valor que
tambin contiene un timestamp
Los nombres y columnas son arrays de bytes
El timestamp registra la ltima vez que una columna es
accedida
Unidad atmica
name:value:timestamp
Email:dipina@deusto.es:123456789

Ejemplo en JSON:
{
"name": "Email",
"value": "dipina@deusto.es",
"timestamp: 123456789
}

34

Super-columnas
Una supercolumna es un array
asociativo (mapa) de columnas
ordenadas por nombre

35

Column Family

Es un contenedor de columnas
Anlogo al concepto de tabla en RDBMS

Contiene una lista ordenada de columnas


Cuando se crea de manera configurativa una familia de
columnas se indica cmo se ordenarn las columnas de cada
fila (cogiendo el nombre)
ASCII, UTF-8, Long, UUID

Cada familia de columnas se guarda en un fichero, y el


fichero est ordenado por clave de fila
Una familia de columnas tiene un
conjunto de filas con un conjunto de
columnas similar pero no idntico

Pueden ser de tipo SUPER o STANDARD

36

Column Family

Ejemplo en JSON:
{
"mccv":{
"Users":{
"emailAddress":{"name":"emailAddress", "value":"foo@bar.com"},
"webSite":{"name":"webSite", "value":"http://bar.com"}
},
"Stats":{
"visits":{"name":"visits", "value":"243"}
}
},
"user2":{
"Users":{
"emailAddress":{"name":"emailAddress",
"value":"user2@bar.com"},
"twitter":{"name":"twitter", "value":"user2"}
}
}
}
37

Familia de supercolumnas
Una familia de super-columnas es
un contenedor de super-columnas
ordenadas por sus nombres, a su vez
estas super-columnas aparecen
ordenadas por las claves de fila
(row_key)

38

Familia de supercolumnas

39

Familias de Columnas vs.


Familia
de Super-Columnas

Una fila en una familia de columnas normal es un


mapa de nombres de columna ordenadas a
valores de columna
The address of a value in a regular column family is a
row key pointing to a column name pointing to a value

Una fila en una familia de super-columnas es un


mapa ordenado de nombres de super-columnas a
mapas de nombres de columnas a valores de
columnas
The address of a value in a column family of type
super is a row key pointing to a column name pointing
to a subcolumn name pointing to a value
40

KeySpaces
Un espacio de claves o KeySpace es un
esquema de alto nivel que contiene
familias de columnas.
Supercolumn Family Estado de Usuario

Column Family Entradas en Twitter: tweets:

41

Resumen Modelo de
Datos

42

Clster
Los datos en Cassandra se guardan
en un Clster o Ring donde se
asignan datos a los nodos dentro de
un ring
Un nodo tiene rplicas para diferentes
rangos de datos
Si un nodo se cae su rplica puede
responder
Un protocolo P2P hace que los datos se
repliquen entre nodos acorde con un
43
replication_factor

Configuracin de un
Keyspace
Los atributos bsicos que puedes asociar a
un keyspace son:
Replication factor: cunto quieres pagar en
rendimiento a favor de consistencia
Replica placement strategy: indica cmo se
colocan las rplicas en el anillo:
SimpleStrategy, OldNetworkTopologyStrategy y
NetworkTopologyStrategy
Revisar:
http://answers.oreilly.com/topic/2408-replica-placem
ent-strategies-when-using-cassandra/

Column families: al menos una por Keyspace,


es un contenedor de44filas, que contienen
columnas

Otros aspectos
importantes
Cassandra ofrece soporte para particionado
distribuido de datos
RandomPartitioner te da buen balanceo de carga
OrderPreservingPartitionioner te permite ejecutar
consultas de rangos, pero exige ms trabajo eligiendo
node tokens
Ms info en:
http://abel-perez.com/cassandra-partitioner-order-preserving
-partit

Cassandra tiene consistencia reconfigurable


http://www.datastax.com/docs/0.8/dml/data_consistency

Con Cassandra tienes que pensar en las consultas


que quieres ejecutar y luego realizar el modelo en
torno a ellas
45

Diferencias entre un
RDBMS y Cassandra

No hay lenguaje de consulta, tiene una API accesible a travs de Thrift

No hay integridad referencial, no hay joins, se puede emular almacenando


claves a otras filas en un column family
ndices secundarios en una tabla dan lugar a nuevos column families que
mapean un campo a la clave de la primera column family

BytesType, UTF8Type, AsciiType, LongType, LexicalUUIDType, TimeUUIDType

Las filas son agrupadas y ordenadas (distribuidas en el cluster) por el


Partitioner

Verdad a medias: desde Cassandra 0.7 se pueden crear ndices secundarios:


http://www.datastax.com/dev/blog/whats-new-cassandra-07-secondary-indexes

Ordenar es una decisin de diseo, las definiciones de familias de


columnas incluyen un elemento CompareWith

Verdad a medias: si existe desde la versin 0.8 CQL

RandomPartitioner, OrderPreservingPartitioner,
CollatingOrderPreservingPartitioner

Cassandra tiene mejor rendimiento con datos desnormalizados


Modelas las consultas y luego defines la estructura de datos a su alrededor
46

RDBS vs. KeySpace

47

Soporte Multi-lenguaje
de Cassandra
Cassandra utiliza la librera Thrift (
http://thrift.apache.org/) para proveer una API
independiente del lenguaje de programacin
Thrift API 1.0: http://wiki.apache.org/cassandra/API
Ejemplo en:
http://wiki.apache.org/cassandra/ClientExamples

Thrift soporta un gran nmero de lenguajes


incluyendo: C++, Java, Python, PHP, Ruby,
Erlang, Perl, Haskell, C#, Cocoa, JavaScript,
Node.js, Smalltalk, y Ocaml
Hay muchas libreras clientes disponibles:
Pycassa para Python:
http://pycassa.github.com/pycassa/index.html
48
Hector para Java: https://github.com/rantav/hector

Avro vs. Thrift

Avro remplazar Thrift como cliente RPC para interaccionar


con Cassandra.
Avro es un subproyecto de Apache Hadoop project
Proporciona funcionalidad similar a Thrift pero es una librera
de serializacin dinmica que no requiere generacin de
cdigo esttica como Thrift
Thrift fue creado por Facebook y luego donado a Apache, pero
apenas ha recibido soporte ltimamente.

El servidor de Cassandra ser portado de


deorg.apache.cassandra.thrift.CassandraServeraor
g.apache.cassandra.avro.CassandraServer
Todava no hecho

Ms informacin sobre Avro en:http://avro.apache.org.

49

Mi primera aplicacin
con Cassandra
Relational vs.
Cassandra Model

50

Cassandra vs. RDBMS


Un RDBS es un modelo basado en el
dominio
qu respuestas tienes?

Cassandra tiene un modelo


orientado a consultas
qu preguntas tienes?

51

Pycassa: un cliente
Python
para Apache Cassandra
Instalacin:

Dependencias:
Instalar Python 2.7 o en adelante
Instalar setuptools

Descarga el ficero .zip de


https://github.com/pycassa/pycassa
Descomprmelo en tu disco duro
Instala pip siguiendo las instrucciones en:
http://www.pip-installer.org/en/latest/installing.html

Ejecuta python setup.py install

Ms info en:
http://pycassa.github.com/pycassa/tutorial.html#connec
ting-to-cassandra
52

Interactuando con
Cassandra desde Python:
pycassa
Comprobar que la librera funciona
haciendo desde Python:
import pycassa

Asegrate que el KeySpace1 existe en


Cassandra
Ejecuta: cassandra-cli h localhost -f
CreateKeySpace1.txt

Conctate a Cassandra:
from pycassa.pool import ConnectionPool
pool = ConnectionPool('Keyspace1')
53

Interactuando con
Cassandra desde Python:
pycassa
Recupera una ColumnFamily:
from pycassa.pool import ConnectionPool
from pycassa.columnfamily import ColumnFamily
pool = ConnectionPool('Keyspace1')
col_fam = pycassa.ColumnFamily(pool, 'Standard1')

Insertando datos:
col_fam.insert('row_key', {'col_name':
'col_val'})
col_fam.insert('row_key2', {'col_name':'col_val',
'col_name2':'col_val2'})
col_fam.batch_insert({'row1': {'name1': 'val1',
'name2': 'val2'}, 'row2': {'foo': 'bar'}})
54

Interactuando con
Cassandra desde Python:
pycassa
Pare recuperar las columnas de una fila:
col_fam.get('row_key')

Si no queremos recuperar todas las columnas en


una fila:
col_fam.get('row_key', columns=['col_name',
'col_name2'])

Podemos tambin recuperar un rango de


columnas en una fila o en orden decreciente un
nmero mximo de columnas:
for i in range(1, 10):
... col_fam.insert('row_key', {str(i): 'val'})
col_fam.get('row_key', column_start='5',
column_finish='7')
col_fam.get('row_key',55column_reversed=True,

Interactuando con
Cassandra desde Python:
pycassa
Para recuperar mltiples filas usamos:
col_fam.multiget(['row1', 'row2'])

Tambin podemos recuperar rangos de filas:


result = col_fam.get_range(start='row_key5',
finish='row_key7')

Para conocer el nmero de columnas en una fila:


col_fam.get_count('row_key')
col_fam.get_count('row_key', columns=['foo', 'bar'])
col_fam.get_count('row_key', column_start='foo')

Para contabilizar las filas que cumplen ciertas restricciones:


col_fam.multiget_count(['fib0', 'fib1', 'fib2', 'fib3',
'fib4'])

Tutorial de pycassa en:


http://pycassa.github.com/pycassa/tutorial.html#
56

Twissandra

Download de: https://github.com/twissandra/twissandra


Instalar Django:
Bajar la ltima versin de: https://www.djangoproject.com/download/
Descomprimir el archivo descargado
Ejecutar: python setup.py install

Instalar Twissandra:
Crear el schema
cd twissandra
python manage.py sync_cassandra
Arrancar el webserver
python manage.py runserver

Los dos ficheros ms importantes a revisar son:


Twissandra/tweets/management/commands/
sync_cassandra.py
Muestra cmo crear el schema de datos de Twissandra

twissandra/cass.py
Muestra cmo hacer CRUD sobre ese schema
57

Modelo de Datos de
Twissandra

Usuarios:

User = {
'hermes': {
'password': '****',
(other properties),
},
}

Amigos y seguidores:
Friends = {

'hermes': {
# friend
'larry':
'curly':
'moe' :
},

id: timestamp of when the friendship was added


'1267413962580791',
'1267413990076949',
'1267414008133277',

}
Followers = {
'hermes': {
# friend
'larry':
'curly':
'moe' :
},
}

id: timestamp of when the followership was added


'1267413962580791',
'1267413990076949',
'1267414008133277',
58

Modelo de Datos de
Twissandra

Tweets:

Tweet = {
'7561a442-24e2-11df-8924-001ff3591711': {
'username': 'hermes',
'body': 'Trying out Twissandra. This is awesome!',
},
}

Timeline y UserLine:
Timeline = {
'hermes': {
# timestamp of tweet: tweet id
1267414247561777: '7561a442-24e2-11df-8924-001ff3591711',
1267414277402340: 'f0c8d718-24e2-11df-8924-001ff3591711',
1267414305866969: 'f9e6d804-24e2-11df-8924-001ff3591711',
1267414319522925: '02ccb5ec-24e3-11df-8924-001ff3591711',
},
}
Userline = {
'hermes': {
# timestamp of tweet: tweet id
1267414247561777: '7561a442-24e2-11df-8924-001ff3591711',
1267414277402340: 'f0c8d718-24e2-11df-8924-001ff3591711',
1267414305866969: 'f9e6d804-24e2-11df-8924-001ff3591711',
1267414319522925: '02ccb5ec-24e3-11df-8924-001ff3591711',
},
}

59

Cassandra Query
Language (CQL)

Cassandra ha sido accedido principalmente medianteThrift


una API RPC que proporciona un denominador comn a
clientes para lenguajes especficos
Pero:
Thrift es de demasiado bajo nivel para ser usado de modo
productivo o dar soporte a nuevas funcionalidades como los
ndices secundarios en 0.7 o los contadores distribuidos en 0.8

CQL da respuesta a sto pasando todos los detalles de


implementacin complejos al servidor
Los clientes slo tienen que saber cmo interpretar objetos en
un resultset

Documentacin:

http://www.datastax.com/dev/blog/what%E2%80%99s-new-in-cas
sandra-0-8-part-1-cql-the-cassandra-query-language
http://www.datastax.com/docs/0.8/dml/using_cql#use-cql
60

Acceso a CQL
Los desarrolladores pueden usar CQL desde
Python o lnea de comandos
Existen drivers en diferentes lenguajes de
programacin
Nosotros vamos a practicar con comandos CQL a
travs del cliente de lnea de comandos cqlsh
Desde Apache Cassandra 1.0.5, el cliente
cqlshest instalado en
$CASSANDRA_HOME/bin/cqlshpara instalaciones
tarball o /usr/bin/cqlshpara instalaciones de
paquetes Linux
Ejemplo programtico en:
61
http://crlog.info/2011/06/13/cql-creating-a-simple-keyspa

Un poco de CQL

Ejemplos tomados de:


http://www.datastax.com/dev/blog/what%E2%80%99s-new-in-cassandra-0-8-part-1-cql-the-cassandra-querylanguage
cqlsh> CREATE KEYSPACE test with strategy_class = 'SimpleStrategy' and strategy_options:replication_factor=1;
cqlsh> USE test;
cqlsh> CREATE COLUMNFAMILY users (
...
key varchar PRIMARY KEY,
...
full_name varchar,
...
birth_date int,
...
state varchar
... );
cqlsh> CREATE INDEX ON users (birth_date);
cqlsh> CREATE INDEX ON users (state);
cqlsh> INSERT INTO users (key, full_name, birth_date, state) VALUES ('bsanderson', 'Brandon Sanderson', 1975,
'UT');
cqlsh> INSERT INTO users (key, full_name, birth_date, state) VALUES ('prothfuss', 'Patrick Rothfuss', 1973,
'WI');
cqlsh> INSERT INTO users (key, full_name, birth_date, state) VALUES ('htayler', 'Howard Tayler', 1968, 'UT');
cqlsh> SELECT key, state FROM users;
key | state |
bsanderson |
UT |
prothfuss |
WI |
htayler |
UT |
cqlsh> SELECT * FROM users WHERE state='UT' AND birth_date > 1970;
KEY | birth_date |
full_name | state |
bsanderson |
1975 | Brandon Sanderson |
UT |

62

Un poco de CQL
Ms ejemplos en:
http://www.datastax.com/docs/1.0/dml/using_cql
cqlsh> CREATE KEYSPACE twissandra1 WITH
strategy_class = 'NetworkTopologyStrategy' AND
strategy_options:DC1 = 3;
cqlsh> USE twissandra;
cqlsh> CREATE COLUMNFAMILY users (
KEY varchar PRIMARY KEY,
password varchar,
gender varchar,
session_token varchar,
state varchar,
birth_year bigint);
63

Hector

Una API de alto nivel en Java para Cassandra


Incluye caractersticas empresariales: connection pooling,
monitoring, etc.

Documentacin:
Tutorial:
https://github.com/rantav/hector/wiki/User-Guide
https://github.com/zznate/cassandra-tutorial

Getting started guide:


https://github.com/rantav/hector/wiki/Getting-started-%285-minut
es%29

Ejemplos:
https://github.com/zznate/hector-examples
https://github.com/zznate/cassandra-tutorial
https://github.com/riptano/twissjava

Inicializar BBDD con create-twissjava-db.txt


Ejecutar: mvn jetty:run
Ir a: http://localhost:8888/
mvn clean
64

CouchDB
CouchDB es una base de datos open
source orientada a documentos, accesible
mediante una API RESTful que hace uso
extensivo de JavaScript Object Notation
(JSON)
"Couch" es el acrnimo de"Cluster Of
Unreliable Commodity Hardware"
Su misin es ser muy escalable, con alta
disponibilidad y robustez, incluso cuando se ejecuta
en hardware convencional

Creada como database of the Web


Django may be built for the Web, but CouchDB is built of the
Web. Ive never seen software that so completely embraces
the philosophies behind HTTP. CouchDB makes Django look
65
old-school in the same way that Django makes ASP look

Caractersticas de
CouchDB

CouchDB es una base de datos orientada a documentos


JSON escrita en Erlang.
Parte de la generacin de bases de datos NoSQL
Es un proyecto open source de la fundacin Apache

Es altamente concurrente, diseada para ser replicada


horizontalmente, a travs de varios dispositivos y tolerante
a fallos.
Permite a las aplicaciones guardar documentos JSON a
travs de una interfaz RESTful
Utiliza map/reduce para indexar y consultar la base de
datos
Permite escribir una aplicacin cliente que habla
directamente va HTTP con CouchDB sin necesidad de una
capa servidora intermedia
Guarda datos en local en la propia mquina cliente para
66
reducir latencia

CouchDB: BBDD orientada a


documentos
Una BBDD document-oriented est compuesta de una serie
de documentos
Son libres de esquema; no existe un esquema definido a priori,
antes de usar la BBDD
Si un documento necesita un nuevo campo, puedes incluirlo, sin
afectar a otros documentos en la BBDD

CouchDB no tiene una funcionalidad de auto-increment o


secuencia
Asigna un Universally Unique Identifier (UUID) a cada
documento, haciendo casi imposible que otra base de datos
seleccione el mismo identificador

No soporta JOINs como las bases de datos relacionales


Una caracterstica denominada vista permite crear relaciones
arbitrarias entre documentos que no son definidas en las
propias bases de datos.

CouchDB ofrece una alternativa a todos aquellos proyectos


donde un modelo orientado 67
a documentos encaja mejor

Ventajas de CouchDB

Documentos JSON todo lo que se guarda en CouchDB


son simplemente documentos JSON.
Interfaz RESTful desde la creacin a la replicacin a la
insercin de datos, toda la gestin de datos en CouchDB
puede ser realizada va HTTP.
Replicacin N-Master puedes hacer uso de un nmero
ilimitado de masters, dando lugar a topologas de
replicacin muy interesantes.
Escrita para ejecutarse offline CouchDB puede
replicarse en dispositivos (e.j. telfonos Android) que
pueden quedarse sin conexin y gestionar sincronizacin
de datos cuando el dispositivo est online de nuevo
Filtros de replicado puedes filtrar de modo preciso los
datos que quieres replicar a distintos nodos.
http://wiki.apache.org/couchdb/Replication#Filtered_Replication
68

Quin usa CouchDB?


Un largo listado de software y
websites que hacen uso de CouchDB
puede encontrarse en:
http://wiki.apache.org/CouchDB/CouchD
B_in_the_wild?action=show&redirect=In
TheWild

69

Conceptos clave en
CouchDB: Documentos
Una base de datos en CouchDB es
una coleccin de documentos,
donde cada uno est identificado por
un ID y contiene un conjunto de
campos nombrados:
Los campos pueden ser strings,
nmeros, fechas o incluso listas
ordenadas y diccionarios.
Ejemplos de documentos seran:
"Subject": "I like Plankton,
70
"Tags": ["plankton", "baseball",

Conceptos clave en
CouchDB: Documentos

Las BBDD CouchDB guardan documentos nombrados de modo


unvoco y proporcionan una API RESTful JSON que permite a las
aplicaciones leer y modificar estos documentos
Cada documento puede tener campos no definidos en otros
documentos:
Los documentos no estn asociados a un esquema de bases de datos
estricto

Cada documento contiene metadatos (datos sobre datos) como el


identificador unvoco del documento (id) y su nmero de
revisin (rev)
Los campos de un documento pueden ser de varios tipos como
strings, nmeros, booleanos, colecciones, etc.
Cuando se hacen cambios sobre un documento CouchDB se crea
una nueva versin del documento, denominado revisin
Se mantiene un historial de modificaciones gestionado
automticamente por la BBDD

CouchDB no dispone de mecanismos de bloqueo (locking) ante


71
escrituras

Conceptos clave en
CouchDB: Vistas
Son el mecanismo para aadir estructura a datos
semi-estructurados
El modelo de vistas en CouchDB usa JavaScript
para describirlas
Las vistas son el mtodo para agregar y realizar
informes sobre los documentos de un repositorio,
siendo creados en demanda para agregar y
agregar documentos.
Las vistas se construyen dinmicamente y no
afectan el documento subyacente, puedes tener
tantas representaciones de vistas de los mismos
datos como gustes.
72

Conceptos clave en
CouchDB: Vistas

CouchDB es desestructurado en naturaleza, adolece de un


esquema estricto pero provee beneficios en trminos de
flexibilidad y escalabilidad, explotar sus datos en aplicaciones
reales a veces puede hacerse complicado
Los datos se guardan en un espacio de almacenamiento plano, algo as
como un repositorio de datos desnormalizados.
Proporciona un modelo de vistas para aadir estructura a los datos de
modo que pueda agregarse para aadir significado til

Las vistas se crean en demanda y son utilizadas para agregar,


enlazar y reportar sobre documentos en la base de datos
Se definen en documentos de diseo y pueden ser replicadas a travs
de varias instancias
Estos documentos de diseo contienen funciones JavaScript que
pueden ejecutar consultas mediante el concepto de MapReduce.
La funcin Map de la vista recibe un documento como argumento
y realiza una serie de clculos para determinar qu datos deberan
ser disponibles en la vista
Si la vista tiene una funcin
Reduce, es usada para agregar los
73
resultados. A partir de un conjunto de pares clave/valor devuelve

Ejemplo de Vista en
CouchDB
map: function(doc) {
if (doc._attachments) {
emit("with attachment", 1);
}
else {
emit("without attachment", 1);
}
}
reduce: function(keys, values) {
return sum(values);
}
74

Conceptos clave en
CouchDB:
Sin
esquema
CouchDB est diseado para almacenar y
reportar sobre grandes volmenes de datos
orientados a documentos semi-estructurados.
Con CouchDB, no se impone ningn esquema,
nuevos tipos de documentos con distintos
campos y significados se pueden unir a los
existentes.
El motor de vistas, apoyado en JavaScript, est
diseado para facilitar la gestin de nuevos tipos
de documentos y variados pero similares
documentos.
75

Conceptos clave:
Distribuida
CouchDB es un sistema distribuido de base de
datos basado en nodos
Un nmero variable de nodos CouchDB (servidores y
clientes offline) pueden tener copias de rplicas
independientes de la misma BBDD, donde las
aplicaciones pueden tener interactividad completa con
la BBDD (consultar, aadir, editar y borrar)
Cuando vuelven a estar online o de modo planificado, los
cambios de las bases de datos son replicados
bidireccionalmente.

CouchDB tiene gestin de conflictos incorporada


de serie, haciendo que el proceso de replicacin
sea incremental y rpido, copiando slo
documentos y campos individuales modificados
76
desde la ltima replicacin.

Gestin de Conflictos
MVCC
Los documentos en CouchDB son versionados, de
modo similar a como se realiza en sistemas de
control de versiones como Subversion.
Si cambias un valor de un documento, realmente
creas una nueva versin del mismo que coexiste
con la versin antigua
Las peticiones se ejecutan en paralelo haciendo
que los servidores permitan una alta concurrencia
Una peticin de lectura ver siempre la versin ms
reciente de la BBDD

77

Teorema CAP en
CouchDB

El teorema CAP dice que en BBDD


distribuidas slo dos de los siguientes
propiedades pueden cumplirse:
Consistency
Todas las bases de datos cliente ven los mismos
datos, incluso cuando se producen
actualizaciones concurrentes.

Availability
Todos los clientes pueden acceder a los datos.

Partition tolerance
La base de datos puede partirse a mltiples
servidores

CouchDB sacrifica consistencia inmediata a


cambio de obtener un mayor rendimiento a
travs de distribucin de la informacin
78

Detalles tcnicos
Un servidor CouchDB gestiona bases de datos
bajo un nombre, que almacenan documentos:
Cada documento tiene un nombre nico en la BBDD y
CouchDB proporciona una API HTTP RESTful para leer y
modificar (aadir, editar y borrar) documentos de la
BBDD.
Los documentos son la unidad de datos primaria en
CouchDB y consisten de un nmero variable de campos
y adjuntos
Las modificaciones sobre documentos (aadir, editar,
borrar) son del todo o de nada, o se modifican
completamente o fallan completamente.
El modelo de modificacin de documentos de CouchDB
es optimista y no hace uso de locks.
Ms detalles genricos en:
79
http://CouchDB.apache.org/docs/overview.html

Modelo de Vistas
Para aadir estructura a datos no estructurados o
semi-estructurados, CouchDB incorpora el modelo
de vistas
Se crean dinmicamente y no afectan al documento
subyacente
Se definen dentro de documentos de diseo
Se replican a otras instancias de la base de datos como
si fueran documentos convencionales
En CouchDB slo se replican datos, aunque esos datos a
menudo (cdigo JavaScript) puede corresponder a
aplicaciones.

Para garantizar un alto rendimiento, el motor de


vistas mantiene ndices de sus vistas e
incrementalmente las actualiza para reflejar los
80
cambios en la base de datos.

Map/Reduce en CouchDB
Usar Map/Reduce tiene ventajas
sobre consultas SQL porque pueden
ser distribuidas entre varios nodos,
algo que no puede hacerse con
RDBMS.
Las bases de datos NoSQL utilizan
map/reduce para consultar e indexar
la BBDD
map consiste en extraer los datos a
procesar
81

Instalacin de CouchDB
Dependencias:
Runtime

Build

Couch
DB

Spider
monke
y

Erlang

ICU

cURL

Autom
ake

Autoc
onf

0.9.x

==1.7

>=5.6.
0

>= 3.0

>=
7.15.5

>=
1.6.3

>=
2.59

0.10.x

>=1.7
&&
<=1.8.
0

>=5.6.
5

>= 3.0

>=
7.18.0

>=
1.6.3

>=
2.59

Detalles de instalacin:

>=5.6.
>=
>=
>=
http://wiki.apache.org/CouchDB/Installation
0.11.x
>=1.7
>= 3.0
5
7.18.0
1.6.3
2.59
Instrucciones detalladas para Windows en:
https://github.com/LearningRegistry/LearningRegistry
/wiki/Windows-Installation-Guide

Curl
Visual C++ 2008 Redistributable Setup
OpenSSL
Configurar %PATH% para82
que apunte a los dirs de instalacin
dependencias

Instalacin en Windows y
Linux
Algunos enlaces de ayuda para Windows:
http://niallodoherty.com/post.cfm/installing-C
ouchDB-on-windows-quick-guide
http://wiki.apache.org/CouchDB/Quirks_on_Win
dows

Instalacin en Linux:
Tan simple como: sudo aptitude install
couchdb
http://wiki.apache.org/couchdb/Installing_on_U
buntu

Para lanzar el servidor de CouchDB


ejecutar el comando83 couchdb en el
directorio bin de instalacin.

Instalacin CouchDB
Sin embargo, lo ms sencillo es:
Ir a CouchBase (
http://www.couchbase.com/downloads)
Descargarse el binario de tu plataforma
Seleccionar Enteprise Edition/Membase Server

Abrir el administrador grfico de bases de


datos en CouchDB, denominado Futon:
http://127.0.0.1:5984/_utils/
Recomendable instalar la extensin FireBug para FireFox:
http://getfirebug.com/ :
Permite editar, depurar y monitorizar CSS, HTML y JavaScript
dinmicamente sobre cualquier pgina
Caractersticas descritas en: https://getfirebug.com/whatisfirebug
84

CouchDB Futon
Futon: http://localhost:5984/_utils/
Hace uso internamente de la librera
http://127.0.0.1:5984/_utils/script/jquery.co
uch.js
Lo primero que hay que hacer es hacer
click en Fix Me para asegurarnos que slo
usuarios autorizados pueden acceder a
CouchDB
Nosotros usaremos la combinacin
admin/enpresadigitala
85

La API RESTful JSON


CouchDB ofrece una API como mecanismo para recuperar
datos de una BBDD.
Donde siguiendo la convencin REST: (si no aparece la sabes
para crear POST y sino PUT)

POST crea un nuevo registro


GET lee registros
PUT actualiza un registro
DELETE borra un registro

Esta API es accesible va HTTP GET y POST y retorna datos


en el formato de objetos JavaScript mediante JSON.
Una ventaja de este enfoque es que puede usarse una
framework AJAX como Prototype o jQuery para crear una
aplicacin web, sin necesidad de hacer uso de un lenguaje de
parte servidora
La herramienta de lnea de comando CURL pueden ser usada
como cliente de lnea de comandos HTTP:
Descargable de: http://curl.haxx.se/
Permite realizar peticiones GET,POST,PUT, yDELETE, mostrando
la respuesta HTTP recibida del
86 servidor web

Probando la API RESTful


de CouchDB con curl

$ curl http://127.0.0.1:5984/

Respuesta: {"CouchDB":"Welcome","version":"1.1.1"}

O explcitamente define el tipo de peticin realizada a travs del parmetro


-X de curl:

$ curl -X GET http://127.0.0.1:5984/_all_dbs

Para crear dos nuevas bases de datos, ejecutaramos los comandos:

$ curl -uadmin:enpresadigitala -X PUT http://127.0.0.1:5984/fruit

Respuesta: {"ok":true}

$ curl -uadmin:enpresadigitala -X PUT


http://127.0.0.1:5984/vegetables

Si ejecutamos ahora:

Respuesta:
["_replicator","_users","nerekurtsoak","test_suite_reports","testdb","users
"]

$ curl -X GET http://127.0.0.1:5984/_all_dbs


Obtendramos:
["_replicator","_users","fruit","nerekurtsoak","test_suite_reports",
"testdb","users"]

Si intentamos volver a crear una BBDD ya existente, recibimos un error:

$ curl -X PUT http://127.0.0.1:5984/fruit


Respuesta: {"error":"file_exists","reason":
87 the file already exists.}
"The database could not be created,

Probando la API RESTful


de CouchDB con curl

Podemos borrar una base de datos con el siguiente comando:

Para crear un documento:

$ curl -uadmin:enpresadigitala -X PUT


http://127.0.0.1:5984/fruit/apple -H "Content-Type:
application/json" -d {}
Respuesta: {"ok":true,"id":"apple","rev":"1967a00dff5e02add41819138abb3284d"}

Para recuperarlo:

$ curl -uadmin:enpresadigitala -X DELETE


http://127.0.0.1:5984/vegetables
Respuesta: {"ok":true}

$ curl -X GET http://127.0.0.1:5984/fruit/apple


Respuesta: {"_id":"apple","_rev":"1967a00dff5e02add41819138abb3284d"}

Para recuperar informacin de la BBDD:

$ curl -X GET http://127.0.0.1:5984/fruit


Respuesta:
{"db_name":"fruit","doc_count":1,"doc_del_count":0,"update_seq":1,"p
urge_seq":0,
"compact_running":false,"disk_size":4179,"instance_start_time":"1321
991208171560","disk_format_version":5,"committed_update_seq":1}
88

Programando CouchDB
Gracias a la API RESTful, los
desarrolladores pueden conectarse a
CouchDB usando cualquier software que
soporte HTTP
La mayora de los lenguajes modernos
ofrecen algn tipo de interfaz HTTP,
implicando que CouchDB puede ser usada
en cualquier proyecto de desarrollo.
Revisar la siguiente pgina para diferentes
clientes programticos a CouchDB:
http://wiki.apache.org/CouchDB/Related_Projects
89

Primeros pasos con


CouchDB
Vamos a seguir el tutorial en:
http://net.tutsplus.com/tutorials/get
ting-started-with-CouchDB/
Asegrate de crear una cuenta de
admin/enpresadigitala

Otros tutoriales:
http://www.catswhocode.com/blog/gettin
g-started-with-CouchDB-tutorial-a-begi
nners-guide
90

Primeros pasos en
CouchDB

91

Primeros Pasos en CouchDB

En Futon:
1.

Crearemos la base de datos haciendo click en Create


Database, de nombre "nerekurtsoak"
2. Hacer click en New Document

Vete aadiendo campos a travs de ADD Field

3.

"name" : Curso NoSQL


"price" : 30

Guarda cada campo


Guarda el documento

Modificar el documento ya existente aadiendo el


campo "type" con valor "course"

La nueva versin del documento debera empezar por 2

92

Primeros Pasos en Curl


1.

Creemos un documento persona.json con el siguiente


contenido:
{
"forename": "Diego",
"surname": "Lopez-de-Ipina",
"type":
"person"
}

2.

Usamos el siguiente comando de CURL para subir el


documento a CouchDB:

curl -X POST http://127.0.0.1:5984/nerekurtsoak/ -d


@persona.json -H "Content-Type: application/json"
Se devolvera:

3.

{"ok":true,"id":"b54b3496d090c43a4266180ecb002a92","rev
":"1-93c73d298af443f623db6861f90e9f6e"}

Para recuperar todos los documentos:

93
curl -X GET
http://127.0.0.1:5984/nerekurtsoak/_all_docs

Vista de un documento
en Futon

94

Creando una funcin


Map
Seleccionar Temporary View en the Drop
View dentro de Futon
La funcin map tendra el siguiente cdigo:
function (doc) {
if (doc.type == "course" && doc.name) {
emit(doc.name, doc);
}
}

Accede a ella a travs del navegador como:


http://127.0.0.1:5984/_utils/database.html?nerekurts
oak/_design/courses/_view/courses
95

Creando un Reduce

Nos aseguraremos de tener al menos dos cursos con precio


Definir la funcin de mapeo como:
function (doc) {
if (doc.type === "course" && doc.price) {
emit(doc.id, doc.price);
}
}

Definir la funcin reduce como:


function (keys, prices) {
return sum(prices);
}

Guardarlo como coursePrices, asegurarse de hacer click


en Reduce
Ir a
http://127.0.0.1:5984/_utils/database.html?nerekurtsoak/_d
esign/courseprices/_view/courseprices
96

Creando un Reduce

97

Documentos de Diseo
en CloudDB
Los documentos de diseo son un tipo especial de
documento en CouchDB que contiene cdigo de
aplicacin:
Vistas MapReduce, validaciones, funciones show, list y
update

Se suele crear un documento de diseo por cada


aplicacin
El documento de diseo es un documento
CouchDB con un ID que comienza con _design/:
Se replica como otros documentos en la BBDD y soporta
gestin de conflictos a travs del parmetro rev
CouchDB mira las vistas y otras funciones de aplicacin en
l
98 de la aplicacin aparecen como
Los contenidos estticos

Estructura interna de un
Documento de Diseo
Estn compuestos de:
Funciones de validacin
Definicin de vistas
Funciones show, list y
update
Attachments

Una BBDD CouchDB puede


tener varios documentos de
diseo.
_design/calendar
_design/contacts

Para recuperar un
documento de diseo haz un
GET con el siguiente patrn
de URL:
http://localhost:5984/my
99
db/_design/calendar

Vistas: funciones map

Las funciones vistas en CouchDB son strings guardados en el


campo views del documento de diseo
Los resultados de un vista se guardan en un B-tree, al igual que
todo documento
Estos rboles permiten realizar bsquedas de filas por clave y
recuperar rangos de filas

Todas las funciones map tienen un nico parmetro doc:


function(doc) {
if(doc.date && doc.title) {
emit(doc.date, doc.title);
}
}

Las funciones map son funciones libres de efectos laterales que


toman un documento como argumento y emiten pares clave/valor:
Generan una lista ordenada por la clave de las filas

Tenemos varios parmetros para recuperar resultados:


Una sola fila: _design/docs/_view/date?key="2009/01/30
18:04:11"
Varias filas: _design/docs/_view/date?startkey="2010/01/01
100
00:00:00"&endkey="2010/02/00 00:00:00&descending=true

Vistas: funciones reduce


Las funciones reduce operan sobre las filas ordenadas
emitidas por las funciones map
Dada la manera en que los rboles B-tree estn
estructurados, podemos cachear los resultados intermedios
de un reduce en los nodos no-hoja
El formato de una funcin reduce en una vista es el
siguiente:
function(keys, values, rereduce) {
return sum(values)
}

La funcin reduce se ejecuta sobre cada nodo del rbol


para calcular el resultado final que es un valor escalar:
Cuando se ejecuta sobre las hojas del rbol (que contiene filas
del mapa), el parmetro rereduce es false
Cuando se ejecuta en los nodos internos del rbol, el valor de
rereduce es true
101

Configuracin de vistas

Se definen en el documento de diseo como sigue:


{
"_id": "_design/application",
"_rev": "1-C1687D17",
"views": {
"viewname": {
"map": "function(doc) { ... }",
"reduce": "function(keys, values) { ... }"
},
"anotherview": {
"map": "function(doc) { ... }",
"reduce": "function(keys, values) { ... }"
}
}
}

Para acceder a ellas se realiza un HTTP GET a


/database/_design/application/_view/viewname
102

Recetas: De SQL a
MapReduce
SELECT field FROM table WHERE
value="searchterm
La funcin map sera:
function(doc) {
if(doc.age && doc.name) {
emit(doc.age, doc.name);
}
}

Y la consulta:
/ladies/_design/ladies/_view/age?key=5

Documentacin:
http://guide.CouchDB.org/draft/cookbook.h
tml
103

Recetas: De SQL a
MapReduce

SELECT field FROM table WHERE value LIKE "searchterm%"


Para un documento:
{
"_id": "Hugh Laurie",
"_rev": "1-9fded7deef52ac373119d05435581edf",
"mime-type": "image/jpg",
"description": "some dude"
}

La funcin map sera:


function(doc) {
if(doc["mime-type"]) {
var prefix = doc["mime-type"].match(/^[^\/]+\//);
if(prefix) {
emit(prefix, null);
}
}
}

Y la consulta:
/files/_design/finder/_view/by-mime-type?key="image/"
104

Validaciones

CouchDB usa la funcin validate_doc_update para evitar que


documentos invlidos o no autorizados sean procesados.
CouchDB enva las funciones y documentos a un intrprete de JavaScript
La funcin validate_doc_update se ejecuta para cada documento a crear
o actualizar

Si lanza una excepcin, la actualizacin es rechazada

El formato de una funcin de validacin es el siguiente:


function(newDoc, oldDoc, userCtx) {
function require(field, message) {
message = message || "Document must have a " + field;
if (!newDoc[field]) throw({forbidden : message});
};
if (newDoc.type == "post") {
require("title");
require("created_at");
require("body");
require("author");
}
}
105

Funciones show y list

CouchDB permite generar respuestas en formatos distintos a JSON


Los campos del documento de diseo show y list contienen funciones
utilizadas para transformar documentos JSON en HTML, XML u otros
Content-Types
Estas funciones son como acciones de una framework web, pero no tienen
efectos laterales, es decir, solamente realizan peticiones de recuperacin
de informacin, no cambian nada o inician procesos o lanzan otras
funciones

Las funciones show se invocan del siguiente modo:


GET /mydb/_design/mydesign/_show/myshow/72d43a93eb74b5f2
donde myshow es una entrada dentro del campo shows del documento de
diseo y 72d43a93eb74b5f2 es la clave del documento a mostrar

El formato de una funcin show es:


function(doc, req) {
return "<p>Aye aye, " + req.parrot + "!</p>";
}

Se suelen utilizar combinados con plantillas y con macros


JavaScript de couchapp como !code y !json
106

Funcin list

Las funciones list en CouchDB permiten generar salida de vistas en cualquier


formato

Son guardadas bajo el campo lists del documento de diseo:


{
"_id" : "_design/foo",
"_rev" : "1-67at7bg",
"lists" : {
"bar" : "function(head, req) { var row; while (row = getRow()) { ... } }",
"zoom" : "function() { return 'zoom!' }",
}
}

La funcin es invocada con dos argumentos: head y req

Donde head tiene el formato: {total_rows:10, offset:0}


Donde req es el mismo objeto que reciben las funciones show, update y filter, conteniendo:
{ "info": {
"db_name": "test_suite_db","doc_count": 11,"doc_del_count": 0,
"update_seq": 11,"purge_seq": 0,"compact_running": false,"disk_size": 4930,
"instance_start_time": "1250046852578425","disk_format_version": 4},
"method": "GET",
"path": ["test_suite_db","_design","lists","_list","basicJSON","basicView"],
"query": {"foo":"bar"},
"headers":
{"Accept": "text/html,application/xhtml+xml ,application/xml;q=0.9,*/*;q=0.8",
"Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7","Accept-Encoding":
"gzip,deflate","Accept-Language": "en-us,en;q=0.5","Connection": "keep-alive", }
"body": "undefined",
"form": {},
"userCtx": {"db": "test_suite_db","name": null,"roles": ["_admin"]}

107

Funcin list

Para ejecutar una funcin list usamos el siguiente formato:


/db/_design/foo/_list/list-name/view-name
Dado que el nombre de la lista y de la vista son especificados, esto
implica que es posible usar la lista para ms de una vista.

Una funcin list de ejemplo sera:


function(head, req) {
var row;
start({
"headers": {
"Content-Type": "text/html"
}
});
while(row = getRow()) {
send(row.value);
}
}

Documentacin de funciones show y list en:


http://wiki.apache.org/CouchDB/Formatting_with_Show_and_List
108

Funcin update

La funcin update se utiliza para gestionar POSTs y transformarlos en nuevos


documentos

Son funciones que los clientes invocan para crear o actualizar documentos
Devuelven el nuevo documento y una respuesta al cliente
Para modificar, enviar peticin PUT en el formato:

Para crear una nueva instancia, hacer POST en el formato:

/<database>/_design/<design>/_update/<function>/<docid>
/<database>/_design/<design>/_update/<function>

En el documento de diseo se creara lo siguiente:


{ updates: {
"hello" : "function(doc, req) {
if (!doc) {
if (req.id) {
return [{
_id : req.id
}, 'New World']
}
return [null, 'Empty World'];
}
doc.world = 'hello';
doc.edited_by = req.userCtx;
return [doc, 'hello doc'];
}
}
109

Documentacin en: http://wiki.apache.org/CouchDB/Document_Update_Handlers

CouchApp
A CouchApp es una framework para la creacin
de aplicaciones JavaScript con CouchDB
Como son aplicaciones JavaScript y HTML5 son
servidas directamente desde CouchDB
Como efecto lateral consigues la flexibilidad y
escalabilidad de CouchDB

http://couchapp.org/
Para crear una CouchApp, necesitas un modo
para meter JavaScript, HTML y otros recursos en
CouchDB
La herramienta CouchApp escrita en Python es la
recomendada para generar plantillas de cdigo en tu
aplicacin y volcarlos a una instancia de CouchDB:
110
http://couchapp.org/page/couchapp-python

CouchApp
CouchApp te simplifica la labor de crear
aplicaciones web a partir de CouchDB:
Fragmenta un documento de diseo en un conjunto de
directorios y ficheros del sistema local, representando
views, shows, validations, attachments, etc. que sern
enviados al servidor CouchDB

Una aplicacin de Couch, CouchApp, sigue ms o


menos el patrn de diseo
Modelo/Vista/Controlador:
CouchDB es el Modelo
El rbol DOM representando el HTML mostrado al
usuario sera la vista
El JavaScript sera el Controller
111

Instalacin de CouchApp
Requiere la ltima versin de Python 2.x
Para las distintas plataformas seguir las instrucciones
en:
http://couchapp.org/page/installing

En Windows:
Seguir instrucciones de:
http://couchapp.org/page/windows-python-installers
Instalar Python 2.7.2:
http://www.python.org/download/releases/2.7.2/
Instalar la herramienta setuptools que incluye instalador de
aplicaciones que permite descargar, construir, instalar y
gestionar paquetes Python automticamente
http://packages.python.org/distribute/easy_install.html

Aadir a PATH C:\Programming\Python27\Scripts

Instalar las extensiones de Python para Windows: pywin32214.win32-py2.7.exe


Instalar Couchapp-0.7.5.win32.exe
112

Hola Mundo con


CouchApp

Los pasos a seguir sern los siguientes:


1.

Usar el comando couchapp para que genere la estructura de


tu aplicacin:
couchapp generate helloworld

2.

Crear una funcin show que devuelve el mensaje "Hello


world"
cd helloworld
couchapp generate show hello
Editar el fichero generado "hello.js" con el siguiente contenido:
function(doc, req) {
return "Hello World";
}

3.

Subirlo a tu servidor de bases de datos, bajo la base de


datos, http://127.0.0.1:5984/testdb :
couchapp push testdb
couchapp push .
http://admin:enpresadigitala@127.0.0.1:5984/testdb
113

Hola Mundo con


CouchApp
4. Comprobar que se ha subido correctamente yendo a:

http://127.0.0.1:5984/testdb/_design/helloworld/_show/hello

5. Se puede clonar una aplicacin ya existente con el


siguiente comando, que cogera una nueva versin en
helloworld2:

couchapp clone
http://127.0.0.1:5984/testdb/_design/helloworld
helloworld2

114

Mi primera aplicacin
seria
con
CouchApp
El objetivo es crear un libro de direcciones usando HTML5
servido desde CouchApp
Cogido de:
http://blog.edparcell.com/using-jquery-and-CouchDB-to-build-a
-simple-we

Los pasos a seguir:


1.
2.

Crear base de datos "addressbook" con Futon


Crea los siguientes dos documentos en la base de datos:
{"type": "address", "name": "Fred", "mobile": "5550001"}
{"type": "address", "name": "Barney", "mobile": "5550002"}

3.

Generamos la aplicacin y una vista para ella, subiendo la


aplicacin:
couchapp generate app addressbook
couchapp generate view addressbook phonenumbers
couchapp push addressbook
115
http://127.0.0.1:5984/addressbook

Mi primera aplicacin
seria
con
CouchApp
4. Una vez creada la vista, la editamos de la siguiente
manera:
Borramos addressbook/views/phonenumbers/reduce.js
Editamos el fichero
addressbook/views/phonenumbers/map.js con:
function(doc) {
if (doc.type && doc.type == "address" && doc.name && doc.mobile) {
emit(doc.name, doc.mobile);
}
}

5. Comprueba que funciona la vista yendo a:


http://127.0.0.1:5984/addressbook/_design/addressbook/_v
iew/phonenumbers

116

Mi primera aplicacin
seria
con CouchApp

6. Modifica el contenido de _attachments \index.html con lo siguiente, sbelo a


CouchDB y vete a http://127.0.0.1:5984/addressbook/_design/addressbook/index.html
:
<!DOCTYPE html>
<html>
<head>
<title>Simple address book</title>
<link rel="stylesheet" href="style/main.css" type="text/css">
<span style="white-space: pre;"> </span><script src="/_utils/script/json2.js"></script>
<span style="white-space: pre;"> </span><script src="/_utils/script/jquery.js?
1.3.1"></script>
<span style="white-space: pre;"> </span><script src="/_utils/script/jquery.couch.js?
0.9.0"></script>
<span style="white-space: pre;"> </span><script type="text/javascript">
<span style="white-space: pre;"> </span></script>
</head>
<body>
<h1>Simple address book</h1>
<span style="white-space: pre;"> </span><div id="add"><button type="button"
id="add">Add</button></div>
<div id="addressbook"></div>
</body>
</html>

117

Mi primera aplicacin
seria
con CouchApp
7.

Modificamos el index.html introduciendo JavaScript que se activa cuando la pgina acaba de cargarse.

El cdigo aadido recupera un documento JSON de la vista phonenumbers desde CouchDB

Itera sobre cada fila de la vista, aadiendo un elemento div por cada fila conteniendo el nombre, phonenumber y
enlaces para editarlos y borrarlos:
$db = $.couch.db("addressbook");
function refreshAddressbook(){
$("div#addressbook").empty();
$db.view("addressbook/phonenumbers", {
success: function(data){
for (i in data.rows) {
id = data.rows[i].id;
name = data.rows[i].key;
phonenumber = data.rows[i].value;
html = '<div class="address">' +
'<span class="name">' + name + '</span>&nbsp;' +
'<span class="phonenumber">' + phonenumber + '</span>&nbsp; ' +
'<a href="#" id="' + id + '" class="edit">edit</a>&nbsp;|&nbsp;' +
'<a href="#" id="' + id + '" class="delete">delete</a>' +
'</div>';
$("div#addressbook").append(html);
}
}
});
}
$(document).ready(function() {
refreshAddressbook();
});

8.

Lo subimos al servidor: couchapp push addressbook http://127.0.0.1:5984/addressbook

118

Mi primera aplicacin
seria
con CouchApp
9. Para aadir elementos aadimos el siguiente formulario web:

function addUpdateForm(target, existingDoc) {


html = '<form name="update" id="update" action=""><table>' +
'<tr><td>Name</td><td>Number</td></tr>' +
'<tr>' +
'<td><input type="text" name="name" id="name" value="' +
(existingDoc ? existingDoc.name : "" ) + '"></td>' +
'<td><input type="text" name="mobile" id="mobile" value="' +
(existingDoc ? existingDoc.mobile : "") + '"></td>' +
'</tr><tr>' +
'<td><input type="submit" name="submit" class="update" value="' +
(existingDoc ? "Update" : "Add") + '"></td>' +
'<td><input type="submit" name="cancel" class="cancel" value="Cancel"/></td>' +
'</tr>' +
'</table></form>';
target.append(html);
target.children("form#update").data("existingDoc", existingDoc);
}

10. Para editar el formulario deberamos hacer:


id = $tgt.attr("id");
if ($tgt.hasClass("edit")){
if ($tgt.hasClass("edit")) {
$("button#add").show();
$("form#update").remove();
$db.openDoc(id, { success: function(doc) {
addUpdateForm($tgt.parent(), doc);
}});
}
119
}

Mi primera aplicacin
seria
con CouchApp
11. Y para aadirlo:

$("button#add").click(function(event) {
$("form#update").remove();
$("button#add").hide();
addUpdateForm($("div#add"));
});

12. Finalmente aadimos la parte de lgica para aadir y editar elementos:


$("input.update").live('click', function(event) {
var $tgt = $(event.target);
var $form = $tgt.parents("form#update");
var $doc = $form.data('existingDoc') || {};
$doc.type = "address";
$doc.name = $form.find("input#name").val();
$doc.mobile = $form.find("input#mobile").val();
$db.saveDoc(
$doc, {
success: function(){
$("button#add").show();
$("form#update").remove();
refreshAddressbook();
}
}
);
return false;
})

120

Mi primera aplicacin
seria
con CouchApp
13. Modify index.html to allow contact deleting:

$(document).ready(function() {
refreshAddressbook();
$("div#addressbook").click(function(event) {
var $tgt = $(event.target);
if ($tgt.is('a')) {
id = $tgt.attr("id");
if ($tgt.hasClass("edit")) {
// TODO: implement edit functionality
}
if ($tgt.hasClass("delete")) {
html = '<span class="deleteconfirm">Sure? <a href="#" class="dodelete">Yes</a> <a
href="#" class="canceldelete">No</a></span>';
$tgt.parent().append(html);
}
if ($tgt.hasClass("dodelete")) {
$db.openDoc(id, { success: function(doc) {
$db.removeDoc(doc, { success: function() {
$tgt.parents("div.address").remove();
}})
}});
}
if ($tgt.hasClass("canceldelete")) {
$tgt.parents("span.deleteconfirm").remove();
}
}
});
121
});

Mi primera aplicacin
seria
con
CouchApp
14.Finalmente habra que subir la aplicacin a CouchDB con el
comando:
$ cd <parent-dir-addressbook-app>
$ couchapp push addressbook
http://admin:enpresadigitala@127.0.0.1:5984/addressbook

. Un ejemplo completo de CouchApp que incluye todas las


caractersticas (funciones) de un documento de diseo puede
encontrarse en:
Sofa-blog: https://github.com/jchris/sofa
Para instalar: couchapp push .
http://admin:enpresadigitala@127.0.0.1:5984/myblogdb

La implementacin de esta aplicacin es descrita paso a paso en:


http://guide.CouchDB.org/editions/1/en/standalone.html

122

Escalabilidad en
CouchDB
CouchDB permite hacer escalado en
tres niveles:
Escalando peticiones de lectura
Se resuelve mediante una cach

Escalando peticiones de escritura


Hay que utilizar tcnicas de scaling

Escalando datos
La solucin es dividir los datos en cachos
(chunks) y colocarlos en diferentes
servidores
Todos los servidores conteniendo chunks
123
conforman un clster

Replicacin en CouchDB
La replicacin sincroniza dos copias de la
misma BBDD, permitiendo que los
usuarios tengan baja latencia de acceso a
datos independientemente de su
localizacin
La replicacin consiste en enviar una peticin
HTTP a un servidor CouchDB incluyendo una
BBDD de origen y otra de destino, haciendo
que CouchDB enve los cambios del origen al
destino:
POST /_replicate HTTP/1.1
{"source":"database","target":http://example.
124
org/database}

Replicacin en CouchDB
Para enviar cambios se sigue utilizando la misma
llamada
Cuando solicitas a CouchDB que replique una BBDD en
otra, comparar ambas para encontrar qu documentos
en el origen difieren de los del destino y luego enviar
todos los cambios al destino en batch
Las bases de datos en CouchDB tienen un nmero de
secuencia que es incrementado cada vez que la BBDD se
cambia

Hay diferentes modos de replicacin:


Replicacin normal, en demanda
Replicacin continua, cada vez que produce un
cambio ste se propaga
Aades "continuous":true al objeto de lanzamiento de
125
replicacin

Replicacin con Futon

Abre tu navegador en Futon: http://127.0.0.1:5984/_utils/

Haz clic en Replicator


Selecciona BBDD a replicar
Haz clic en continuous
Haz clic en el botn Replicate

Alternativamente desde lnea de comando:


curl -uadmin:enpresadigitala -X DELETE
http://127.0.0.1:5984/nerekurtsoak_rep2
curl -uadmin:enpresadigitala -X PUT
http://127.0.0.1:5984/nerekurtsoak_rep2
curl -uadmin:enpresadigitala -X POST
http://127.0.0.1:5984/_replicate -H "Content-Type:
application/json" -d @replication-example.json

Donde replication-example.json contiene:


'{"source":"http://127.0.0.1:5984/nerekurtsoak",
"target":http://admin:enpresadigitala@127.0.0.1:5984/nereku
rtsoak_rep2, "continuous":true}'
126

Gestin de Conflictos
Cuando replicas dos BBDD en CouchDB y se
identifican conflictos, CouchDB los seala en los
documentos afectados con el atributo
"_conflicts":true
La versin que es seleccionada como ltima es la
versin ganadora.
La revision perdedora es almacenada como versin
anterior.
CouchDB no hace un merge de las revisiones
conflictivas.
Tu aplicacin es la que resuelve programticamente los
conflictos

La replicacin garantiza que los conflictos se detecten y


que cada instancia de CouchDB haga la misma seleccin
respecto a ganadores y 127
perdedores,

Resolucin de conflictos
por ejemplo
La base de datos A se replica en B:

Creamos un documento en A

Forzamos replicacin:

128

Resolucin de conflictos
por ejemplo
Creamos una nueva versin del
documento en B:

Aadimos una nueva versin en A:

129

Resolucin de conflictos
por ejemplo
Cuando replicamos ahora A en B, se
detecta un conflicto:

La aplicacin resuelve el conflicto

130

Puesta en prctica de
Replicacin
Creamos una BD y una rplica:
curl -uadmin:enpresadigitala -X PUT
127.0.0.1:5984/db
curl -uadmin:enpresadigitala -X PUT
127.0.0.1:5984/db-replica
curl -uadmin:enpresadigitala -X PUT
127.0.0.1:5984/db/foo -d @foo.json
curl -uadmin:enpresadigitala -X POST
http://127.0.0.1:5984/_replicate -H "ContentType: application/json" -d @replicationconflict-example.json

131

Puesta en prctica de
Replicacin
Actualizamos ahora el documento en db-replica a la
versin 2:
curl -X PUT 127.0.0.1:5984/db-replica/foo -d
'{"count":2,"_rev":"174620ecf527d29daaab9c2b465fbce66"}'

Creamos el conflicto cambiando la versin del


documento en db a 3:
curl -uadmin:enpresadigitala -X PUT
127.0.0.1:5984/db/foo -d '{"count":3,"_rev":"174620ecf527d29daaab9c2b465fbce66"}

Volvemos a replicar la BBDD:


curl -uadmin:enpresadigitala -X POST
http://127.0.0.1:5984/_replicate -H "Content-Type:
application/json" -d @replication-conflict-example.json

132

Puesta en prctica de
Replicacin
Para ver si tenemos conflictos creamos una vista en dbreplica con Futon con el siguiente contenido:
function(doc) {
if(doc._conflicts) {
emit(doc._conflicts, null);
}
}

Ejecutamos la vista yendo a:


http://127.0.0.1:5984/db-replica/_design/conflicts/_v
iew/conflicts
Resultado: {"total_rows":1,"offset":0,"rows":
[ {"id":"foo","key":["27c971bb974251ae8541b8fe045964219"],"value":null} ]}

La revisin con el mayor nmero histrico de revisiones o con


una clave de revisin menor que la otra es la seleccionada

133

Algunos ejemplos de
CouchApp
Revisar documentacin en:

http://couchapp.org/page/index

Instalacin de Pages:
couchapp push pages
http://admin:enpresadigitala@127.0
.0.1:5984/pages
Ir a:
http://127.0.0.1:5984/pages/_design/pag
es/_rewrite/page/index
134

Notificaciones de
cambios
CouchDB ofrece un mecanismo de subscripciones
a cambios mediante la API _changes
La API _changes suministra informacin en el
siguiente formato:
{"seq":12,"id":"foo","changes":[{"rev":"123202479633c2b380f79507a776743d5"}]}
Donde seq es un valor que va cambiando cada vez que se
produce un cambio en una BBDD
id es el identificador del documento
El campos changes suele contener una descripcin de las
ltimas modificaciones

135

Probando la API _changes

Creamos una BBDD:


$ curl -X PUT http://127.0.0.1:5984/db-changes

Revisamos si ha habido cambios:


$ curl -X GET http://127.0.0.1:5984/db-changes /_changes
Devuelve:
{"results":[], "last_seq":0}

Aadimos un documento:
$ curl -X PUT http://127.0.0.1:5984/db-changes/test -d
'{"name":"Anna"}

Revisamos si ha habido cambios de nuevo:


{"results":[{"seq":1,"id":"test","changes":[{"rev":"1aaa8e2a031bca334f50b48b6682fb486"}]}], "last_seq":1}

Podemos usar el parmetro since para filtrar resultados y


longpoll para quedarse bloqueado hasta un nuevo cambio:
$ curl -X GET $HOST/db/_changes?feed=longpoll&since=1

136

Probando la API _changes

Long polling requiere abrir una nueva conexin HTTP por cada cambio
notificado.
La API continuous changes permite establecer una conexin permanente
entre tu aplicacin y CouchDB para recibir cambios:

$ curl -X GET "$HOST/db/_changes?feed=continuous&since=3"

Podemos definir filtros para refinar los cambios en los que estamos
interesados. Por ejemplo:
{
"_id": "_design/app",
"_rev": "1-b20db05077a51944afd11dcb3a6f18f1",
"filters": {
"important":
"function(doc, req) {
if(doc.priority == 'high') { return true; }
else { return false; }
}"
}
}

Para ver los cambios filtrados invocaramos:

137
$ curl "$HOST/db/_changes?filter=app/important"

APIs JavaScript para


CouchApp
Tutorial de JSON:
http://guide.CouchDB.org/editions/1/en/json.ht
ml

Tutoriales de jQuery:
http://docs.jquery.com/Tutorials
jQuery.ajax():
http://api.jquery.com/jQuery.ajax/#jQuery-ajax-setting
s

Hay un plugin jQuery para CouchDB:


http://bradley-holt.com/2011/07/CouchDB-jquery
-plugin-reference/
API en:
http://daleharvey.github.com/jquery.couch.js-docs/sy
138
mbols/index.html

Mustache

Una manera cmoda de genera documentos HTML es a travs de libreras de


plantillas como Mustache

Funciona expandiendo tags en una plantilla usando valores de un mapa

Ejemplo:

El texto de entrada sera:


Hello {{name}}
You have just won ${{value}}!
{{#in_ca}}
Well, ${{taxed_value}}, after taxes.
{{/in_ca}}

Dado el siguiente diccionario:


{
"name": "Chris",
"value": 10000,
"taxed_value": 10000 - (10000 * 0.4),
"in_ca": true
}

Producira los siguientes resultados:


Hello Chris
You have just won $10000!
Well, $6000.0, after taxes.

Tutorial en: http://mustache.github.com/mustache.5.html


139

Evently

Evently es un librera sobre jQuery que define atajos para facilitar la mezcla de eventos estndar y
propietarios, reduciendo significativamente el cdigo utilizado
Dado el siguiente cdigo en jQuery:
$("#myelement").bind("click", function() {

$(this).text("You clicked me.");


});
$("#myelement").bind("mouseenter", function() {
$(this).text("You moused over me.");
});
$("#myelement").bind("loggedIn", function(e, user) {
$(this).text("You are logged in.");
});
$("#logIn").bind("click", function() {
$("#myelement").trigger("loggedIn", ["Dr. Pepper"]);
})

En Evently se escribira:
$("#another").evently({
click : function() {
$(this).text("You clicked me.");
},
mouseenter : function() {
$(this).text("You moused me.");
},
loggedIn : function(e, name) {
$(this).text("You are logged in, " + name);
}
});

Tutorial en: http://couchapp.org/page/evently-primer y


http://jameswestby.net/weblog/tech/20-couchapp-walkthrough-part-3-evently.html
140

MongoDB
Similar a CouchDB
Pretende combinar lo mejor de los
almacenes clave/valor, bases de datos de
documentos y RDBMS
Hace uso de JSON y tiene su propio
lenguaje de consultas
Implementada en C++
Usada por SourceForge, Bit.ly, Foursquare
o GitHub
URL: http://www.mongodb.org/
141

NoSQL or not NoSQL?

En NoSQL, generalmente los datos son recuperados de manera


mucho ms rpida que en un RDBMS, sin embargo las consultas
que se pueden hacer son ms limitadas y requieren trasladar
complejidad a la aplicacin
RDBMS para escribir usan locks y redos para garantizar ACID, pero
NoSQL no soporta a menudo Atomicy, Consistency o Durability
Si quieres soporte transaccional integral debes seguir usando RDBMS

Aplicaciones que generan informes emplean consultas complejas


para las que NoSQL no es muy adecuado
Aplicando MapReduce, las bases de datos NoSQL pueden
paralelizar operaciones complejas como agregaciones
estadsticas, filtros, agrupaciones o ordenacin.
Desde un punto de vista de sistemas deberamos considerar la
combinacin de SQL y NoSQL:
LinkedIn comenz slo con un RDBMS, pero desarroll su propia BBDD
NoSQL (Voldemort)
Facebook tienen una arquitectura hbrida con Memcached y MySQL
junto a un OLTP (envo de mensajes
al Wall), yCassandrapara la
142
bsqueda en la bandeja de entrada

NoSQL or not NoSQL?

Los principales problemas de NoSQL son:


Su complejidad:
Instalacin
Consultas (comprender bien MapReduce)
Los modelos de datos usados

Su falta de madurez

Dnde usarlas?

Datos sociales
Procesado de datos (Hadoop)
Bsqueda (Lucene)
Caching (Memcache)
Data Warehousing

Qu problema quieres resolver?


Transacciones
Grandes volmenes de datos (Exabytes)
Estructura de los datos
143

Conclusin
Las BBDD NoSQL son una clara alternativa a los
RDBMS
Sobre todo para algunas aplicaciones sociales y web que
requieren elevada escalabilidad

No son idneas para todo, de hecho en la


mayora de los casos las RDBMS deberan seguir
siendo la primera opcin:
La capacidad de hacer JOIN y las garantas ACID son
muy importantes para muchas aplicaciones

Es muy posible que los RDBMS actuales


evolucionen para incorporar capacidades
de NoSQL
144

Referencias
Cassandra
NoSQL Not only SQL (Introduction to Apache
Cassandra)
http://www.scriptandscroll.com/3508/technology/nosq
l-not-only-sql-introduction-to-apache-cassandra/#.T
tonPmMk6nA

DataSax company:

http://www.datastax.com/about-us/about-datastax

Getting started with CQL:


http://www.datastax.com/docs/0.8/dml/using_cql

http://cassandra.apache.org/
145

Referencias

CouchDB
Exploring CouchDB, Joe Lennon,
http://www.ibm.com/developerworks/opensource/library/os-CouchD
B/index.html

CouchDB tutorial
http://net.tutsplus.com/tutorials/getting-started-with-couchdb/

CouchDB for geeks:


http://www.slideshare.net/svdgraaf/CouchDB-for-geeks?from=share
_email

CouchDB site:
http://CouchDB.apache.org/

CouchApp.org: The Do It Yourself Evently Tutorial


http://couchapp.org/page/evently-do-it-yourself

CouchApp.org:What the HTTP is CouchApp?


http://wiki.couchapp.org/page/what-is-couchapp

Tutorial: Using JQuery and CouchDB to build a simple AJAX web


application
146
http://blog.edparcell.com/using-jquery-and-CouchDB-to-build-a-sim

Referencias

NoSQL vs. RDBMS


Riyaz -- Thanks for the question regarding "NOSQL vs. RDBMS
databases", version 10r2
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUEST
ION_ID:2664632900346253817

NoSQL or not NoSQL?


http://www.slideshare.net/ruflin/nosql-or-not-nosql/download

Comparativa de diferentes soluciones NoSQL:


http://kkovacs.eu/cassandra-vs-mongodb-vs-couchdb-vs-redis

SQL vs. NoSQL


http://www.linuxjournal.com/article/10770

147

NoSQL: la siguiente generacin


de bases de datos
19 Abril de 2012, 9:00-14:30
Miramon Enpresa Digitala. Paseo Mikeletegi 56, 1. 20009 San
Sebastin
Dr. Diego Lz. de Ipia Glz. de Artaza
DeustoTech-INTERNET2, DeustoTech Deusto Institute of Technology,
Universidad de Deusto

dipina@deusto.es
http://paginaspersonales.deusto.es/dipina
http://www.morelab.deusto.es
Los ejemplos de este curso estn disponibles en:
http://dl.dropbox.com/u/2763621/CursoNoSQL/NoSQL-cd.rar
148

Вам также может понравиться