2.1 Aparición del término NoSQL

Recientemente, el término "NoSQL" se ha puesto muy de moda y popular, todo tipo de soluciones de software se están desarrollando y promoviendo activamente bajo este signo. NoSQL se ha convertido en sinónimo de grandes cantidades de datos, escalabilidad lineal, clústeres, tolerancia a fallas, no relacionalidad. Sin embargo, pocas personas tienen una comprensión clara de qué es el almacenamiento NoSQL, cómo apareció el término y qué características comunes tienen. Tratemos de llenar este vacío.

Lo más interesante del término es que a pesar de que se usó por primera vez a finales de los 90, solo adquirió un significado real en la forma en que se usa ahora a mediados de 2009. Inicialmente, este era el nombre de un abierto -base de datos de origen creada por Carlo Strozzi, que almacenó todos los datos como archivos ASCII y usó scripts de shell en lugar de SQL para acceder a los datos. No tenía nada que ver con "NoSQL" en su forma actual.

En junio de 2009, Johan Oskarsson organizó una reunión en San Francisco para discutir las nuevas tendencias en el mercado de almacenamiento y procesamiento de TI. El principal impulso de la reunión fueron los nuevos productos de código abierto como BigTable y Dynamo. Para una señal brillante para una reunión, era necesario encontrar un término amplio y conciso que encajara perfectamente en el hashtag de Twitter. Uno de estos términos fue propuesto por Eric Evans de RackSpace: "NoSQL". El término fue planeado para una sola reunión y no tenía una carga semántica profunda, pero sucedió que se extendió por la red global como un anuncio viral y se convirtió en el nombre de facto de toda una tendencia en la industria de TI. Por cierto, Voldemort (clon de Amazon Dynamo), Cassandra, Hbase (análogos de Google BigTable), Hypertable, CouchDB, MongoDB hablaron en la conferencia.

Vale la pena enfatizar una vez más que el término "NoSQL" tiene un origen completamente espontáneo y no tiene una definición generalmente aceptada o una institución científica detrás. Este nombre más bien caracteriza el vector de desarrollo de TI que se aleja de las bases de datos relacionales. Significa Not Only SQL, aunque hay partidarios de la definición directa de No SQL. Pramod Sadalaj y Martin Fowler intentaron agrupar y sistematizar el conocimiento sobre el mundo NoSQL en su reciente libro "NoSQL Distilled".

2.2 Características básicas de las bases de datos NoSQL

