Sie sind auf Seite 1von 186

Bases de Datos No Relacionales (NoSQL)

29, 30 y 31 de Octobre de 2012, 18:00-21:00 , Aula 104, ESIDE


Mster en Desarrollo e Integracin de Soluciones Software,
Facultad de Ingeniera, Universidad de Deusto

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
Introduccin a Cloud Computing
Qu es una Base de Datos No Relacional?
Las bases de datos NoSQL o de Big Data
Bases de datos distribuidas: teorema de CAP
Arquitectura de una BBDD NoSQL
Tipologa de las BBDD NoSQL
Una base de datos NoSQL del tipo Key-Value Store: Apache Cassandra
Bases de datos NoSQL del tipo orientadas a Documentos: Apache CouchDB y
MongoDB
Ventajas y desventajas de las bases de datos NoSQL
Utilizacin en la industria de las BBDD NoSQL
Integracin con las BBDD relacionales
Conclusin

2
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/CursoNoSQL/N
oSQL-cd.rar

3
El Futuro del Desarrollo Software

4
Infraestructura Virtualizada:
Cloud Computing
Un paradigma de computacin emergente donde los datos y servicios
residen en centros de datos muy escalables que pueden ser accedidos
ubicuamente desde cualquier dispositivo conectado a Internet1

Merrill Lynch:
Cloud computing market
opportunity by 2011 =
$95bn in business and
productivity apps +
$65bn in online advertising =
$160bn

(1) Source: IBM

5
Cloud Computing es
capacidad computacional y
almacenamiento virtualizada expuesta
mediante infraestructura agnstica a la
plataforma y accedida por Internet
Recursos IT compartidos en demanda, creados y
eliminados eficientemente y de modo escalable a
travs de una variedad de interfaces programticos
facturados en base a su uso

6
Forrester Research
A pool of abstracted, highly scalable, and
managed compute infrastructure capable of
hosting end-customer applications and billed
by consumption1

1- Is Cloud Computing Ready for The Enterprise? Forrester Research, Inc.


7
The Cloud = 10X Improvement
Fcil de usar: hazlo tu mismo remotamente de cualquier
lugar en cualquier momento
Escalable: controla tu infraestructura con tu aplicacin
Riesgo: nada que comprar, cancela inmediatamente
Robustez: basado en gran hardware empresarial
Coste: paga slo por lo que uses

8
Evolucin hacia Cloud Computing
La coexistencia y limitaciones de cluster
computing y supercomputing dieron
lugar a grid computing
De grid computing progresamos hacia
utility computing, i.e. Servicios
computacionales empaquetados como
agua, electricidad, etc.
Esto deriv en Cloud Computing, es
decir, todo como servicio (XaaS) :
Plataforma como Servicio
Software como Servicio
Infraestructura como Servicio

9
Mltiples Descripciones Grficas
de la Cloud

10
Mltiples Descripciones Grficas
de la Cloud

11
Arquitectura Cloud Computing

12
Caractersticas de Cloud
Tipos de despliegue Manifestaciones
Cloud privada Cloud Software as a Service (SaaS)
Propiedad de o alquilada por una Uso de la aplicacin del proveedor sobre
empresa (centros de datos,) la red, e.j., Salesforce.com,
Cloud comunitaria Cloud Platform as a Service (PaaS)
Infraestructura compartida por Despliega aplicaciones creadas por los
una comunidad especfica clientes a la nube, e.j. Google App Engine,
Cloud pblica Microsoft Azure,
Vendida al pblico, gran escala Cloud Infrastructure as a Service (IaaS)
(ec2, S3,) Alquilar procesamiento, almacenamiento,
Cloud hbrida capacidad de red y otros recursos
computacionales e.j., EC2 Elastic
Composicin de dos o ms
Compute Cloud, S3 Simple Storage
clouds
Service, Simple DB,

13
Diferentes Manifestaciones

14
Cloud Computing vs. Centros de
Datos Tradicionales

15
Componentes de Cloud Computing

16
Taxonoma de Cloud Computing

17
Evolucin de Tecnologas de Cloud
Computing
Maduracin de tecnologa de virtualizacin
La virtualizacin permite nubes de computacin
Las nubes de computacin demandan nubes de
almacenamiento
Las nubes de almacenamiento y computacin crean
infraestructura cloud
La infraestructura cloud da lugar a plataformas y aplicaciones
cloud
Diferentes tipos de cloud dan lugar a Cloud Aggregators
Nichos de requisitos dan lugar a Cloud Extenders

