Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Designing Data-Intensive Applications: 2. Data Models and Query Languages #3

Open
guilleiguaran opened this issue Apr 17, 2019 · 3 comments
Labels

Comments

@guilleiguaran
Copy link
Collaborator

Esta semana a cargo: @sescobb27
Siguiente semana: @ricardorojass

@sescobb27
Copy link

sescobb27 commented Apr 22, 2019

Cuando diseñamos aplicaciones complejas lo que hacemos es contruir niveles de abstraccion sobre otros niveles de abstraccion de mas bajo nivel tratando cada vez de ocultar la complejidad de nuestras aplicaciones a travez de APIs; estas abstracciones permiten que diferentes grupos de personas trabajen efectivamente usando un mismo "lenguaje" ubicuo, en este caso los lenguajes de las bases de datos permiten que los desarrolladores de una aplicacion puedan trabajar con los ingenieros de una base de datos usando un mismo lenguaje.

En este capitulo se trabajara sobre los diferentes modelos de datos (SQL, NoSQL, Grafos entre otros) y sus lenguajes para consulta de datos (Query Languages)

Modelo Relacional vs Modelo basado en Documentos (Relational Model Versus Document Model)

El mejor ejemplo y mas conocido sobre el Modelo Relacional son las bases de datos SQL basados en el modelo relacional de Edgar Codd en donde los datos estan organizados en relaciones llamadas tablas (tables) en SQL y cada relacion es una coleccion the tuplas sin orden llamadas filas (rows). a mediados los 80s las bases de datos relacionales fueron las herramientas predilectas de la mayoria de personas y projectos que requerian almacenar datos relacionales que tuvieran cierta estructura y desde entonces su predileccion ha durado cerca mas de 25 años.

La preferencia sobre las bases de datos relacionales nace a rason de que en los años 60s y 70s otros modelos de base de datos obligaban a los desarrolladores de aplicaciones a pensar sobre la representacion interna de los datos mientras que el modelo relacional oculta esta representacion a travel de un lenguaje declarativo con el cual se pueden explorar los datos de una manera mas corta y conciza dejando que el motor de busqueda decida como recorrer los datos, optmizar consultas, alamcenamiento y muchas mas cosas.

El nacimiento de NoSQL (The Birth of NoSQL)

NoSQL nace en el 2010 cuando alguien le puso un titulo llamativo a su charla para un meetup sobre bases de datos no relaciones y que fuera tendencia en twitter para que a la gente le diera curiosidad saber que era eso de NoSQL pero en realidad significa No Solo SQL (Not Only SQL) y no hace referencia a alguna tecnologia.

El movimiento NoSQL esta impulsado por la necesidad de una escalabilidad mucho mas grande que de lo que las bases de datos relacionales nos pueden brindar (tanto en tamaño de datos como en cantidad de escrituras), una gran variedad de productos de codigo libre (OpenSource) sobre base de datos comerciales y costosas y lo restrictivo que podrian llegar a ser los esquemas relacionales ofreciendo modelos de datos sin esquemas y mas expresivos aunque hoy en dia muchas de estos modelos relacionales an adoptado algunos de attributos de los modelos no relacionales como por ejemplo soporte para documentos JSON.

Discordancia en la Modelacion Objetual-Relacional(The Object-Relational Mismatch)

En la actualidad muchas aplicaciones usan lenguajes basados en objetos para modelar sus dominios, el problema radica en la discordancia que existe para mapear esos objectos y sus relaciones a una base de datos relacional, donde normalmente solo se tienen tablas, filas y columnas, es alli donde nacen herramientas complicadas que ayudan hacer la traduccion de estos objectos y sus relaciones a lenguaje SQL, estas herramientas son llamados ORMs o Object Relational Mapping pero no pueden ocultar por completo todas las differencias que existen entre ambos modelos.

Por lo general las bases de datos no relacionales optan por una representacion de los datos en lenguaje JSON, en este caso hablaremos de las base de datos basadas en documentos (Document Data Bases), las cuales pueden representar varios pros y contras como por ejemplo:

PROS:

  • la localidad de los datos es mas consiza que en un modelo relacional y por esto tiene mejor rendimiento (performance); en un modelo relacional es necesario hacer un join entre multiples tablas para realizar asociaciones entre los datos, mientras que en el modelo basado en documentos la representacion JSON permite que todos los datos estan en un mismo lugar, es decir, dentro de la informacion del documento padre o raiz (Document Root)
  • en las relaciones uno-a-muchos (one-to-many) la informacion puede ser representada en forma de arbol y la representacion JSON hace esta estructura explicita, tambien trae facilidades a la hora de actualizar un dato
  • al no tener un esquema explicito puede ser mas flexible el almacenamiento de los datos (schema on write), pero se tiene un esquema implicito al leer los datos (schema on read)
  • el modelo basado en documentos puede asemejar de una mejor manera la forma en la que traducimos nuestras estructuras de datos de nuestras aplicaciones a la forma en las que las almacenamos en el motor de la base de datos
  • el modelo basado en documentos sin esquema es beneficioso cuando los datos som hetereogeneos, es decir, se tiene una estructura dinamica