Hay pocas características comunes para todos los NoSQL, ya que muchos sistemas heterogéneos ahora están ocultos bajo la etiqueta NoSQL (quizás la lista más completa se pueda encontrar en http://nosql-database.org/). Muchas características son peculiares solo de ciertas bases de datos NoSQL, definitivamente mencionaré esto en la lista.

1. No se utiliza SQL

Me refiero a ANSI SQL DML, ya que muchas bases de datos intentan usar lenguajes de consulta similares a la conocida sintaxis favorita, pero nadie ha logrado implementarlo por completo y es poco probable que lo logre. Aunque se rumorea que hay startups que están intentando implementar SQL, por ejemplo en hadup ( http://www.drawntoscalehq.com/ y http://www.hadapt.com/ ).

2. No estructurado (sin esquema)

El significado es que en las bases de datos NoSQL, a diferencia de las bases de datos relacionales, la estructura de datos no está regulada (o está débilmente tipeada, si hacemos analogías con los lenguajes de programación): puede agregar un campo arbitrario en una línea o documento separado sin primero cambiar declarativamente la estructura de toda la mesa. Por lo tanto, si es necesario cambiar el modelo de datos, la única acción suficiente es reflejar el cambio en el código de la aplicación.

Por ejemplo, al cambiar el nombre de un campo en MongoDB:

BasicDBObject order = new BasicDBObject();
order.put("date", orderDate); // this field was a long time ago
order.put("totalSum", total); // before we just used "sum"

Si cambiamos la lógica de la aplicación, también esperamos un nuevo campo al leer. Pero debido a la falta de un esquema de datos, el campo totalSum no se encuentra en otros objetos Order ya existentes. En esta situación, hay dos opciones para tomar medidas adicionales.

El primero es rastrear todos los documentos y actualizar este campo en todos los documentos existentes. Debido al volumen de datos, este proceso se produce sin bloqueos (comparable al comando de columna para cambiar el nombre de la tabla), por lo que durante la actualización, otros procesos pueden leer los datos ya existentes. Por lo tanto, la segunda opción, verificar el código de la aplicación, es inevitable:

BasicDBObject order = new BasicDBObject();
Double totalSum = order.getDouble("sum"); // This is the old model
if (totalSum  == null)
totalSum = order.getDouble("totalSum"); // This is the updated model

Y ya cuando volvamos a grabar, escribiremos este campo en la base de datos en un nuevo formato.

Una consecuencia agradable de la ausencia de un esquema es la eficiencia de trabajar con datos dispersos. Si un documento tiene un campo de fecha de publicación y el segundo no, no se creará ningún campo vacío de fecha de publicación para el segundo. Esto, en principio, es lógico, pero un ejemplo menos obvio son las bases de datos NoSQL de la familia de columnas, que utilizan los conceptos familiares de tablas/columnas. Sin embargo, debido a la falta de un esquema, las columnas no se declaran declarativamente y se pueden cambiar/agregar durante la sesión de la base de datos de un usuario. Esto permite, en particular, el uso de columnas dinámicas para la implementación de listas.

El esquema no estructurado tiene sus inconvenientes, además de la sobrecarga mencionada anteriormente en el código de la aplicación al cambiar el modelo de datos, la ausencia de todo tipo de restricciones desde la base (no nulo, único, restricción de verificación, etc.), además existen dificultades adicionales para comprender y controlar los datos de la estructura cuando se trabaja con la base de datos de diferentes proyectos en paralelo (no hay diccionarios al lado de la base de datos). Sin embargo, en un mundo moderno que cambia rápidamente, esa flexibilidad sigue siendo una ventaja. Un ejemplo es Twitter, que hace cinco años, junto con el tuit, almacenaba solo un poco de información adicional (hora, identificador de Twitter y algunos bytes más de metainformación), pero ahora, además del mensaje en sí, algunos más. kilobytes de metadatos se almacenan en la base de datos.

(De aquí en adelante, nos referiremos principalmente a bases de datos de clave-valor, documento y familia de columnas, las bases de datos de gráficos pueden no tener estas propiedades)

2.3. Representación de datos en forma de agregados (agregados)

A diferencia del modelo relacional, que almacena la entidad comercial lógica de la aplicación en varias tablas físicas con fines de normalización, las tiendas NoSQL operan en estas entidades como si fueran objetos holísticos:

Este ejemplo muestra agregaciones para un modelo relacional conceptual estándar de comercio electrónico "Pedido - Artículos de pedido - Pagos - Producto". En ambos casos, el pedido se combina con posiciones en un objeto lógico, mientras que cada posición almacena un enlace al producto y algunos de sus atributos, por ejemplo, el nombre (dicha desnormalización es necesaria para no solicitar un objeto de producto al recuperar una orden - la regla principal de los sistemas distribuidos es "unión" entre objetos). En un agregado, los pagos se combinan con el pedido y son parte integral del objeto, en el otro, se colocan en un objeto separado. Esto demuestra la regla principal para diseñar una estructura de datos en bases de datos NoSQL: debe obedecer los requisitos de la aplicación y optimizarse tanto como sea posible para las solicitudes más frecuentes.

Muchos objetarán, señalando que trabajar con objetos grandes, a menudo desnormalizados, está plagado de numerosos problemas cuando se intentan consultas arbitrarias sobre datos cuando las consultas no encajan en la estructura de agregados. ¿Qué pasa si usamos pedidos junto con líneas de pedido y pagos (así es como funciona la aplicación), pero la empresa nos pide que contemos cuántas unidades de un producto en particular se vendieron el mes pasado? En este caso, en lugar de escanear la tabla OrderItem (en el caso de un modelo relacional), tendremos que recuperar los pedidos completos en almacenamiento NoSQL, aunque no necesitaremos mucha de esta información. Desafortunadamente, este es un compromiso que debe hacerse en un sistema distribuido: no podemos normalizar los datos como en un sistema convencional de un solo servidor,

Traté de agrupar los pros y los contras de ambos enfoques en una tabla: