Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
En un artículo anterior ya hablamos sobre MongoDB. Recordemos. MongoDB es una base de datos
orientada a documentos. Esto quiere decir que en lugar de guardar los datos en registros, guarda los
datos en documentos. Estos documentos son almacenados en BSON, que es una representación binaria
de JSON.
Una de las diferencias más importantes con respecto a las bases de datos relacionales, es que no es
necesario seguir un esquema. Los documentos de una misma colección - concepto similar a una tabla de
una base de datos relacional -, pueden tener esquemas diferentes.
Imaginemos que tenemos una colección a la que llamamos Personas. Un documento podría
almacenarse de la siguiente manera:
Nombre: "Pedro",
Edad: 22,
Aficiones: ["fútbol","tenis","ciclismo"],
Amigos: [
Nombre:"María",
Edad:22
},
Nombre:"Luis",
Edad:28
El documento anterior es un clásico documento JSON. Tiene strings, arrays, subdocumentos y números.
En la misma colección podríamos guardar un documento como este:
Nombre: "Luis",
Este documento no sigue el mismo esquema que el primero. Tiene menos campos, algún campo nuevo
que no existe en el documento anterior e incluso un campo de distinto tipo.
Esto que es algo impensable en una base de datos relacional, es algo totalmente válido en MongoDB.
MongoDB está escrito en C++, aunque las consultas se hacen pasando objetos JSON como parámetro. Es
algo bastante lógico, dado que los propios documentos se almacenan en BSON. Por ejemplo:
db.Clientes.find({Nombre:"Pedro"});
La consulta anterior buscará todos los clientes cuyo nombre sea Pedro.
MongoDB viene de serie con una consola desde la que podemos ejecutar los distintos comandos. Esta
consola está construida sobre JavaScript, por lo que las consultas se realizan utilizando ese lenguaje.
Además de las funciones de MongoDB, podemos utilizar muchas de las funciones propias de JavaSciprt.
En la consola también podemos definir variables, funciones o utilizar bucles.
Si queremos usar nuestro lenguaje de programación favorito, existen drivers para un gran número de
ellos. Hay drivers oficiales para C#, Java, Node.js, PHP, Python, Ruby, C, C++, Perl o Scala. Aunque estos
drivers están soportados por MongoDB, no todos están en el mismo estado de madurez. Por ejemplo el
de C es una versión alpha. Si queremos utilizar un lenguaje concreto, es mejor revisar los drivers
disponibles para comprobar si son adecuados para un entorno de producción.
Aunque se suele decir que las bases de datos NoSQL tienen un ámbito de aplicación reducido, MongoDB
se puede utilizar en muchos de los proyectos que desarrollamos en la actualidad.
Cualquier aplicación que necesite almacenar datos semi estructurados puede usar MongoDB. Es el caso
de las típicas aplicaciones CRUD o de muchos de los desarrollos web actuales.
Eso sí, aunque las colecciones de MongoDB no necesitan definir une esquema, es importante que
diseñemos nuestra aplicación para seguir uno. Tendremos que pensar si necesitamos normalizar los
datos, denormalizarlos o utilizar una aproximación híbrida. Estas decisiones pueden afectar al
rendimiento de nuestra aplicación. En definitiva el esquema lo definen las consultas que vayamos a
realizar con más frecuencia.
MongoDB es especialmente útil en entornos que requieran escalabilidad. Con sus opciones de
replicación y sharding, que son muy sencillas de configurar, podemos conseguir un sistema que escale
horizontalmente sin demasiados problemas.
En esta base de datos no existen las transacciones. Aunque nuestra aplicación puede utilizar alguna
técnica para simular las transacciones, MongoDB no tiene esta capacidad. Solo garantiza operaciones
atómicas a nivel de documento. Si las transacciones son algo indispensable en nuestro desarrollo,
deberemos pensar en otro sistema.
Tampoco existen los JOINS. Para consultar datos relacionados en dos o más colecciones, tenemos que
hacer más de una consulta. En general, si nuestros datos pueden ser estructurados en tablas, y
necesitamos las relaciones, es mejor que optemos por un RDBMS clásico.
Y para finalizar, están las consultas de agregación. MongoDB tiene un framework para realizar
consultas de este tipo llamado Aggregation Framework. También puede usar Map Reduce. Aún así,
estos métodos no llegan a la potencia de un sistema relacional. Si vamos a necesitar explotar informes
complejos, deberemos pensar en utilizar otro sistema. Eso sí, esta es una brecha que MongoDB va
recortando con cada versión. En poco tiempo esto podría dejar de ser un problema.
La instalación de una instancia del servidor es un juego de niños. Simplemente tenemos que bajar los
binarios para nuestro sistema operativo. Hay versiones par Windows, Linux y MacOs. Una vez bajados
podremos arrancar el servicio de MongoDB con un solo comando.
Con este comando arrancamos el servicio mongod, que empezará a escuchar peticiones por el puerto
27017. Es importante indicar el parámetro --dbpath, con la ruta dónde se almacenarán los ficheros de
nuestra base de datos.
Si ya tenemos el servidor lanzado en nuestra máquina, bastará con lanzar desde la consola el siguiente
comando
mongo localhost
Desde ese momento entraremos en la consola y podremos realizar consultas. Si escribimos help
tendremos un listado con los comandos más comunes y su descripción.
Y de momento lo dejamos aquí. En próximos artículos veremos como se pueden hacer inserciones,
consultas y actualizaciones de datos.
MongoDB (de la palabra en inglés “humongous” que significa enorme) es un sistema de base de datos
NoSQL orientado a documentos, desarrollado bajo el concepto de código abierto.
MongoDB forma parte de la nueva familia de sistemas de base de datos NoSQL. En lugar de guardar los
datos en tablas como se hace en las base de datos relacionales, MongoDB guarda estructuras de datos
en documentos similares a JSON con un esquema dinámico (MongoDB utiliza una especificación
llamada BSON), haciendo que la integración de los datos en ciertas aplicaciones sea más fácil y rápida.
El desarrollo de MongoDB empezó en octubre de 2007 por la compañía de software 10gen.1 Ahora
MongoDB es una base de datos lista para su uso en producción y con muchas características (features).
Esta base de datos se utiliza mucho en la industria,2 contando con implantaciones en empresas como
MTV Network,3 Craiglist4, BCI o Foursquare.5
El código binario está disponible para los sistemas operativos Windows, Linux, OS X y Solaris.
Historia
El desarrollo de MongoDB empezó con la empresa de software 10gen Inc. (ahora llamada MongoDB
Inc.)1 en 2007 cuando estaban desarrollando una plataforma como servicio (PaaS) similar al conocido
Google App Engine.6 En 2009 MongoDB fue lanzado como un producto independiente y publicado bajo
la licencia de código abierto AGPL.7
En marzo de 2011, se lanzó la versión 1.4 y se consideró ya como una base de datos lista para su uso en
producción.8
MongoDB se puede obtener de una forma gratuita bajo la licencia pública general de Affero (AGPL) de
GNU.7 Los drivers para los lenguajes de programación están bajo la licencia de Apache. Adicional a
estas licencias, MongoDB Inc. ofrece una licencia comercial para MongoDB que incluye características
avanzadas (como integración con SASL, LDAP, Kerberos,9 Simple Network Management Protocol10 y
búsqueda de texto de Rosette Linguistics Platform de Basis Technology11), herramientas de gestión,
monitorización y backup, así como soporte. 12
Características principales
Consultas Ad hoc
MongoDB soporta la búsqueda por campos, consultas de rangos y expresiones regulares. Las consultas
pueden devolver un campo específico del documento pero también puede ser una función JavaScript
definida por el usuario.
Indexación
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..
Replicación
Balanceo de carga
MongoDB se puede escalar de forma horizontal usando el concepto de “shard”.14 El desarrollador elige
una clave de sharding, la cual determina cómo serán distribuidos los datos de una colección. Los datos
son divididos en rangos (basado en la clave de sharding) y distribuidos a través de múltiples shard.
Cada shard puede ser una replica set. MongoDB tiene la capacidad de ejecutarse en múltiple servidores,
balanceando la carga y/o replicando los datos para poder mantener el sistema funcionando en caso que
exista un fallo de hardware. La configuración automática es fácil de implementar bajo MongoDB y se
pueden agregar nuevas servidores a MongoDB con el sistema de base de datos funcionando.
Almacenamiento de archivos
MongoDB puede ser utilizado como un sistema de archivos, tomando la ventaja de la capacidad que
tiene MongoDB para el balanceo de carga y la replicación de datos utilizando múltiples servidores para
el almacenamiento de archivos. Esta función se llama GridFS15 y es más bien una implementación en
los drivers, no en el servidor,16 por lo que está incluida en los drivers oficiales que la compañía de
MongoDB desarrolla. Estos drivers exponen funciones y métodos para la manipulación de archivos y
contenido a los desarrolladores. En un sistema con múltiple servidores, los archivos pueden ser
distribuidos y replicados entre los mismos y de una forma transparente, de esta forma se crea un
sistema eficiente que maneja fallos y balanceo de carga.
Agregación
MongoDB proporciona un framework de agregación que permite realizar operaciones similares a las
que se obtienen con el comando SQL "GROUP BY". El framework de agregación está construido como un
pipeline en el que los datos van pasando a través de diferentes etapas en los cuales estos datos son
modificados, agregados, filtrados y formateados hasta obtener el resultado deseado. Todo este
procesado es capaz de utilizar índices si existieran y se produce en memoria. Asimismo, MongoDB
proporciona una función MapReduce que puede ser utilizada para el procesamiento por lotes de datos
y operaciones de agregación.
MongoDB tiene la capacidad de realizar consultas utilizando JavaScript, haciendo que estas sean
enviadas directamente a la base de datos para ser ejecutadas.
Fragmentación (Sharding)
Si estás desarrollando un servicio que se va haciendo popular o los niveles de acceso a base de datos
son cada vez más altos, empezarás a notar que tu base de datos está siendo atacada por un tráfico
creciente y tu servidor esté sufriendo por los altos niveles de stress y te podrías ver en la necesidad de
actualizar tu infraestructura para soportar la demanda.
Aquí entra en juego el sharding, es el modo en el que hacemos nuestra base de datos escalable. En lugar
de tener una colección en una base de datos, la pondríamos en varias bases de datos distribuidas, de
modo que a la hora de consultar los datos de dicha colección, los recuperemos como si de una única
base de datos se tratase. Mongo se encargará de averiguar de manera transparente en qué base de
datos se encuentran los datos.
Los fragmentos estarán formados por replica set, de modo que si creamos tres fragmentos, cada uno de
los cuales tiene una replica set con tres servidores, estaríamos hablando de un total de nueve
servidores.
Principales problemas
MongoDB garantiza ACID dentro del mismo documento. El no implementar las propiedades ACID
genera que la base de datos no asegure la durabilidad, la integridad, la consistencia y el aislamiento
requeridos obligatoriamente en las transacciones. Es posible que en futuras versiones esto se solucione.
Problemas de consistencia
En versiones anteriores de la base de datos las lecturas estrictamente consistentes ven versiones
obsoletas de documentos, también pueden devolver datos incorrectos de lecturas que nunca deberían
haber ocurrido.17
MongoDB bloquea la base de datos a nivel de documento ante cada operación de escritura. Sólo se
podrán hacer operaciones de escritura concurrentes entre distintos documentos.
Problemas de escalabilidad
Casos de uso
MongoDB es utilizado para uno o varios de estos casos por varias empresas.21
MongoDB guarda la estructura de los datos en documentos tipo JSON con un esquema dinámico
llamado BSON, lo que implica que no existe un esquema predefinido. Los elementos de los datos se
denominan documentos y se guardan en colecciones. Una colección puede tener un número
indeterminado de documentos. Comparando con una base de datos relacional, se puede decir que las
colecciones son como tablas y los documentos son registros en la tabla. La diferencia es que en una base
de datos relacional cada registro en una tabla tiene la misma cantidad de campos, mientras que en
MongoDB cada documento en una colección puede tener diferentes campos. En un documento, se
pueden agregar, eliminar, modificar o renombrar nuevos campos en cualquier momento,22 ya que no
hay un esquema predefinido. La estructura de un documento es simple y compuesta por pares
llave/valor, parecido a las matrices asociativas en un lenguaje de programación, esto es debido a que
MongoDB sigue el formato de JSON. En MongoDB la clave es el nombre del campo y el valor es su
contenido, los cuales se separan mediante el uso de “:”, tal y como se puede ver en el siguiente ejemplo.
Como valor se pueden usar números, cadenas o datos binarios como imágenes o cualquier otro.
"_id": ObjectId("4efa8d2b7d284dad101e4bc7"),
"Age": 29,
"Address": {
"City": "VERSAILLES"
En este ejemplo se puede ver que en el campo “Address” se contiene otro documento que tiene los
campos de “Street” y “City”.
Los siguientes comandos pueden ser instalados para el manejo y la administración del sistema de base
de datos:
mongo:23 es un Shell interactivo que permite a los desarrolladores y administradores ver, insertar,
eliminar y actualizar datos en su base de datos. Este también permite entre otras funciones la
replicación de datos, configuración de sharding, apagar los servidores, ejecutar JavaScript y todos los
comandos que se puedan realizar.
mongotop:25 es un instrumento de línea de comandos que provee un método para dar seguimiento a la
cantidad de tiempo que dura una lectura o escritura de datos en una instancia. También provee
estadísticas en el nivel de cada colección.
ACID
En bases de datos se denomina ACID a las características de los parámetros que permiten clasificar las
transacciones de los sistemas de gestión de bases de datos. Cuando se dice que es ACID compliant se
indica -en diversos grados- que éste permite realizar transacciones.
Definiciones
Atomicidad: Si cuando una operación consiste en una serie de pasos, bien todos ellos se ejecutan o bien
ninguno, es decir, las transacciones son completas.
Consistencia: (Integridad). Es la propiedad que asegura que sólo se empieza aquello que se puede
acabar. Por lo tanto se ejecutan aquellas operaciones que no van a romper las reglas y directrices de
Integridad de la base de datos. La propiedad de consistencia sostiene que cualquier transacción llevará
a la base de datos desde un estado válido a otro también válido. "La Integridad de la Base de Datos nos
permite asegurar que los datos son exactos y consistentes, es decir que estén siempre intactos, sean
siempre los esperados y que de ninguna manera cambian ni se deformen. De esta manera podemos
garantizar que la información que se presenta al usuario será siempre la misma."
Aislamiento: Esta propiedad asegura que una operación no puede afectar a otras. Esto asegura que la
realización de dos transacciones sobre la misma información sean independientes y no generen ningún
tipo de error. Esta propiedad define cómo y cuándo los cambios producidos por una operación se hacen
visibles para las demás operaciones concurrentes. El aislamiento puede alcanzarse en distintos niveles,
siendo el parámetro esencial a la hora de seleccionar SGBDs.
Durabilidad: (Persistencia). Esta propiedad asegura que una vez realizada la operación, esta persistirá y
no se podrá deshacer aunque falle el sistema y que de esta forma los datos sobrevivan de alguna
manera.
Cumpliendo estos 4 requisitos un sistema gestor de bases de datos puede ser considerado ACID
Compliant.
Puesta en práctica
Poner las características ACID en ejecución no es tan sencillo. El proceso de una transacción requiere a
menudo un número de cambios pequeños al ser realizado, incluyendo la puesta al día de los índices que
son utilizados en el sistema para acelerar búsquedas. Esta secuencia de operaciones puede fallar por un
número de razones; por ejemplo, el sistema puede no tener ningún sitio disponible en sus
accionamientos de disco, o puede haber sobrepasado su tiempo de CPU asignado.
ACID sugiere que la base de datos pueda realizar todas estas operaciones inmediatamente. De hecho
esto es difícil de conseguir. Hay dos clases de técnicas populares: escribir a un registro antes de
continuar y la paginación de la sombra. En ambos casos, los bloqueos se deben implantar antes que la
información sea actualizada, y dependiendo de la técnica puesta en práctica, todos los datos se tienen
que haber leído. En escribir a un registro antes de continuar, la atomicidad es garantizada
asegurándose que toda la información esté escrita a un registro antes que se escriba a la base de datos.
Eso permite que la base de datos vuelva a un estado anterior en caso de un desplome. En sombrear, las
actualizaciones se aplican a una copia de la base de datos, y se activa la nueva copia cuando la
transacción sea confiable. La copia refiere a partes sin cambios de la vieja versión de la base de datos,
en vez de ser un duplicado entero.
Esto significa que debe realizarse un bloqueo en cualquier momento antes de procesar datos en una
base de datos, incluso en operaciones leídas. Mantener una gran cantidad de bloqueos da lugar a un
aumento substancial indirecto de los procesos así como a una alteración de la concurrencia de ellos. Si
el usuario A está procesando una transacción que ha leído una fila de los datos que el usuario B desea
modificar, por ejemplo, el usuario B debe esperar hasta que el otro usuario acabe..
Una alternativa a la fijación es mantener copias separadas de cualquier dato que se modifique. Esto
permite a usuarios leer datos sin adquirir ningún bloqueo. Usando de nuevo el ejemplo anterior,
cuando la transacción del usuario consigue los datos que el usuario B ha modificado, la base de datos
puede recuperar la versión exacta de los datos para que el usuario A comience su transacción. Esto
asegura que el usuario A consiga una vista constante de la base de datos aunque otros usuarios estén
cambiando datos.
Es difícill garantizar las características ACID en un ambiente de red. Las conexiones de red pueden
fallar, o dos usuarios pueden utilizar la misma parte de la base de datos al mismo tiempo.