CONS:

  • las relaciones muchos-a-muchos (many-to-many) entre los datos son mas eficientes en el modelo relacional que en el modelo basado en documentos, ya que el motor de la base de datos es el que realiza estas asociaciones en una sola llamada, mientras que en el basado en documentos se necesitan hacer este tipo de asociaciones a nivel de aplicacion, por lo que significa varios llamados a la base de datos para extraer la informacion, lo cual puede implicar cambios a lo largo del codigo cuando la estructura de los datos cambian lo que puede provocar inconsistencias a nivel de aplicacion
  • en el modelo basado en documentos tener relaciones muchos-a-muchos o uno-a-muchos puede significar duplicar datos lo que puede implicar tener que actualizar un dato en muchas partes, lo que puede perjudicar los tiempos de respuesta
  • en el modelo basado en documentos no puedes hacer una relacion directa a un item dentro de un documento padre, se tiene que hacer referencia indirecta usando caminos (paths) entre los documentos
  • el modelo basados en documentos sin esquema no garantiza en que tipo de dato o si el campo existe en un esquema, es obligacion de la aplicacion validar este tipo de casos, mientras que en el modelo relacional, la base de datos se segura que los datos que sean escritos se adhieran al esquema estipulado
  • para datos altamente interconectados el modelo basado en documentos puede no ser el adecuado, el modelo relacional es aceptable pero la mejor opcion seria un modelo basado en grafos
  • en el modelo basado en documentos las actualizaciones de datos (updates) pueden requerir ser reescritos cuando la actualizacion incrementa el tamaño de los datos

Lenguajes de Consulta de Datos (Query Languages for Data)

SQL fue introducido como un lenguage de datos declarativo que fue desarrollado siguiendo la misma estructura que el algebra relacional, en este se describe el objetivo de la consulta, los patrones deseados y como transformar los datos, mas no los pasos para llegar a ella, ocultando asi los detaller de la implementacion lo cual permite que los motores de busqueda que han sido el resultado de decadas de investigacion para optimizar esas consultas sean los encargados de escoger como ejecutar la instruccion; por otro lado los lenguajes imperativos describen una serie de pasos ordenados de como realizar una consulta usando estructuras de control de flujo que ya se conocen de la programacion, e.g condicionales, ciclos y actualizacion de variables, pero esto hace casi imposible que el motor de la base de datos haga optimizaciones sobre el codigo sin romper la consulta. otras diferencias son:

  • SQL permite que el motor de la base de datos paralelize la ejecucion de la instruccion, mientras que es muy dificil para el motor de la base de datos paralelizar una busqueda imperativa
  • SQL no garantiza un orden en la ejecucion de consultas, por lo que le permite hacer optimizaciones sobre la consulta que pueden modificar el orden sin que sea un problema, mientras que en consultas imperativas el motor no puede asegurar que cambiar el orden de los rultados no va a dañar el resultado de la consulta
  • Los lenguajes declarativos no estan limitados a SQL sino que los conocemos en otros lenguajes como CSS, XPATH, XSL etc.

MapReduce Querying

MapReduce es un modelo de programacion de bajo nivel para el procesamiento de datos en grupos a gran escala, donde pueden ser utilizadas muchas maquinas (un cluster) de forma distribuida gracias a su facilidad de paralelizacion y distribucion. Este modelo es usado en bases de datos como MongoDB pero solo para hacer busquedas de solo lectura a travez de muchos documentos. Habiendo dicho esto MapReduce no es un lenguaje ni declarativo ni completamente imperativo, ya que a travez de un lenguage declarativo hace filtros sobre los datos recibidos, y usando lenguaje imperativo mapea, modifica y reduce la informacion a los resultados deseados.

MapReduce se define en 2 funciones, una funcion Map que se encarga de transformar los datos y moldearlos a corde se necesitan, y una funcion Reduce que se encarga de acumular y computar el resultado final con los datos mapeados de la funcion Map; ambas funciones son puras, lo que quiere decir que no se puede realizar otras busquedas dentro de ellas ni otro efecto colateral o side effect.

La implementacion de MapReduce de MongoDB dio soporte a un lenguage declarativo para las funciones de Map y Reduce las cuales permiten que, como ya se habia hablado antes, el motor de busqueda pueda optimizar y paralelizar de una mejor manera las operaciones en la base de datos, este lenguage declarativo ha sido llamado "Aggregation Pipeline"