18
Aplicaciones Cloud
Corresponden con lo que se denomina como SaaS
Manifestacin de cloud ms popular
Ejemplos: SalesForce, Gmail, Yahoo! Mail, rememberthemilk,
doodle, Google Docs, DropBox, picnik, Panda Cloud Antivirus,
scribd, slideshare
Ventajas: Libre, Fcil, Adopcin de consumo
Desventajas: funcionalidad limitada, no hay control de acceso
a la tecnologa subyacente

19
Plataformas Cloud
Contenedores de aplicaciones
Entornos cerrados
Ejemplos: Google App Engine, Microsoft Azure, Heroku,
Mosso, Engine Yard, Joyent o Force.com
Ventajas: buenas para desarrolladores, ms control que en las
aplicaciones cloud, configuradas estrechamente
Desventajas: restringidas a lo que est disponible, otras
dependencias, dependencia tecnolgica

20
Infraestructura Cloud
Proveen nubes de computacin y almacenamiento
Ofrecen capas de virtualizacin (hardware/software)
Ejemplos: Amazon EC2, GoGrid, Amazon S3, Nirvanix, Linode,
Arsys Cloud Flexible, EyeOS
Ventajas: control completo del entorno y la infraestructura
Desventajas: precio premium, competencia limitada

21
Extensores de la Cloud
Proveen extensiones a infraestructura y plataformas cloud con
funcionalidad bsica
Ejemplos: Amazon SimpleDB, Amazon SQS, Google BigTable
Ventajas: extienden la funcionalidad de las nubes de
computacin y almacenamiento para integrar sistemas
heredados u otras cloud
Desventajas: a veces requieren el uso de plataformas o
infraestructura especfica

22
Agregadores Cloud
Se apoyan en varias infraestructuras cloud para su
gestin
Ejemplos: RightScale, Appistry
Ventajas: proveen ms opciones para entornos cloud
Desventajas: dependientes de proveedores de cloud

23
Qu framework o plataforma
usar para mis aplicaciones Cloud?

24
Amazon Web Services (AWS)
AWS proporciona una infraestructura de servicios elstica donde alojar
computacin, almacenamiento o sistemas empresariales
Amazon Elastic Cloud (EC2) permite configurar y ejecutar un Amazon Machine
Instance (AMI) servidores en demanda
Amazon Simple Storage Service (S3) permite guardar y recuperar datos en la nube
Amazon SimpleDB proporciona la funcionalidad de una base de datos sobre S3
basada en pares clave-valor
Amazon Simple Queue Service (SQS) servicio de mensajera para encolar tareas y
mensajes
Amazon Relational Database Service (RDS) servicio web para crear, operar y escalar
una base de datos en la nube
Amazon CloudFront copias de tus objetos ms populares son cacheados en una red de
nodos alrededor del mundo

Documentacin: http://aws.amazon.com/documentation/

25
Amazon Web Services (AWS)

26
Amazon Web Services (AWS)

27
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 por Carlo Strozzi y
resucitado en 2009 por Eric Evans
El propio Evans sugiere mejor referirse a esta familia de
BBDD de nueva generacin como Big Data

28
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 datastores 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 Almacenamiento
Estructurado
29
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
30
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.

31
RDBMS vs. NoSQL
Las bases de datos relacionales tradicionales nos permiten definir la estructura de
un esquema que demanda reglas rgidas y garantizan ACID:
Atomicity
Consistency
Isolation
Durability
Las aplicaciones web modernas presentan desafos muy distintos a las que
presentan los sistemas empresariales tradicionales (e.j. sistemas bancarios):
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

32
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 3 TB de 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

33
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 pares clave-valor
34
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-database.html
Five Reasons to Use NoSQL
http://facility9.com/2010/09/five-reasons-to-use-nosql/
Las ms populares son: Cassandra, CouchDB,
MongoDB, Riak, Neo4j

35
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/h
ow-twitter-uses-nosql.php)

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

37
Caractersticas BBDD
orientadas a Clave-Valor
Su precursor fue Amazon Dynamo
Basadas en DHT (Distributed Hash Tables)
Modelo de datos: coleccin de pares
clave/valor
Ejemplos: Dynomite, Voldemort, Tokyo

38
Distributed Hash Table (DHT)
Un distributed 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

39
Caractersticas BBDD
orientadas a Familia de Columnas
Su precursor es 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
Alta disponibilidad
MapReduce
40
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

41
Base de Datos orientada a
Documentos
Una base de datos orientada a documentos es 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

42
Caractersticas Bases de
Datos Basadas en Grafos
Inspiradas por Euler y la teora de grafos
Modelo de datos: nodos, relaciones con pares
clave valor en ambos
Ejemplos: AllegroGraph, VertexBD, Neo4j

43
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.1.6
Web: http://cassandra.apache.org/
Documentacin: http://www.datastax.com/docs/1.0/index

44
Quin usa Apache Cassandra?
Algunos usuarios famosos de Cassandra son:
Digg
Facebook
Twitter
Rackspace
SimpleGEO

45
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 off

46
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 tena SQL
Pero desde la versin 0.8 tenemos CQL

47
Instalacin de Cassandra
Documentacin en:
Cassandra Wiki: GettingStarted,
http://wiki.apache.org/cassandra/GettingStarted
Requisitos:
Java 1.6 en adelante
Las ltimas versiones estables disponibles en:
http://cassandra.apache.org/download/

48
Instalacin de Cassandra
Disponible desde: http://cassandra.apache.org/download/
Descargar apache-cassandra-1.1.6-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.1.6\bin

49
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

50
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;
51
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;
assume User validator 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'];
get User['dipina'];
52
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 datos.

53
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-cassandra-
cluster-on-a-single-windows-machine/
http://www.datastax.com/docs/0.7/getting_started/configuring

54
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 node1.cassandra
127.0.0.1 node2.cassandra
127.0.0.1 node3.cassandra
127.0.0.1 node4.cassandra
3. Descomprime apache-cassandra-1.1.6-bin.tar.gz en 4 carpetas, por ejemplo: %HOME%\apache-
cassandra-1.1.6\1 a %HOME%\apache-cassandra-1.1.6\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
Por ejemplo, commitlog_directory: /var/lib/cassandra/1/commitlog
Modifica las variables:
listen_address: node1.cassandra
rpc_address: node1.cassandra
5. Modicar el nmero de puerto en cassandra.bat de JMX: -
Dcom.sun.management.jmxremote.port=7199
6. Ejecutar el siguiente comando para ver los nodos en el clster:
nodetool -h 127.0.0.1 -p 7199 ring

55
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

56
Modelo de Datos en Cassandra
Est basado en un modelo clave-valor
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:
Un keyspace, una column family, una key, una super
column opcional, y una column.
Al final siempre tenemos un valor nico que es la columna.

57
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

58
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
}
59
Super-columnas
Una supercolumna es un array asociativo
(mapa) de columnas ordenadas por nombre

60
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

61
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"}
}
}
}
62
Familia de super-columnas
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)

63
Familia de super-columnas

64
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

65
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:

66
Resumen Modelo de Datos

67
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
replication_factor

68
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://www.datastax.com/docs/1.0/cluster_architecture/r
eplication
Column families: al menos una por Keyspace, es un
contenedor de filas, que contienen columnas

69
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
Documentation:
http://www.datastax.com/docs/1.0/cluster_architecture/partitioning
Cassandra tiene consistencia reconfigurable
http://www.datastax.com/docs/1.0/dml/data_consistency
Con Cassandra tienes que pensar en las consultas que quieres
ejecutar y luego realizar el modelo en torno a ellas
70
Diferencias entre un RDBMS y
Cassandra
No haba lenguaje de consulta, tiene una API accesible a travs de Thrift
S existe desde la versin 0.8 CQL
No hay integridad referencial, no hay joins, se puede emular almacenando claves a otras filas
en un column family
ndices secundarios en una tabla daban lugar a nuevos column families que mapean un
campo a la clave de la primera column family
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
BytesType, UTF8Type, AsciiType, LongType, LexicalUUIDType, TimeUUIDType
Las filas son agrupadas y ordenadas (distribuidas en el cluster) por el Partitioner
RandomPartitioner, OrderPreservingPartitioner,
CollatingOrderPreservingPartitioner
Cassandra tiene mejor rendimiento con datos desnormalizados
Modelas las consultas y luego defines la estructura de datos a su alrededor

71
RDBS vs. KeySpace

72
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
Hector para Java: https://github.com/hector-client/hector

73
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
de org.apache.cassandra.thrift.CassandraServer a org
.apache.cassandra.avro.CassandraServer
Todava no hecho
Ms informacin sobre Avro en: http://avro.apache.org.

74
Mi primera aplicacin con
Cassandra
Relational vs.
Cassandra Model

75
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?

76
Pycassa: un cliente Python
para Apache Cassandra
Instalacin:
Dependencias:
Instalar Python 2.7 o en adelante: http://www.python.org/download/
Instalar setuptools: http://pypi.python.org/pypi/setuptools#windows
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
Actualizar PATH con directorio donde est python.exe
Ms info en:
http://pycassa.github.com/pycassa/tutorial.html#connecting-to-
cassandra
77
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')

78
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'}})

79
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', column_reversed=True,
column_count=3)
80
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#

81
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

82
Modelo de Datos de Twissandra
Usuarios:
User = {
'hermes': {
'password': '****',
(other properties),
},
}
Amigos y seguidores:
Friends = {
'hermes': {
# friend id: timestamp of when the friendship was added
'larry': '1267413962580791',
'curly': '1267413990076949',
'moe' : '1267414008133277',
},
}

Followers = {
'hermes': {
# friend id: timestamp of when the followership was added
'larry': '1267413962580791',
'curly': '1267413990076949',
'moe' : '1267414008133277',
},
}

83
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',
},
}

84
Cassandra Query Language (CQL)
Cassandra ha sido accedido principalmente mediante Thrift 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 esto 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-cassandra-0-8-
part-1-cql-the-cassandra-query-language
http://www.datastax.com/docs/0.8/dml/using_cql#use-cql

85
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 cqlsh est
instalado en $CASSANDRA_HOME/bin/cqlsh para
instalaciones tarball o /usr/bin/cqlsh para instalaciones
de paquetes Linux
Ejemplo programtico en:
http://crlog.info/2011/06/13/cql-creating-a-simple-keyspace/
http://www.datastax.com/docs/1.1/dml/using_cql
86

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-query-language
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 |

87
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);
88
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-minutes%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

89
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 old-school in the same way that Django makes
ASP look outdated.
Jacob Kaplan-Moss, Django developer
90
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 reducir latencia
Gestiona la replicacin a la nube por ti

91
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 a documentos encaja mejor que una base de datos
relacional: wikis, blogs y sistemas de gestin documental
92
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

93
Quin usa CouchDB?
Un largo listado de software y websites que
hacen uso de CouchDB puede encontrarse en:
http://wiki.apache.org/CouchDB/CouchDB_in_the
_wild?action=show&redirect=InTheWild

94
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,
"Tags": ["plankton", "baseball",
"decisions"]
95
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 escrituras

96
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.

97
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 resultados. A partir
de un conjunto de pares clave/valor devuelve un slo valor.

98
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);
}

99
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.

100
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 desde la ltima replicacin.
Utiliza Multi-Version Concurrency Control (MVCC)
101
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

102
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

103
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:
http://CouchDB.apache.org/docs/overview.html

104
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 cambios en la base de datos.

105
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
reduce se centra en la agregacin de los
mismos.
106
Instalacin de CouchDB
Dependencias:
Runtime Build
CouchDB
Spidermonkey Erlang ICU cURL Automake Autoconf

0.9.x ==1.7 >=5.6.0 >= 3.0 >= 7.15.5 >= 1.6.3 >= 2.59
>=1.7 &&
0.10.x >=5.6.5 >= 3.0 >= 7.18.0 >= 1.6.3 >= 2.59
<=1.8.0
0.11.x >=1.7 >=5.6.5 >= 3.0 >= 7.18.0 >= 1.6.3 >= 2.59

Detalles de instalacin:
http://wiki.apache.org/CouchDB/Installation
Instrucciones detalladas para Windows en:
https://github.com/LearningRegistry/LearningRegistry/wiki/Windows-
Installation-Guide
Curl
Visual C++ 2008 Redistributable Setup
Microsoft Visual C++ 2010 Redistributable Package (x64)
http://www.microsoft.com/en-us/download/details.aspx?id=14632
OpenSSL
Configurar %PATH% para que apunte a los dirs de instalacin dependencias
107
Instalacin en Windows y Linux
Algunos enlaces de ayuda para Windows:
http://niallodoherty.com/post.cfm/installing-CouchDB-on-
windows-quick-guide
http://wiki.apache.org/CouchDB/Quirks_on_Windows
Instalacin en Linux:
Tan simple como: sudo aptitude install
couchdb
http://wiki.apache.org/couchdb/Installing_on_Ubuntu
Para lanzar el servidor de CouchDB ejecutar el
comando couchdb en el directorio bin de
instalacin.
108
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

109
CouchDB Futon
Futon: http://localhost:5984/_utils/
Hace uso internamente de la librera
http://127.0.0.1:5984/_utils/script/jquery.couch.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

110
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, y DELETE, mostrando la respuesta HTTP recibida del
servidor web

111
Probando la API RESTful de
CouchDB con curl
$ curl http://127.0.0.1:5984/
Respuesta: {"couchdb":"Welcome","version":"1.2.0"}
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
Respuesta:
["_replicator","_users","nerekurtsoak","test_suite_reports","testdb","users"]
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:
$ curl -X GET http://127.0.0.1:5984/_all_dbs
Obtendramos:
["_replicator","_users","fruit","nerekurtsoak","test_suite_reports","testdb","u
sers"]
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":
"The database could not be created, the file already exists.}

112
Probando la API RESTful de
CouchDB con curl
Podemos borrar una base de datos con el siguiente comando:
$ curl -uadmin:enpresadigitala -X DELETE
http://127.0.0.1:5984/vegetables
Respuesta: {"ok":true}
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":"1-
967a00dff5e02add41819138abb3284d"}
Para recuperarlo:
$ curl -X GET http://127.0.0.1:5984/fruit/apple
Respuesta: {"_id":"apple","_rev":"1-967a00dff5e02add41819138abb3284d"}
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}

113
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

114
Primeros pasos con CouchDB
Vamos a seguir el tutorial en:
http://net.tutsplus.com/tutorials/getting-
started-with-CouchDB/
Asegrate de crear una cuenta de
admin/enpresadigitala
Otros tutoriales:
http://www.catswhocode.com/blog/getting-
started-with-CouchDB-tutorial-a-beginners-guide

115
Primeros pasos en CouchDB

116
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
"name" : Curso NoSQL
"price" : 30
Guarda cada campo
Guarda el documento
3. Modificar el documento ya existente aadiendo el campo "type"
con valor "course"
La nueva versin del documento debera empezar por 2

117
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:
{"ok":true,"id":"b54b3496d090c43a4266180ecb002a92","rev":"1-
93c73d298af443f623db6861f90e9f6e"}
3. Para recuperar todos los documentos:
curl -X GET http://127.0.0.1:5984/nerekurtsoak/_all_docs

118
Vista de un documento en Futon

119
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?nerekurtsoak/_design
/courses/_view/courses

120
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/_design/course
prices/_view/courseprices
121
Creando un Reduce

122
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
Los contenidos estticos de la aplicacin aparecen como
_attachments en el documento de diseo

123
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/mydb/
_design/calendar
http://127.0.0.1:5984/mydb/
_design/contacts

124
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
00:00:00"&endkey="2010/02/00 00:00:00&descending=true

125
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

126
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

127
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.html
128
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/"

129
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");
}
}
130
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

131
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"]}
}
132
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
133
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:
/<database>/_design/<design>/_update/<function>/<docid>
Para crear una nueva instancia, hacer POST en el formato:
/<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'];
}
}
Documentacin en: http://wiki.apache.org/CouchDB/Document_Update_Handlers
134
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:
http://couchapp.org/page/couchapp-python
135
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

136
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: pywin32-214.win32-
py2.7.exe
Instalar Couchapp-0.7.5.win32.exe

137
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

138
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

139
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. Crear base de datos "addressbook" con Futon
2. Crea los siguientes dos documentos en la base de datos:
{"type": "address", "name": "Fred", "mobile": "555-
0001"}
{"type": "address", "name": "Barney", "mobile": "555-
0002"}
3. Generamos la aplicacin y una vista para ella, subiendo la aplicacin:
couchapp generate app addressbook
couchapp generate view addressbook phonenumbers
couchapp push
addressbook http://127.0.0.1:5984/addressbook
140
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

141
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>

142
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

143
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);
}});
} 144
}
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;
})

145
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();
}
}
}); 146
});
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

147
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 conforman un
clster
148
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.
org/database}

149
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 replicacin
CouchDB har uso de la _changes API sobre cambios en documentos

150
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}'

151
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
perdedores, independientemente de las instancias que existan.

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

Creamos un documento en A

Forzamos replicacin:

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

Aadimos una nueva versin en A:

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

La aplicacin resuelve el conflicto

155
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 "Content-
Type: application/json" -d @replication-
conflict-example.json

156
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":"1-
74620ecf527d29daaab9c2b465fbce66"}'
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":"1-
74620ecf527d29daaab9c2b465fbce66"}
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

157
Puesta en prctica de
Replicacin
Para ver si tenemos conflictos creamos una vista en db-replica 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/_view/conflicts
Resultado: {"total_rows":1,"offset":0,"rows":[
{"id":"foo","key":["2-
7c971bb974251ae8541b8fe045964219"],"value":null} ]}
La revisin con el mayor nmero histrico de revisiones o con una clave de
revisin menor que la otra es la seleccionada

158
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/page
s/_rewrite/page/index

159
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":"1-
23202479633c2b380f79507a776743d5"}]}
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

160
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":"1-
aaa8e2a031bca334f50b48b6682fb486"}]}], "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

161
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:
$ curl "$HOST/db/_changes?filter=app/important"

162
APIs JavaScript para
CouchApp
Tutorial de JSON:
http://guide.CouchDB.org/editions/1/en/json.html
Tutoriales de jQuery:
http://docs.jquery.com/Tutorials
jQuery.ajax():
http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings
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/symbols/index.html
163
Mustache
Una manera cmoda de generar 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

164
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

165
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++
Es quizs el motor NoSQL ms popular
Usada por SourceForge, Bit.ly, Foursquare o GitHub
URL: http://www.mongodb.org/
166
MongoDB
MongoDB (de la palabra en ingles humongous que
significa enorme) es un sistema de base de datos
NoSQL orientado a documentos
MongoDB guarda estructuras de datos en
documentos tipo BSON (Binary JSON (JSON Binario)
con un esquema dinmico , haciendo que la
integracin de los datos en ciertas aplicaciones sea
mas fcil y rpida.
The MongoDB Manual:
http://docs.mongodb.org/manual/
167
Caractersticas Principales
Consultas Ad hoc
MongoDB soporta la bsqueda por campos, consultas de rangos y expresiones regulares. Las consultas pueden devolver un campo especfico
del documento pero tambin puede ser una funcin JavaScript definida por el usuario.
Indexacin
Cualquier campo en un documento de MongoDB puede ser indexado, al igual que es posible hacer ndices secundarios. El concepto de
ndices en MongoDB es similar a los encontrados en base de datos relacionales.
Replicacin
MongoDB soporta el tipo de replicacin maestro-esclavo. El maestro puede ejecutar comandos de lectura y escritura. El esclavo puede copiar los datos del
maestro y slo se puede usar para lectura o para copia de seguridad, pero no se pueden realizar escrituras. El esclavo tiene la habilidad de poder elegir un
nuevo maestro en caso del que se caiga el servicio con el maestro actual.
Balanceo de carga
MongoDB se puede escalar de forma horizontal usando el concepto de shard.
El desarrollador elije una llave shard, la cual determina como sern distribuidos los datos en una coleccin. los datos son divididos en rangos (basado en la
llave shard) y distribuidos a travs de mltiples shard.
Un shard es un maestro con uno o ms esclavos.
MongoDB tiene la capacidad de ejecutarse en mltiple servidores, balanceando la carga y/o duplicando los datos para poder mantener el sistema
funcionando en caso que exista un fallo de hardware.
Almacenamiento de archivos
MongoDB puede ser utilizado con un sistema de archivos, tomando la ventaja de la capacidad que tiene MongoDB para el balanceo de carga y la replicacin
de datos utilizando mltiples servidores para el almacenamiento de archivos.
Esta funcin (que es llamada GridFS ) est incluida en los drivers de MongoDB y disponible para los lenguajes de programacin que soporta MongoDB.
Agregacin
La funcin MapReduce puede ser utilizada para el procesamiento por lotes de datos y operaciones de agregacin. Esta funcin permite que los usuarios
puedan obtener el tipo de resultado que se obtiene cuando se utiliza el comando SQL group-by.
Ejecucin de JavaScript del lado del servidor
MongoDB tiene la capacidad de realizar consultas utilizando JavaScript, haciendo que estas sean enviadas directamente a la base de datos para ser
ejecutadas.

168
Casos de uso de MongoDB
Almacenamiento y registro de eventos
Para sistemas de manejo de documentos y contenido
Comercio Electrnico
Juegos
Problemas de alto volumen
Aplicaciones mviles
Almacn de datos operacional de una pgina Web
Manejo de contenido
Almacenamiento de comentarios
Votaciones
Registro de usarios
Perfiles de usuarios
Sesiones de datos
Proyectos que utilizan metodologas de desarrollo iterativo o giles
Manejo de estadsticas en tiempo real

169
Manipulacin de Datos:
colecciones y documentos
MongoDB guarda la estructura de los datos en documentos tipo JSON con
un esquema dinmico llamado BSON, lo que implica que no existe un
esquema predefinido.
Los elementos de los datos son llamados documentos y se guardan en
colecciones
Una coleccin puede tener un nmero indeterminado de documentos
Las colecciones son como tablas y los documentos
Cada documento en una coleccin puede tener diferentes campos.
La estructura de un documento es simple y compuesta por key-value
pairs parecido a las matrices asociativas en un lenguaje de programacin
Como valor se pueden usar nmeros, cadenas o datos binarios como
imgenes o cualquier otro key-value pairs.

170
Ejemplo de documento
en MongoDB
{
"_id":
ObjectId("4efa8d2b7d284dad101e4bc7"),
"Last Name": "PELLERIN",
"First Name": "Franck",
"Age": 29,
"Address": {
"Street": "1 chemin des Loges",
"City": "VERSAILLES"
}
}

171
Utilidades de MongoDB
Los siguientes comandos pueden ser instalados para el manejo y la administracin del sistema de base de
datos:
mongo: es un Shell interactivo que permite a los desarrolladores ver, insertar, eliminar y actualizar datos
en su base de datos. Este tambin permite entre otras funciones la replicacin de informacin, configurar
los Shards, apagar los servidores y ejecutar JavaScript.
mongostat: es un instrumento de lnea de comandos que muestra en resumen una lista de estadsticas
de una instancia de MongoDB en ejecucin. Esto te permite visualizar cuantas inserciones, actualizaciones,
eliminaciones, consultas y comandos se han ejecutado, pero tambin cuanta memoria esta utilizando y
cuanto tiempo ha estado cerrada la base de datos.
mongotop: es un instrumento de lnea de comandos que provee un mtodo para dar seguimiento a la
cantidad de tiempo que dura una la lectura o escritura de datos en una instancia. Tambin provee
estadsticas en el nivel de cada coleccin.
mongosniff: es un instrumento de lnea de comandos que provee un sniffing en la base de datos
haciendo un sniffing en el trfico de la red que va desde y hacia MongoDB.
mongoimport/mongoexport: es un instrumento de lnea de comandos que facilita la importacin
exportacin de contenido desde JSON, CSV o TSV. Tambin tiene el potencial de importar o exportar hacia
otros formatos.
mongodump/mongorestore: es un instrumento de lnea de comandos para la creacin de una
exportacin binaria del contenido de la base de datos. Estos comandos son utilizado para la estrategia de
copias de seguridad cuando se utiliza MongoDB.

172
Documentacin e instalacin
La documentacin completa de MongoDB puede encontrarse en:
http://docs.mongodb.org/manual/
Instrucciones para instalar MongoDB en Windows:
Descargar de: http://docs.mongodb.org/manual/tutorial/install-mongodb-on-
windows/
Crear directorio de datos: mkdir data/db
Ejecutar el comando: mongod.exe --dbpath ..\data\db
Ejecutar el cliente de mongo y los siguientes comandos en JavaScript:
C:\Programming\utilities\mongodb-win32-x86_64-2.0.6\bin>mongo
MongoDB shell version: 2.0.6
connecting to: test
> db.test.save( {a:1} )
> db.test.find()
{ "_id" : ObjectId("4fe6e41b184d3a26629be9b6"), "a" : 1 }
>

173
Usando MongoDB
mongo es un shell JavaScript completo, cualquier funcin JavaScript, sintxis o clase puede
usarse en el shell
use mydb
j = { name : "mongo" };
t = { x : 3 };
db.things.save(j);
db.things.save(t);
db.things.find();
for (var i = 1; i <= 20; i++) db.things.save({x : 4, j : i});
db.things.find();
// Iterate through the remaining items
it
// Store the cursor of the DB in a variable
var cursor = db.things.find();
while (cursor.hasNext()) printjson(cursor.next());
// Use functional features of JavaScript
db.things.find().forEach(printjson);
// cursor like an array
var cursor = db.things.find();
printjson(cursor[4]);
// The query expression is an document itself.
db.things.find({name:"mongo"}).forEach(printjson);
db.things.find({x:4}).forEach(printjson);
db.things.find({x:4}, {j:true}).forEach(printjson);
174
Documentos de consulta
Documentos que indican el patrn de claves y valores que deben ser
localizados
Ejemplos:
SELECT * FROM things WHERE name="mongo
db.things.find({name:"mongo"}).forEach(printjson);
SELECT * FROM things WHERE x=4
db.things.find({x:4}).forEach(printjson);
SELECT j FROM things WHERE x=4
db.things.find({x:4}, {j:true}).forEach(printjson);
Recuperar el primer elemento que cumple alguna restriccin:
printjson(db.things.findOne({name:"mongo"}));
Limitar el nmero de resultados:
db.things.find().limit(3);
More info at:
SQL to Mongo Mapping Chart
http://www.mongodb.org/display/DOCS/SQL+to+Mongo+Mapping+Chart
175
GridFS
GridFS is a specification for storing large files in MongoDB
The database supports native storage of binary data
within BSON objects
BSON objects in MongoDB are limited in size (4MB older versions,
16MB in v1.7/1.8, higher limits in the future)
GridFS spec provides a mechanism for transparently dividing a
large file among multiple documents
Each file has a metadata object in a files collection, and one or more
chunk objects in a chunks collection.
URL: http://www.mongodb.org/display/DOCS/GridFS
Specification:
http://www.mongodb.org/display/DOCS/GridFS+Specification

176
MongoDB and Java
Java Tutorial:
http://www.mongodb.org/display/DOCS/Java+Tutori
al
Una lista de buenos ejemplos en MongoDB
programados con Java:
http://www.mkyong.com/tutorials/java-mongodb-
tutorials/
Ejemplo using GridFS con MongoDB
http://www.mkyong.com/mongodb/java-mongodb-save-
image-example/

177
Comparacin de BBDD NoSQL
Cassandra vs MongoDB vs CouchDB vs Redis vs Riak vs HBase vs Membase
vs Neo4j comparison
http://kkovacs.eu/cassandra-vs-mongodb-vs-couchdb-vs-redis
NoSQL: Comparing the Different Solutions
http://www.readwriteweb.com/cloud/2010/11/nosql-comparison.php
Is the Relational Database Doomed?
http://www.readwriteweb.com/enterprise/2009/02/is-the-relational-
database-doomed.php
Comparing Document Databases to Key-Value Stores
http://nosql.mypopescu.com/post/659390374/comparing-document-
databases-to-key-value-stores

178
Comparacin de BBDD NoSQL
Cassandra vs MongoDB vs CouchDB vs Redis vs Riak vs HBase vs Membase
vs Neo4j comparison
http://kkovacs.eu/cassandra-vs-mongodb-vs-couchdb-vs-redis
NoSQL: Comparing the Different Solutions
http://www.readwriteweb.com/cloud/2010/11/nosql-comparison.php
Is the Relational Database Doomed?
http://www.readwriteweb.com/enterprise/2009/02/is-the-relational-
database-doomed.php
Comparing Document Databases to Key-Value Stores
http://nosql.mypopescu.com/post/659390374/comparing-document-
databases-to-key-value-stores

179
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), y Cassandra para la bsqueda en la bandeja de entrada

180
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

181
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

182
Referencias
Cassandra
NoSQL Not only SQL (Introduction to Apache
Cassandra)
http://www.scriptandscroll.com/3508/technology/nosql-not-only-
sql-introduction-to-apache-cassandra/#.TtonPmMk6nA
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/

183
Referencias
CouchDB
Exploring CouchDB, Joe Lennon,
http://www.ibm.com/developerworks/opensource/library/os-CouchDB/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
http://blog.edparcell.com/using-jquery-and-CouchDB-to-build-a-simple-we
CouchApp site:
http://couchapp.org/page/getting-started

184
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_QUESTION_ID:2664632
900346253817
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

185
Bases de Datos No Relacionales (NoSQL)
29, 30 y 31 de Octobre de 2012, 18:00-21:00 , Aula 104, ESIDE
Mster en Desarrollo e Integracin de Soluciones Software,
Facultad de Ingeniera, Universidad de Deusto

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

186

Das könnte Ihnen auch gefallen