Hola amigos Antes de partir para la segunda parte de las vacaciones de mayo, compartimos con ustedes el material que tradujimos en la víspera del lanzamiento de una nueva transmisión al ritmo de
"DBMS relacional" .

Los desarrolladores de aplicaciones pasan mucho tiempo comparando múltiples bases de datos operativas para elegir la que mejor funcione para su carga de trabajo prevista. Las necesidades pueden incluir modelado de datos simplificado, garantías transaccionales, rendimiento de lectura / escritura, escala horizontal y tolerancia a fallas. Por tradición, la elección comienza con una categoría de base de datos, SQL o NoSQL, ya que cada categoría proporciona un conjunto claro de compensaciones. El alto rendimiento en términos de baja latencia y alto rendimiento generalmente se considera un requisito de compensación y, por lo tanto, es necesario para cualquier base de datos en la muestra.
El propósito de este artículo es ayudar a los desarrolladores de aplicaciones a tomar la decisión correcta entre SQL y NoSQL en el contexto del modelado de datos de aplicaciones. Analizaremos una base de datos SQL, a saber, PostgreSQL y dos bases de datos NoSQL, Cassandra y MongoDB, para hablar sobre los conceptos básicos del diseño de la base de datos, como crear tablas, rellenarlas, leer datos de la tabla y eliminarlas. En el próximo artículo, definitivamente veremos los índices, las transacciones, las UNIONES, las directivas TTL y el diseño de bases de datos basadas en JSON.
¿Cuál es la diferencia entre SQL y NoSQL?Las bases de datos SQL aumentan la flexibilidad de la aplicación con garantías transaccionales ACID, así como su capacidad de consultar datos utilizando JOIN de manera inesperada además de los modelos de bases de datos relacionales normalizados existentes.
Dada su arquitectura monolítica / de nodo único y el uso de un modelo de replicación maestro-esclavo para la redundancia, las bases de datos SQL tradicionales no tienen dos características importantes: escalabilidad lineal del registro (es decir, división automática en varios nodos) y pérdida de datos automática / cero. Esto significa que la cantidad de datos recibidos no puede exceder el rendimiento máximo de escritura de un nodo. Además, se debe tener en cuenta cierta pérdida temporal de datos durante la tolerancia a fallas (en una arquitectura sin compartir recursos). Aquí debe tener en cuenta que las confirmaciones recientes aún no se han reflejado en la copia esclava. Las actualizaciones sin tiempo de inactividad también son difíciles de lograr en las bases de datos SQL.
Las bases de datos NoSQL generalmente se distribuyen por naturaleza, es decir en ellos, los datos se dividen en secciones y se distribuyen en varios nodos. Requieren desnormalización. Esto significa que los datos ingresados también deben copiarse varias veces para responder a las solicitudes específicas que envíe. El objetivo general es obtener un alto rendimiento al reducir la cantidad de fragmentos disponibles durante la lectura. Sigue la afirmación de que NoSQL requiere que modele sus consultas, mientras que SQL requiere que modele sus datos.
NoSQL se enfoca en lograr un alto rendimiento en un clúster distribuido, y esta es la razón principal para muchas compensaciones de diseño de bases de datos que incluyen ACID de pérdida de transacciones, UNIONES e índices secundarios globales consistentes.
Se cree que aunque las bases de datos NoSQL proporcionan escalabilidad de escritura lineal y alta tolerancia a fallas, la pérdida de garantías transaccionales las hace inadecuadas para datos críticos para la misión.
La siguiente tabla muestra cómo el modelado de datos en NoSQL difiere de SQL.
SQL y NoSQL: ¿Por qué se necesitan ambos?Las aplicaciones del mundo real con una gran cantidad de usuarios, como Amazon.com, Netflix, Uber y Airbnb, llevan a cabo tareas complejas y de clasificación múltiple. Por ejemplo, una aplicación de comercio electrónico como Amazon.com necesita almacenar datos livianos y altamente críticos, como información sobre usuarios, productos, pedidos, facturas, junto con datos pesados pero menos confidenciales, como revisiones de productos, mensajes de soporte , actividad del usuario, opiniones de los usuarios y recomendaciones. Naturalmente, estas aplicaciones se basan en al menos una base de datos SQL junto con al menos una base de datos NoSQL. En los sistemas interregionales y globales, la base de datos NoSQL funciona como un caché geo-distribuido para los datos almacenados en una fuente confiable, una base de datos SQL, trabajando en cualquier región.
¿Cómo combina YugaByte DB SQL y NoSQL?Construido sobre un motor de almacenamiento mixto orientado a registros, fragmentación automática, replicación de consenso distribuida fragmentada y transacciones distribuidas ACID (inspiradas en Google Spanner), YugaByte DB es la primera base de datos de código abierto del mundo que es simultáneamente compatible con NoSQL (Cassandra & Redis ) y SQL (PostgreSQL). Como se muestra en la tabla a continuación, YSQL, la API YugaByte DB compatible con Cassandra, agrega los conceptos de transacciones ACID simples y de múltiples claves e índices secundarios globales a las API NoSQL, abriendo así la era de las bases de datos NoSQL transaccionales. Además, YSQL, una API YugaByte DB compatible con PostgreSQL, agrega la noción de escala de escritura lineal y tolerancia automática a fallas a la API SQL, presentando bases de datos SQL distribuidas al mundo. Dado que la base de datos YugaByte DB es esencialmente transaccional, la API NoSQL ahora se puede usar en el contexto de datos de misión crítica.

Como se indicó anteriormente en el artículo
"Introducción de YSQL: una API SQL distribuida compatible con PostgreSQL para YugaByte DB" , la elección entre SQL o NoSQL en YugaByte DB depende completamente de las características de la carga de trabajo principal:
- Si la carga de trabajo principal es operaciones de múltiples claves con JOIN, al elegir YSQL, comprenda que sus claves se pueden distribuir en varios nodos, lo que conducirá a un mayor retraso y / o menor rendimiento que en NoSQL.
- De lo contrario, seleccione cualquiera de las dos API NoSQL, teniendo en cuenta que obtendrá un mejor rendimiento como resultado de las consultas que se atienden desde un nodo a la vez. YugaByte DB puede servir como una única base de datos operativa para aplicaciones complejas reales en las que necesita administrar múltiples cargas de trabajo al mismo tiempo.
El laboratorio de modelado de datos en la siguiente sección se basa en las bases de datos YugaByte DB compatibles con PostgreSQL y Cassandra API, a diferencia de las bases de datos de origen. Este enfoque enfatiza la facilidad de interacción con dos API diferentes (en dos puertos diferentes) del mismo grupo de bases de datos, en lugar de usar grupos completamente independientes de dos bases de datos diferentes.
En las siguientes secciones, nos reuniremos con el laboratorio de modelado de datos para ilustrar las diferencias y algunas características comunes de las bases de datos en cuestión.
Laboratorio de modelado de datosInstalación de base de datosDado el énfasis en el diseño de un modelo de datos (en lugar de arquitecturas de implementación complejas), instalaremos las bases de datos en contenedores Docker en la computadora local, y luego interactuaremos con ellos utilizando sus correspondientes shells de línea de comandos.
Compatible con PostgreSQL y Cassandra, base de datos YugaByte DBmkdir ~/yugabyte && cd ~/yugabyte wget https://downloads.yugabyte.com/yb-docker-ctl && chmod +x yb-docker-ctl docker pull yugabytedb/yugabyte ./yb-docker-ctl create
Mongodb docker run
Línea de comando de accesoVamos a conectarnos a las bases de datos utilizando el shell de la línea de comandos para las API correspondientes.
PostgreSQLpsql es un shell de línea de comando para interactuar con PostgreSQL. Para facilitar su uso, YugaByte DB viene con psql directamente en la carpeta bin.
docker exec -it yb-postgres-n1 /home/yugabyte/postgres/bin/psql -p 5433 -U postgres
Cassandracqlsh es un shell de línea de comandos para interactuar con Cassandra y sus bases de datos compatibles a través de CQL (lenguaje de consulta Cassandra). Para facilitar su uso, YugaByte DB viene con
cqlsh
en el
bin
.
Tenga en cuenta que CQL se inspiró en SQL y tiene conceptos similares a tablas, filas, columnas e índices. Sin embargo, como lenguaje NoSQL, agrega un cierto conjunto de restricciones, la mayoría de las cuales también cubriremos en otros artículos.
docker exec -it yb-tserver-n1 /home/yugabyte/bin/cqlsh
Mongodbmongo es un shell de línea de comando para interactuar con MongoDB. Se puede encontrar en el directorio bin de la instalación de MongoDB.
docker exec -it my-mongo bash cd bin mongo
Creación de tablaAhora podemos interactuar con la base de datos para realizar varias operaciones utilizando la línea de comando. Comencemos creando una tabla que almacene información sobre canciones escritas por diferentes artistas. Estas canciones pueden ser parte de un álbum. También atributos opcionales para la canción: año de lanzamiento, precio, género y calificación. Necesitamos considerar atributos adicionales que pueden ser necesarios en el futuro a través del campo "etiquetas". Puede almacenar datos semiestructurados como pares clave-valor.
PostgreSQL CREATE TABLE Music ( Artist VARCHAR(20) NOT NULL, SongTitle VARCHAR(30) NOT NULL, AlbumTitle VARCHAR(25), Year INT, Price FLOAT, Genre VARCHAR(10), CriticRating FLOAT, Tags TEXT, PRIMARY KEY(Artist, SongTitle) );
CassandraCrear una tabla en Cassandra es muy similar a PostgreSQL.
Una de las principales diferencias es la falta de restricciones de integridad (por ejemplo, NO NULL), pero esto es responsabilidad de la aplicación, no de la base de datos NoSQL . La clave principal consta de una clave de sección (columna Artista en el ejemplo a continuación) y un conjunto de columnas de agrupación (columna SongTitle en el ejemplo a continuación). La clave de partición determina en qué partición / fragmento colocar la fila, y las columnas de agrupamiento indican cómo deben organizarse los datos dentro del fragmento actual.
CREATE KEYSPACE myapp; USE myapp; CREATE TABLE Music ( Artist TEXT, SongTitle TEXT, AlbumTitle TEXT, Year INT, Price FLOAT, Genre TEXT, CriticRating FLOAT, Tags TEXT, PRIMARY KEY(Artist, SongTitle) );
MongodbMongoDB organiza los datos en bases de datos (Base de datos) (similar a Keyspace en Cassandra), donde hay colecciones (Colecciones) (similares a tablas), que contienen documentos (Documentos) (similares a filas en una tabla). MongoDB básicamente no requiere la definición del esquema original. El comando
"usar base de datos" que se muestra a continuación crea una instancia de la base de datos en la primera llamada y cambia el contexto de la base de datos recién creada. Incluso las colecciones no necesitan ser creadas explícitamente, se crean automáticamente, simplemente cuando agrega el primer documento a una nueva colección. Tenga en cuenta que MongoDB usa la base de datos de prueba de forma predeterminada, por lo tanto, cualquier operación de nivel de recopilación sin especificar una base de datos específica se realizará de forma predeterminada.
use myNewDatabase;
Recuperando información de la tabla PostgreSQL \d Music Table "public.music" Column | Type | Collation | Nullable | Default
Cassandra DESCRIBE TABLE MUSIC; CREATE TABLE myapp.music ( artist text, songtitle text, albumtitle text, year int, price float, genre text, tags text, PRIMARY KEY (artist, songtitle) ) WITH CLUSTERING ORDER BY (songtitle ASC) AND default_time_to_live = 0 AND transactions = {'enabled': 'false'};
Mongodb use myNewDatabase; show collections;
Publicar datos en una tabla PostgreSQL INSERT INTO Music (Artist, SongTitle, AlbumTitle, Year, Price, Genre, CriticRating, Tags) VALUES( 'No One You Know', 'Call Me Today', 'Somewhat Famous', 2015, 2.14, 'Country', 7.8, '{"Composers": ["Smith", "Jones", "Davis"],"LengthInSeconds": 214}' ); INSERT INTO Music (Artist, SongTitle, AlbumTitle, Price, Genre, CriticRating) VALUES( 'No One You Know', 'My Dog Spot', 'Hey Now', 1.98, 'Country', 8.4 ); INSERT INTO Music (Artist, SongTitle, AlbumTitle, Price, Genre) VALUES( 'The Acme Band', 'Look Out, World', 'The Buck Starts Here', 0.99, 'Rock' ); INSERT INTO Music (Artist, SongTitle, AlbumTitle, Price, Genre, Tags) VALUES( 'The Acme Band', 'Still In Love', 'The Buck Starts Here', 2.47, 'Rock', '{"radioStationsPlaying": ["KHCR", "KBQX", "WTNR", "WJJH"], "tourDates": { "Seattle": "20150625", "Cleveland": "20150630"}, "rotation": Heavy}' );
CassandraEn general, la expresión
INSERT
en Cassandra es muy similar a la de PostgreSQL. Sin embargo, hay una gran diferencia en la semántica. En Cassandra,
INSERT
realidad una operación
UPSERT
donde los últimos valores se agregan a la cadena en caso de que la cadena ya exista.
La entrada de datos es similar a la inserción de PostgreSQL anterior
MongodbAunque MongoDB es una base de datos NoSQL, como Cassandra, su operación de inserción no tiene nada que ver con el comportamiento semántico en Cassandra. En MongoDB,
insert () no tiene capacidades
UPSERT
, lo que lo hace parecer PostgreSQL. Agregar datos predeterminados sin
_idspecified
agregará un nuevo documento a la colección.
db.music.insert( {
artist: "No One You Know",
songTitle: "Call Me Today",
albumTitle: "Somewhat Famous",
year: 2015,
price: 2.14,
genre: "Country",
tags: {
Composers: ["Smith", "Jones", "Davis"],
LengthInSeconds: 214
}
}
);
db.music.insert( {
artist: "No One You Know",
songTitle: "My Dog Spot",
albumTitle: "Hey Now",
price: 1.98,
genre: "Country",
criticRating: 8.4
}
);
db.music.insert( {
artist: "The Acme Band",
songTitle: "Look Out, World",
albumTitle:"The Buck Starts Here",
price: 0.99,
genre: "Rock"
}
);
db.music.insert( {
artist: "The Acme Band",
songTitle: "Still In Love",
albumTitle:"The Buck Starts Here",
price: 2.47,
genre: "Rock",
tags: {
radioStationsPlaying:["KHCR", "KBQX", "WTNR", "WJJH"],
tourDates: {
Seattle: "20150625",
Cleveland: "20150630"
},
rotation: "Heavy"
}
}
);
Consulta de tablaQuizás la diferencia más significativa entre SQL y NoSQL en términos de diseño de consultas es el uso de las instrucciones
FROM
y
WHERE
. SQL le permite seleccionar varias tablas después de una
FROM
, y una
WHERE
puede ser de cualquier complejidad (incluidas las operaciones
JOIN
entre tablas). Sin embargo, NoSQL tiende a imponer una restricción estricta en
FROM
y funciona con una sola tabla especificada, y en
WHERE
, la clave primaria siempre debe especificarse. Esto se debe al deseo de mejorar el rendimiento de NoSQL, del que hablamos anteriormente. Este deseo conduce a todas las reducciones posibles en cualquier interacción entre tablas y claves. Puede dar lugar a una gran demora en la comunicación internodal al responder a una solicitud y, por lo tanto, es mejor evitarlo en principio. Por ejemplo, Cassandra requiere que las consultas se limiten a ciertos operadores (solo se permiten
=, IN, <, >, =>, <=
) en las teclas de partición, excepto cuando se solicita un índice secundario (aquí solo se permite el operador =).
PostgreSQLA continuación se ofrecen tres ejemplos de consultas que una base de datos SQL puede ejecutar fácilmente.
- Imprime todas las canciones del artista;
- Imprima todas las canciones del artista que coincidan con la primera parte del nombre;
- Enumere todas las canciones del artista que tengan una palabra específica en el título y que tengan un precio inferior a 1.00.
SELECT * FROM Music WHERE Artist='No One You Know'; SELECT * FROM Music WHERE Artist='No One You Know' AND SongTitle LIKE 'Call%'; SELECT * FROM Music WHERE Artist='No One You Know' AND SongTitle LIKE '%Today%' AND Price > 1.00;
CassandraDe las consultas PostgreSQL anteriores, solo la primera funcionará en Cassandra sin cambios, ya que la instrucción
LIKE
no se puede aplicar a columnas de agrupación como
SongTitle
. En este caso, solo se permiten operadores
=
e
IN
.
SELECT * FROM Music WHERE Artist='No One You Know'; SELECT * FROM Music WHERE Artist='No One You Know' AND SongTitle IN ('Call Me Today', 'My Dog Spot') AND Price > 1.00;
MongodbComo se muestra en ejemplos anteriores, el método principal para crear consultas en MongoDB es
db.collection.find () . Este método contiene explícitamente el nombre de la colección (
music
en el ejemplo a continuación), por lo que está prohibida la solicitud de varias colecciones.
db.music.find( { artist: "No One You Know" } ); db.music.find( { artist: "No One You Know", songTitle: /Call/ } );
Leer todas las filas de la tablaLeer todas las líneas es solo un caso especial de la plantilla de consulta que examinamos anteriormente.
PostgreSQL SELECT * FROM Music;
CassandraSimilar al ejemplo en PostgreSQL anterior.
Mongodb
db.music.find( {} );
Edición de datos en una tablaPostgreSQLPostgreSQL proporciona una
UPDATE
para modificar datos. No tiene capacidades
UPSERT
, por lo que la ejecución de esta instrucción fallará si la fila ya no está en la base de datos.
UPDATE Music SET Genre = 'Disco' WHERE Artist = 'The Acme Band' AND SongTitle = 'Still In Love';
CassandraCassandra tiene una
UPDATE
similar a PostgreSQL.
UPDATE
tiene la misma semántica
UPSERT
INSERT
.
Similar al ejemplo en PostgreSQL anterior.
MongodbLa operación
update () en MongoDB puede actualizar completamente un documento existente o actualizar solo ciertos campos. Por defecto, actualiza solo un documento con la semántica
UPSERT
. La actualización de múltiples documentos y comportamientos similares a
UPSERT
se puede aplicar estableciendo indicadores adicionales para la operación. Por ejemplo, en el ejemplo a continuación, su canción actualiza el género de un artista en particular.
db.music.update( {"artist": "The Acme Band"}, { $set: { "genre": "Disco" } }, {"multi": true, "upsert": true} );
Eliminar datos de una tablaPostgreSQL DELETE FROM Music WHERE Artist = 'The Acme Band' AND SongTitle = 'Look Out, World';
CassandraSimilar al ejemplo en PostgreSQL anterior.
MongodbMongoDB tiene dos tipos de operaciones para eliminar documentos:
deleteOne () / deleteMany () y
remove () . Ambos tipos eliminan documentos, pero devuelven resultados diferentes.
db.music.deleteMany( { artist: "The Acme Band" } );
Eliminar tablaPostgreSQL DROP TABLE Music;
CassandraSimilar al ejemplo en PostgreSQL anterior.
Mongodb db.music.drop();
ConclusiónEl debate sobre la elección entre SQL y NoSQL ha sido furioso durante más de 10 años. Hay dos aspectos principales de este debate: la arquitectura del motor de la base de datos (SQL monolítico, transaccional versus NoSQL distribuido, no transaccional) y el enfoque del diseño de la base de datos (modelar datos en SQL versus modelar sus consultas en NoSQL).
Con una base de datos transaccional distribuida como YugaByte DB, el debate sobre la arquitectura de la base de datos se puede disipar fácilmente. A medida que los volúmenes de datos se hacen más grandes de lo que se puede escribir en un solo nodo, se hace necesaria una arquitectura completamente distribuida que admita escalabilidad lineal de grabaciones con fragmentación / reequilibrio automático.
Además de ser dicho en un artículo de
Google Cloud , las arquitecturas transaccionales estrictamente consistentes ahora se usan más ampliamente para proporcionar una mejor flexibilidad de desarrollo que las arquitecturas no transaccionales y, en última instancia, consistentes.
Volviendo a la discusión del diseño de la base de datos, es justo decir que ambos enfoques de diseño (SQL y NoSQL) son necesarios para cualquier aplicación real compleja. El enfoque de "modelado de datos" del enfoque SQL permite a los desarrolladores cumplir más fácilmente los requisitos comerciales cambiantes, mientras que el "datos de modelado" del enfoque NoSQL permite a los mismos desarrolladores manejar grandes cantidades de datos con baja latencia y alto rendimiento. Es por esta razón que YugaByte DB proporciona API SQL y NoSQL en un núcleo común, en lugar de promover uno de los enfoques. Además, al garantizar la compatibilidad con los lenguajes de bases de datos populares, incluidos PostgreSQL y Cassandra, YugaByte DB garantiza que los desarrolladores no tengan que aprender otro idioma para trabajar con un motor de base de datos distribuido y estrictamente coherente.
En este artículo, descubrimos cómo los fundamentos del diseño de la base de datos difieren en PostgreSQL, Cassandra y MongoDB. En los siguientes artículos, profundizaremos en conceptos de diseño avanzados, como índices, transacciones, uniones, directivas TTL y documentos JSON.
Le deseamos una maravillosa estadía el resto del fin de semana y lo invitamos a un
seminario web gratuito , que se realizará el 14 de mayo.