Graph-Like Data Models

Las relaciones muchos-a-muchos son una funcionalidad importante para distinguir si el modelo de la aplicacion se adapta a un modelo basado en documentos si la aplicacion tiene principalmente relaciones uno-a-muchos, se adapta a un modelo relacional si la aplicacion tiene muchas relaciones simples de muchos-a-muchos, pero en los casos en los que las relaciones comienzan a ser mas complejas, mas anidadas, se vuelva mas natural ver nuestras aplicaciones y sus datos como grafos, donde cada vertice son nuetras entidades y cada conexion o edge son sus relaciones; un ejemplo de aplicaciones que pueden ser moldeadas como grafos son las redes sociales, la web tal y como la conocemos, las redes entre otros usos, ya que los grafos no estan limitados solo a datos homogeneos, el poder de los grafos es la manera consistente en la cual se pueden almacenar todo tipo de datos distintos en un sola base de datos.

Existen varias maneras distintas, pero relacionadas, de organizar y consultar los datos en un grafo como por ejemplo usando Grafos de Propiedades (Property Graphs), Almacenamiento de Tripletas (Triple Store) y varios lenguajes declarativos para consultas en grafos como Cypher, SPARQL y Datalog.

Grafos de Propiedades (Property Graphs)

  • Cada vertice consiste en un identificador unico (ID), un conjunto de conexiones salientes, un conjunto de conexiones entrantes y una coleccion de tuplas de propiedades llave-valor (key-value)
  • Cada conexion consiste en un identificador unico (ID), el vertice desde donde inicia (Tail Vertex), el vertice en donde termina (Head Vertex), una etiqueta que describe la relacion entre ambos vertices y una collecion de tuplas de propiedaded llave-valor (key-value)
  • No hay esquema que restrinja que tipo de datos puede ser almacenados o asociados (vertices)
  • Dado un vertice se puede encontrar cualquier otro vertice relacionado con este en cualquier direccion (entrante o saliente), para llegar a un vertice siempre hay un camino a seguir, ya sea hacia adelante o hacia atras
  • Usando etiquetas puedes guardar cualquier tipo de informacion y accederla de una forma consistente, clara y concisa permitiendo mantener un modelo de datos limpio y claro
  • Permite la evolucion de los modelos de datos adaptandose a los nuevas estructuras de datos de la aplicacion conforma esta tambien evoluciona

Almacenamiento de Tripletas (Triple-Stores)

En su mayoria es equivalente al modelo de Grafos de Propiedades pero con distintas palabras; toda la informacion en este modelo es almacenado en 3 partes (Sujeto, Predicado, Objeto) e.g (Jim, likes, Bananas) donde el sujeto es equivalente a un vertice en un grafo, el objecto puede ser un tipo de dato primitivo e.g (Texto, Numero etc) donde el predicado haria las veces de una tupla llave-valor del vertice asociado. U otro vertice en el grafo, donde en ese caso el predicado es una conexion, el Sujeto es el (Tail Vertex) y el Objecto es el (Head Vertex) e.g (lucy, marriedTo, alain)

@guilleiguaran
Copy link
Collaborator Author

guilleiguaran commented Apr 25, 2019

@sescobb27 excelente overview!

Para agregar algo que tambien menciona el autor es que la linea que separa las DB relacionales y algunas NoSQL se ha hecho cada vez mas delgada en los ultimos años.

Por una parte DBs como Postgres y MySQL ya tienen soporte para almacenar columnas de tipo JSON[1][2] y soportan operaciones sobre estas columnas[3][4] y algunas base de datos NoSQL como RethinkDB soportan joins[5] mientras que otras usan lenguajes de consulta muy similares a SQL como Cassandra que usa CQL[6]

Adicionalmente ya hay algunas DB NoSQL con soporte para transacciones como MongoDB[7] (aunque esto seria algo que habria que examinar posteriormente en detalle porque no todas las DBs que soportan transacciones ofrecen las mismas garantias en estas y todos los vendors usan su propia definicion de ACID)

[1] https://www.postgresql.org/docs/10/datatype-json.html
[2] https://dev.mysql.com/doc/refman/8.0/en/json.html
[3] https://www.postgresql.org/docs/9.3/functions-json.html
[4] https://dev.mysql.com/doc/refman/8.0/en/json-functions.html
[5] https://www.rethinkdb.com/docs/table-joins/
[6] http://cassandra.apache.org/doc/latest/cql/dml.html
[7] https://www.mongodb.com/transactions

@glrodasz
Copy link

glrodasz commented May 18, 2019

Polyglot persistence el uso de bases de datos relacionales y no-relacionales en un mismo sistema.

https://martinfowler.com/bliki/PolyglotPersistence.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants