<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Pablo Arango Ramirez</title>
    <description>The latest articles on DEV Community by Pablo Arango Ramirez (@pabloar).</description>
    <link>https://dev.to/pabloar</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2203200%2Fc6c3562d-afb8-4923-bbd2-7ef8fd25edb0.png</url>
      <title>DEV Community: Pablo Arango Ramirez</title>
      <link>https://dev.to/pabloar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pabloar"/>
    <language>en</language>
    <item>
      <title>Capítulo 3 - Almacenamiento y Acceso a Datos</title>
      <dc:creator>Pablo Arango Ramirez</dc:creator>
      <pubDate>Mon, 18 Nov 2024 01:11:16 +0000</pubDate>
      <link>https://dev.to/pabloar/capitulo-3-almacenamiento-y-acceso-a-datos-84d</link>
      <guid>https://dev.to/pabloar/capitulo-3-almacenamiento-y-acceso-a-datos-84d</guid>
      <description>&lt;p&gt;En su nivel más fundamental, una base de datos hace dos cosas&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Permite almacenar datos&lt;/li&gt;
&lt;li&gt;Permite consultar esos datos&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Desde las perspectiva de la BD, ¿Cómo podemos almacenar los datos? y, cuando nos consulten, cómo podemos devolver esos datos?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;    Probablemente usted no va a implementar su propio motor de almacenamiento, &lt;strong&gt;pero si va a escoger uno&lt;/strong&gt;. Por eso debe saber que hace un motor de almacenamiento por debajo&lt;/li&gt;
&lt;li&gt;    Hay diferencias muy marcadas entre los motores de almacenamiento optimizados para cargas &lt;strong&gt;transaccionales&lt;/strong&gt; vs los optimizados para cargas &lt;strong&gt;analíticas&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Motores de Almacenamiento -&lt;/strong&gt; Dos familias (Para sistemas transaccionales)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Estructurados por logs &lt;/li&gt;
&lt;li&gt;Orientado a paginación&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Las estructuras de datos que soportan las bases de datos modernas
&lt;/h2&gt;

&lt;p&gt;Ejemplo: Funciones &lt;strong&gt;db_get()&lt;/strong&gt; y &lt;strong&gt;db_set()&lt;/strong&gt; que implementan una base de datos muy sencilla&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;!&lt;/span&gt;/bin/bash
db_set &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; database
&lt;span class="o"&gt;}&lt;/span&gt;
db_get &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"^&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;,"&lt;/span&gt; database | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"s/^&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;,//"&lt;/span&gt; | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 1
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;db_set 42 &lt;span class="s1"&gt;'{"name":"San Francisco","attractions":["Exploratorium"]}'&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;db_get 42
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;:&lt;span class="s2"&gt;"San Francisco"&lt;/span&gt;,&lt;span class="s2"&gt;"attractions"&lt;/span&gt;:[&lt;span class="s2"&gt;"Exploratorium"&lt;/span&gt;&lt;span class="o"&gt;]}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;De la misma forma como funciona esta BD, muchas BDs de datos modernas utilizan un &lt;strong&gt;&lt;em&gt;log&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;log:&lt;/strong&gt; archivo tipo &lt;em&gt;append-only&lt;/em&gt; que es una secuencia de records añadidos al final de una estructura de datos&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Escribir datos → Buen desempeño. Insertar datos al final de un archivo es muy eficiente&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Consultar datos → Mal desempeño. El costo de consulta es O(n). Si se duplica la cantidad de records en la BD, el tiempo de consulta se duplica también. La solución a esto son los &lt;strong&gt;índices&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Índice:&lt;/strong&gt; estructura de datos adicional derivada de los datos primarios para obtener acceso rápido a los datos.&lt;br&gt;
    - Aceleran las consultas de lectura&lt;br&gt;
    - &lt;strong&gt;Pero,&lt;/strong&gt; hacen que las escrituras sean más lentas. Esto porque al escribir se debe actualizar el índice.&lt;/p&gt;

&lt;p&gt;Trade-off en sistemas de almacenamiento: Índices aceleran las consultas, pero afectan negativamente las escrituras &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Por eso es que las BDs no indexan todo de forma predeterminada, &lt;strong&gt;eso lo debe hacer el desarrollador porque es el que conoce los patrones de acceso a los datos&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Índices
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;def.&lt;/strong&gt; Estructura de datos adicional que se deriva de los datos primarios y sirve para facilitar la búsqueda de información en la BD.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Trade-off&lt;/em&gt; en los sistemas de almacenamiento

&lt;ul&gt;
&lt;li&gt;índices aumentan desempeño de lectura &lt;strong&gt;pero&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;reducen desempeño de escritura&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tipos de Índices&lt;/strong&gt; → Las estructuras de datos que soportan las bases de datos modernas&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;    Índices hash → “Hasheé” llaves a valores&lt;/li&gt;
&lt;li&gt;    Tablas SST → Tablas de cadenas de caracteres ordenadas (&lt;em&gt;sorted string tables&lt;/em&gt;). Almacena los datos en disco de forma ordenada&lt;/li&gt;
&lt;li&gt;    Árboles LSM → Log-structured merge tree&lt;/li&gt;
&lt;li&gt;    Árboles-B → Divida la BD en bloques de tamaño fijo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Índices Hash&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;def.&lt;/strong&gt; Estructura adicional tipo llave-valor donde la llave es el identificador del dato en la estructura primaria y el valor es la ubicación del dato en la tabla&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;    Se basa en la estructura &lt;em&gt;HashMap (*tipo de dato *&lt;/em&gt;&lt;em&gt;diccionario&lt;/em&gt;** en múltiples lenguajes de programación)&lt;/li&gt;
&lt;li&gt;    Log + Hash map&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ferbjk8r9bbumt5pa8j13.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ferbjk8r9bbumt5pa8j13.png" alt="Image description" width="505" height="258"&gt;&lt;/a&gt;&lt;/p&gt;
Crédito de la imagen: Martin Kleppmann, Designing Data-Intensive Applications, O'Reilly Media, 2017, Capítulo 3.



&lt;ul&gt;
&lt;li&gt;Cada vez que añade un nuevo dato al &lt;strong&gt;log&lt;/strong&gt; de la BD, también actualiza el Hash Map&lt;/li&gt;
&lt;li&gt;Para no quedarse sin espacio en disco, se realiza un proceso de &lt;strong&gt;compactación&lt;/strong&gt; y &lt;strong&gt;agrupamiento&lt;/strong&gt;(merging) para solo almacenar el valor más actualizado de una llave y reducir el espacio en disco

&lt;ul&gt;
&lt;li&gt;compactación → Eliminar llaves duplicadas en el log y solo almacenar la última copia&lt;/li&gt;
&lt;li&gt;Agrupamiento (merging) → Juntar varios segmentos en uno solo
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl6n0x464nukew7ohaxjv.png" alt="Image description" width="800" height="410"&gt;Crédito de la imagen: Martin Kleppmann, Designing Data-Intensive Applications, O'Reilly Media, 2017, Capítulo 3.

&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Limitaciones de una tabla Hash&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Debe estar en memoria principal → En disco es muy complicado tener un hash map porque es lento. Debe hacer muchas operaciones aleatorias de entrada y salida y es costoso hacer que escale eficientemente.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tablas SST&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;def.&lt;/strong&gt; Tablas de cadenas de caracteres ordenados (&lt;em&gt;sorted string tables&lt;/em&gt;)&lt;br&gt;
Formato de almacenamiento en disco donde la secuencia de parejas llave-valor está ordenado con base en la llave.&lt;br&gt;
&lt;strong&gt;Características:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Las parejas llave-valor se almacenan en forma ordenada en disco&lt;/li&gt;
&lt;li&gt;Cada llave solo puede aparecer una vez, con el valor actualizado
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fblg6fmvb3i41p8b53st6.png" alt="Image description" width="468" height="318"&gt;Crédito de la imagen: Martin Kleppmann, Designing Data-Intensive Applications, O'Reilly Media, 2017, Capítulo 3.

&lt;/li&gt;
&lt;li&gt;El proceso de agrupamiento (merging) se encarga de eliminar los valores no actualizados de las llaves&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Árboles LSM (&lt;em&gt;Log-structured merge tree&lt;/em&gt;)&lt;/strong&gt;: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Usada en Bases de datos NoSQL&lt;/strong&gt;&lt;br&gt;
Son una cascada de Tablas SST que se integran en segundo plano&lt;br&gt;
“&lt;em&gt;Data is initially written to a memory component (memtable) and then periodically flushed to disk-based components (SSTables).&lt;/em&gt;”&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Datos ordenados → consultas basadas en rangos eficientes&lt;/li&gt;
&lt;li&gt;Escrituras secuenciales a disco → Buen &lt;em&gt;throughput&lt;/em&gt; de escritura&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr5mfxtoam8q66tmtrrwu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr5mfxtoam8q66tmtrrwu.png" alt="Image description" width="800" height="393"&gt;&lt;/a&gt;Crédito de la imagen: Martin Kleppmann, Designing Data-Intensive Applications, O'Reilly Media, 2017, Capítulo 3.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Usuario hace una operación de escritura&lt;/li&gt;
&lt;li&gt;Las escrituras es escriben en memoria principal

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;memtable →&lt;/strong&gt; Estructura de datos en memoria para almacenar datos recientes&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;Cuando memtable se llena, se &lt;strong&gt;ordenan&lt;/strong&gt; y se envian a disco (&lt;em&gt;sort and flush&lt;/em&gt;)&lt;/li&gt;

&lt;li&gt;Al estar en disco después de un tiempo, ocurre un algoritmo de agrupamiento y compactación.

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;merge&lt;/em&gt; y &lt;em&gt;compact&lt;/em&gt; → Agrupar las SSTables y eliminar valores actualizados o borrados&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;Básicamente, se tiene una estructura tipo árbol en RAM que recibe las escrituras (Memtable). Cuando la &lt;em&gt;memtable&lt;/em&gt; se llena, los datos se envían al disco. En el disco se hace un proceso de segundo plano que agrupa y compacta los segmentos para eliminar valores eliminados y desactualizados. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nota.&lt;/strong&gt; DynamoDB, Cassandra, BigTable y RocksDB usan Árboles LSM&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google BigTable fue la tecnología pionera que introdujo los términos SSTable y Memtable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Árboles-B (B-Trees )&lt;/strong&gt;&lt;br&gt;
El tipo de indice más utilizado y el estándar para las bases de datos relacionales (Y muchas no relacionales). Tipo &lt;em&gt;update-in-place&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Filosofía&lt;/strong&gt;: Dividen la base datos en bloques de tamaño fijo (páginas), tradicionalmente de 4 KB y leen/escriben una página a la vez.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;   Es un diseño que encaja más con el hardware subyacente porque los discos también se dividen en bloques de tamaño fijo&lt;/li&gt;
&lt;li&gt;   Cada página se puede identificar utilizando una dirección (como un apuntador en disco, no en memoria). Se utiliza las referencias de disco para construir un &lt;strong&gt;árbol de páginas&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;    Cada llave en las “hojas” del B-tree tiene una apuntador a la dirección en disco donde está el bloque que contiene el valor de la llave&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiu8g5hmy799irp94rpj8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiu8g5hmy799irp94rpj8.png" alt="Image description" width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;
Crédito de la imagen: Martin Kleppmann, Designing Data-Intensive Applications, O'Reilly Media, 2017, Capítulo 3.



&lt;p&gt;Son el tipo de estructura de índice más utilizado en bases de datos relacionales. &lt;strong&gt;MySQL, Postgres, Oracle&lt;/strong&gt; y muchas más usan árboles-b para sus indices.&lt;/p&gt;

&lt;p&gt;El árbol siempre está balanceado y tiene una profundidad de O(log n)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Casi todas las BDs pueden estar en un B-tree que sea de 3 a 4 niveles de profundidad. Un árbol de 3 niveles, páginas de 4KB y un factor de branching de 500 puede almacenar hasta 265 TB&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=aZjYr87r1b8" rel="noopener noreferrer"&gt;Explicación Árboles-B&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Procesamiento Transaccional vs Analítico
&lt;/h1&gt;

&lt;p&gt;Originalmente, una escritura a una BD representaba una &lt;strong&gt;&lt;em&gt;transacción comercial.&lt;/em&gt;&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cliente comprando algo&lt;/li&gt;
&lt;li&gt;pagarle a un empleado&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;OLTP →&lt;/strong&gt; &lt;em&gt;Online transaction processing&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Patrones de acceso similares a los de una transacción comercial

&lt;ul&gt;
&lt;li&gt;App normalmente consulta un pequeño número de filas con base en un índice (llave)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;OLAP →&lt;/strong&gt; &lt;em&gt;Online analytical processing&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Patrones de acceso para el análisis de datos

&lt;ul&gt;
&lt;li&gt;Consulta sobre cantidades masivas de filas pero a pocas columnas. Calcula valores agregados (SUM, AVG, COUNT)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Procesamiento transaccional vs analitico&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Propiedad&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;OLTP&lt;/th&gt;
&lt;th&gt;OLAP&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Patrón de lectura&lt;/td&gt;
&lt;td&gt;Pocas filas por consulta, utilizando una llave para acceder al dato.&lt;/td&gt;
&lt;td&gt;Valores agregados sobre muchas filas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Patrón de escritura&lt;/td&gt;
&lt;td&gt;Acceso aleatorio. Baja latencia de escritura para el input del usuario&lt;/td&gt;
&lt;td&gt;Importar datos en lote (ETL) o eventos de stream&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Usado por&lt;/td&gt;
&lt;td&gt;Usuario final, via app web&lt;/td&gt;
&lt;td&gt;Analista interno para Inteligencia de negocios&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Que representan los datos&lt;/td&gt;
&lt;td&gt;El estado actual de los datos&lt;/td&gt;
&lt;td&gt;Historial de eventos que han ocurrido con el tiempo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tamaño de los datos&lt;/td&gt;
&lt;td&gt;GB a TB&lt;/td&gt;
&lt;td&gt;TB a PB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;En resumen&lt;/td&gt;
&lt;td&gt;muchas consultas pequeñas con baja latencia&lt;/td&gt;
&lt;td&gt;Pocas consultas grandes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;¿El mismo sistema que utilizo para que mis clientes reserven un asiento en el avión  es el mismo sistema que utiliza el analista para detectar patrones de compra en los vuelos? &lt;strong&gt;NO!&lt;/strong&gt;&lt;br&gt;
Por eso se crearon dos aproximaciones distintas. Dos tipos de motores de almacenamiento&lt;br&gt;
&lt;strong&gt;OLTP&lt;/strong&gt; → BD que soporta que los clientes reserven un puesto en el avión&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Optimizado para procesamiento transaccional&lt;/li&gt;
&lt;li&gt;Son sistemas “&lt;em&gt;user facing”&lt;/em&gt;. Manejan un volumen masivo de consultas&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;OLAP →&lt;/strong&gt; BD que soporta las operaciones de analitica e inteligencia de negocios. Por ejemplo, averiguar cuantos puestos se han vendido en un mes&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Optimizado para analítica&lt;/li&gt;
&lt;li&gt;Son sistemas &lt;em&gt;“Business-analyst facing”.&lt;/em&gt; Manejan poco volumen de consultas pero las consultas son mucho más grandes&lt;/li&gt;
&lt;li&gt;Cuando sus consultas necesitan escanear una gran cantidad de filas, los índices de las BDs OLTPs pierden relevancia. Acá es más importante codificar los datos de una forma compacta.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Al principio de los sistemas computacionales, las BDs se utilizaban tanto para procesamiento transaccional como analítico. SQL es flexible en ese aspecto. No obstante, la década de 1980 las compañías dejaron de usar sus sistemas OLTP para analítica y empezaron a hacer consultas de análisis en BDs separadas → &lt;strong&gt;Esas bases de datos se conocen como Bodegas de Datos (&lt;/strong&gt;Data warehouses)&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Warehousing (Bodegas de datos)
&lt;/h2&gt;

</description>
    </item>
    <item>
      <title>Capítulo 2 - Modelos de Datos y Lenguajes de Consulta</title>
      <dc:creator>Pablo Arango Ramirez</dc:creator>
      <pubDate>Tue, 22 Oct 2024 02:50:52 +0000</pubDate>
      <link>https://dev.to/pabloar/capitulo-2-modelos-de-datos-y-lenguajes-de-consulta-28eh</link>
      <guid>https://dev.to/pabloar/capitulo-2-modelos-de-datos-y-lenguajes-de-consulta-28eh</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnxij5ct0ejnw6u8x5lj0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnxij5ct0ejnw6u8x5lj0.png" alt="Crédito de la imagen: Martin Kleppmann, Designing Data-Intensive Applications, O'Reilly Media, 2017" width="800" height="609"&gt;&lt;/a&gt;&lt;/p&gt;
Crédito de la imagen: Martin Kleppmann, Designing Data-Intensive Applications, O'Reilly Media, 2017, Capítulo 2.



&lt;p&gt;&lt;strong&gt;Tipos de modelos de datos&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Jerárquico (El modelo inicial) → Desarrollado en los 1950s por IBM. No se adaptaba bien a las relaciones &lt;strong&gt;many-to-many&lt;/strong&gt;. &lt;a href="https://www.geeksforgeeks.org/hierarchical-model-in-dbms/" rel="noopener noreferrer"&gt;Modelo Jerárquico&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Relacional (SQL) → Solución al modelo jerárquico. Poco flexible&lt;/li&gt;
&lt;li&gt;Documental → Datos que vienen en documentos autocontenidos (JSON). Poco soporte de relación entre documentos&lt;/li&gt;
&lt;li&gt;Modelo de grafos → Nodos y ejes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;El Modelo Relacional&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Propuesto por &lt;strong&gt;Edgar Codd&lt;/strong&gt; en 1970&lt;/li&gt;
&lt;li&gt;Los datos se organizan en relaciones (tablas) donde cada relación es una colección no ordenada de tuplas (filas)&lt;/li&gt;
&lt;li&gt;Casos de uso originales

&lt;ul&gt;
&lt;li&gt;Procesamiento transaccional → operaciones de movimiento de dinero en un banco, reservas de aerolineas&lt;/li&gt;
&lt;li&gt;Procesamiento analítico en lotes → reportes, payroll, analítica&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Sigue el paradigma de &lt;strong&gt;&lt;em&gt;schema-on-write&lt;/em&gt;&lt;/strong&gt; (Esquema al escribir)

&lt;ul&gt;
&lt;li&gt;El esquema de los datos es explicito y el motor de BD se asegura que todos los datos escritos a la BD sean consistentes con el esquema predefinido.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;NoSQL&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Surgió con un hashtag de Twitter en el 2009&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;def.&lt;/strong&gt; Not ONLY SQL&lt;/li&gt;
&lt;li&gt;Sigue el paradigma de &lt;strong&gt;&lt;em&gt;schema-on-read&lt;/em&gt;&lt;/strong&gt; (Esquema al leer)&lt;/li&gt;
&lt;li&gt;Surgió debido a estos factores:

&lt;ul&gt;
&lt;li&gt;Necesidad de mayor escalabilidad que las BDs relacionales.&lt;/li&gt;
&lt;li&gt;Preferencia por software open-source gratis envés de productos de BDs relacionales empresariales.&lt;/li&gt;
&lt;li&gt;Operaciones de consultas especializadas que no están bien soportadas por el modelo relacional.&lt;/li&gt;
&lt;li&gt;Frustración con las restricciones de los esquemas relacionales.&lt;/li&gt;
&lt;li&gt;Necesidad de un modelo más dinámico y expresivo&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Problema:&lt;/strong&gt; Objetos vs Relaciones → Desajuste por Impedancia (&lt;em&gt;Impedance mismatch&lt;/em&gt;)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Impedance Mismatch:&lt;/strong&gt; Problema de incongruencia entre el modelo relacional y los objetos en el código de la aplicación. Es el conjunto de dificultades técnicas y conceptuales que surgen cuando se almacenan &lt;strong&gt;objetos&lt;/strong&gt; de programación en &lt;strong&gt;bases de datos con modelos relacionales&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Si los objetos en la app se almacenan en una BD con modelo relacional (SQL), se necesita una capa de traducción entre el código de la app y la modelo de la BD&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Solución → Mapeo Objeto-Relacional (&lt;/strong&gt;ORM: Object-relational mapping)

&lt;ul&gt;
&lt;li&gt;Frameworks de ORM&lt;/li&gt;
&lt;li&gt;Reducen el código &lt;em&gt;boilerplate&lt;/em&gt; requerido para esa capa de transición&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Ejemplos: Apache OpenJPA, SQLAlchemy, TypeORM&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Expresiones en distintos Modelos&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Perfil de Linkedin

&lt;ul&gt;
&lt;li&gt;Modelo Relacional&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5bpqfuxwletx2paw7u1x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5bpqfuxwletx2paw7u1x.png" alt="Image description" width="800" height="713"&gt;&lt;/a&gt;Martin Kleppmann, Designing Data-Intensive Applications, O'Reilly Media, 2017.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modelo Documental NoSQL (JSON)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"user_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;251&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"first_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pedro"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"positions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"job_title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"founder"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"organization"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EmpresaA"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"job_title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ceo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"organization"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EmpresaB"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Con el modelo JSON, la estructura de árbol implícita en el perfil de Linkedin, se vuelve explícita en el modelo de datos&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Versiones iniciales de una aplicación pueden encajar bien en un modelo documental JOIN-Free,&lt;/strong&gt; pero los datos tienen una tendencia a volverse más interconectados a medida que surgen nuevas funcionalidades&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;En algún punto va a necesitar &lt;strong&gt;many-to-many&lt;/strong&gt; y por ende utilizar &lt;strong&gt;joins&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Ejemplo Linkedin → Representar la organización donde trabaja la persona como una entidad.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbb5iwcf3hf72ita62s6q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbb5iwcf3hf72ita62s6q.png" alt="Image description" width="800" height="525"&gt;&lt;/a&gt;Crédito de la imagen: Martin Kleppmann, Designing Data-Intensive Applications, O'Reilly Media, 2017, Capítulo 2.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Debate&lt;/strong&gt;: ¿Cómo representar de mejor forma las relaciones de las entidades en una base de datos?&lt;/p&gt;

&lt;p&gt;Es una discusión más vieja que los esquemas NoSQL. Viene desde los primeros sistemas de bases de datos computacionales.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Caso&lt;/strong&gt;: La IMS de IBM utilizaba el modelo jerárquico. Este modelo no soportaba JOINs. En los 60s, los desarrolladores tenían que decidir entre duplicar datos (Normalizar) o resolver manualmente las referencias de un record a otro. &lt;a href="https://www.ibm.com/products/ims" rel="noopener noreferrer"&gt;IMS de IBM&lt;/a&gt;. 
&lt;strong&gt;Este es el mismo problema que tienen los desarrolladores hoy en día con las BDs documentales.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La solución a esto en su entonces fue el modelo relacional de &lt;strong&gt;SQL&lt;/strong&gt;. El modelo relacional permite poner todos los datos al descubierto con una lista de tuplas (tabla). El optimizador de consultas en una BD relacional automáticamente decide que partes de la consulta ejecutar y en qué orden hacerlo. &lt;/p&gt;

&lt;p&gt;Estas decisiones ya no las toma un desarrollador&lt;br&gt;
        - &lt;em&gt;“Solo se construye un optimizador de consultas una vez. Todas las apps que utilicen la BD se benefician de el”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Las BDs documentales se devolvieron al modelo jerárquico → almacena records embebidos (&lt;strong&gt;many-to-one&lt;/strong&gt;) en el mismo record, no en otra tabla&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cuando se trata de relaciones &lt;strong&gt;many-to-many&lt;/strong&gt;, el modelo documental y el modelo relacional no son muy distintos. En ambos casos, el ítem relacionado se referencia mediante un identificador único. Este identificador se utiliza como llave foránea en el otro ítem en el modelo relacional. En el modelo documental se usa como referencia a otro documento.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Modelo Relacional vs Modelo Documental&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Documental

&lt;ul&gt;
&lt;li&gt;Flexibilidad de esquema&lt;/li&gt;
&lt;li&gt;Mejor localidad de datos → Capacidad para mover computo (objetos) a datos almacenados&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Poco soporte de JOINS&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Relacional

&lt;ul&gt;
&lt;li&gt;Buen soporte de joins&lt;/li&gt;
&lt;li&gt;Buen soporte de relaciones &lt;strong&gt;many-to-one&lt;/strong&gt; y &lt;strong&gt;many-to-many&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Poca flexibilidad de esquema&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;¿Convergencia entre el modelo relacional y documental?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Postgres ya soporta documentos JSON como tipo de datos desde la versión 9. &lt;a href="https://www.postgresql.org/docs/current/datatype-json.html" rel="noopener noreferrer"&gt;Documentación Postgres&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Hay drivers de Mongo que automáticamente resuelven las referencias externas de documentos. Resuelve el problema desde el lado del cliente.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Parece ser que las BDs relacionales y documentales se están volviendo cada vez más parecidas. Esto es algo bueno porque los modelos de datos se complementan entre sí. Si una BD soporta datos que son &lt;em&gt;&lt;em&gt;document-like&lt;/em&gt;&lt;/em&gt; y también soporta consultas relacionales, las aplicaciones pueden utilizar la combinación de ambas funcionalidades que mejor se ajuste a sus necesidades.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Regla de pulgar:&lt;/strong&gt;&lt;br&gt;
Use documentales cuando&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tiene datos con relaciones &lt;strong&gt;one-to-many&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Necesita que un árbol de datos embebidos se cargue en la aplicación desde el inicio.&lt;/li&gt;
&lt;li&gt;Estructura de datos tipo documento.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use relacionales cuando&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Necesita muy buen soporte de joins&lt;/li&gt;
&lt;li&gt;Tiene relaciones &lt;strong&gt;many-to-many&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Lenguajes de Consulta
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Dos tipos de lenguajes: Declarativo e Imperativo&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Declarativo → SQL&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Le digo a la máquina &lt;strong&gt;que&lt;/strong&gt; datos y transformaciones quiero realizar frente a los datos, pero &lt;strong&gt;no le digo como realizar la consulta&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;animals&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;family&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;"sharks"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Imperativo → Lenguajes de programación (Java, python, JS)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Le digo a la máquina, &lt;strong&gt;como&lt;/strong&gt; ejecutar la consulta&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getSharks&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;sharks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;animals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="n"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;animals&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;family&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nv"&gt;"sharks"&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
            &lt;span class="n"&gt;sharks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;animals&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sharks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;La misma consulta se puede expresar de forma genérica con algebra relacional: &lt;em&gt;&lt;strong&gt;sharks = σ_family="Sharks" (animals)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;SQL Provee mejor soporte para algunos tipos de consultas&lt;/p&gt;

&lt;p&gt;Consultas tipo Map Reduce (Documentales) → Ej: Obtener número de tiburones por mes&lt;br&gt;
 &lt;strong&gt;SQL&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;date_trunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'month'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;observation_timestamp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;observation_month&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
                   &lt;span class="k"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num_animals&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;total_animals&lt;/span&gt;
            &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;observations&lt;/span&gt;
            &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;family&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Sharks'&lt;/span&gt;
            &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;observation_month&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Documental (Mongo)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.observations.mapReduce(
                function map() { 2
                    var year  = this.observationTimestamp.getFullYear();
                    var month = this.observationTimestamp.getMonth() + 1;
                    emit(year + "-" + month, this.numAnimals); 3
                },
                function reduce(key, values) { 4
                    return Array.sum(values); 5
                },
                {
                    query: { family: "Sharks" }, 1
                    out: "monthlySharkReport" 6
                }
            );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Modelo de Grafos
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;def.&lt;/strong&gt; Base de datos que almacena los datos como relaciones entre nodos conectados por ejes&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F51j98xqp181kltec70sn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F51j98xqp181kltec70sn.png" alt="Image description" width="800" height="374"&gt;&lt;/a&gt;Imagen: &lt;a href="https://www.larkinfolab.nl/partners/neo4j/" rel="noopener noreferrer"&gt;https://www.larkinfolab.nl/partners/neo4j/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ejemplo&lt;/strong&gt;: Representar el matrimonio de dos personas&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzghonf37y5rp9vtdocaw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzghonf37y5rp9vtdocaw.png" alt="Image description" width="800" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Estructura→ ejemplo Neo4J&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cada vertice (Nodo) consiste de

&lt;ul&gt;
&lt;li&gt;ID&lt;/li&gt;
&lt;li&gt;Ejes hacia afuera&lt;/li&gt;
&lt;li&gt;Ejes hacia adentro&lt;/li&gt;
&lt;li&gt;propiedades llave-valor&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Cada eje consiste de

&lt;ul&gt;
&lt;li&gt;Id&lt;/li&gt;
&lt;li&gt;Vertice origen&lt;/li&gt;
&lt;li&gt;Vertice destino&lt;/li&gt;
&lt;li&gt;etiqueta&lt;/li&gt;
&lt;li&gt;Propiedades llave - valor&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Los grafos son muy buenos para la evolucionabilidad del sistema. Un grafo se puede extender fácilmente para acomodar cambios en las estructuras de datos de la app.&lt;/p&gt;

&lt;p&gt;Ejemplo de lenguaje para BDs de grafos → &lt;strong&gt;Cypher&lt;/strong&gt; (Lenguaje de consultas utilizado en Neo4J)&lt;br&gt;
Ejemplo: Insertar el hecho que Idaho queda en USA y que USA queda en América del norte. Insertar que Lucy nació en Idaho&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        CREATE
        (NAmerica:Location {name: 'north america', type: 'continent'}),
        (USA:Location {name:'united states', type: 'country'}),
        (Idaho:Location {name: 'idaho', type 'state'}),
        (Lucy: Person {name:'Lucy'}),
        (Idaho) -[:WITHIN] -&amp;gt; (USA) -[:WITHIN] -&amp;gt; (NAmerica)
        (Lucy) -[:BORN_IN] -&amp;gt; (Idaho)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este modelo permite realizar consultas muy complejas con una sintaxis sencilla.&lt;br&gt;
Ejemplo: Encuentre los nombres de las personas que emigraron de USA a Europa&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;BORN_IN&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;  &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;WITHIN&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;..]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;us&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;Location&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'United States'&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;LIVES_IN&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;WITHIN&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;..]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;Location&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'Europe'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
    &lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;WITHIN&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;..]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;follow&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;within&lt;/span&gt; &lt;span class="n"&gt;edge&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;zero&lt;/span&gt; &lt;span class="k"&gt;or&lt;/span&gt; &lt;span class="k"&gt;more&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Encuentra todos los vertices (personas) que&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tengan un &lt;strong&gt;&lt;em&gt;born_in&lt;/em&gt;&lt;/strong&gt; eje a un vertice. Desde ese vértice siga una cadena ejes &lt;strong&gt;WITHINs&lt;/strong&gt; hasta que llegue a una ubicación que sea USA.&lt;/li&gt;
&lt;li&gt;Ese mismo vertice (persona) tenga un eje &lt;strong&gt;&lt;em&gt;lives_in&lt;/em&gt;&lt;/strong&gt; que lleve a un vertices que pertenezca a Europa.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Si fuera a hacer la misma consulta en &lt;strong&gt;SQL&lt;/strong&gt;, sería algo asi&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- in_usa es el set de vértices de todas las ubicaciones en USA&lt;/span&gt;
&lt;span class="n"&gt;in_usa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vertex_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
                      &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;vertex_id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vertices&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'United States'&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
                    &lt;span class="k"&gt;UNION&lt;/span&gt;
                      &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tail_vertex&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;edges&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
                        &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;in_usa&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;head_vertex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;in_usa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vertex_id&lt;/span&gt;
                        &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'within'&lt;/span&gt;
                  &lt;span class="p"&gt;),&lt;/span&gt;

&lt;span class="c1"&gt;-- in_europe es el set de vèrtices de todas las ubicaciones en Europa&lt;/span&gt;
                  &lt;span class="n"&gt;in_europe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vertex_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
                      &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;vertex_id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vertices&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Europe'&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
                    &lt;span class="k"&gt;UNION&lt;/span&gt;
                      &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tail_vertex&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;edges&lt;/span&gt;
                        &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;in_europe&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;head_vertex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;in_europe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vertex_id&lt;/span&gt;
                        &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'within'&lt;/span&gt;
                  &lt;span class="p"&gt;),&lt;/span&gt;

&lt;span class="c1"&gt;-- born_in_usa es el set de vértices de todas las personas que nacieron en USA&lt;/span&gt;
                  &lt;span class="n"&gt;born_in_usa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vertex_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
                    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tail_vertex&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;edges&lt;/span&gt;
                      &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;in_usa&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;head_vertex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;in_usa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vertex_id&lt;/span&gt;
                      &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'born_in'&lt;/span&gt;
                  &lt;span class="p"&gt;),&lt;/span&gt;

 &lt;span class="c1"&gt;-- lives_in_europe es el set de todas las personas que viven en Europa&lt;/span&gt;
                  &lt;span class="n"&gt;lives_in_europe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vertex_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
                    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tail_vertex&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;edges&lt;/span&gt;
                      &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;in_europe&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;head_vertex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;in_europe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vertex_id&lt;/span&gt;
                      &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'lives_in'&lt;/span&gt;
                  &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;vertices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;
                &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vertices&lt;/span&gt;
                &lt;span class="c1"&gt;-- join para encontrar a las personas que nacieron en USA y viven en Europa&lt;/span&gt;
                &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;born_in_usa&lt;/span&gt;     &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;vertices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vertex_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;born_in_usa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vertex_id&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;
                &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;lives_in_europe&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;vertices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vertex_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lives_in_europe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vertex_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Triple store &amp;amp; SPARQL →&lt;/strong&gt; Almacenar toda la información en forma de sentencias de tres partes&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sujeto&lt;/li&gt;
&lt;li&gt;Predicato&lt;/li&gt;
&lt;li&gt;Objeto&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ejemplo: Juan&lt;/strong&gt; Gustan &lt;strong&gt;bananos&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Modelo “Lucy vive en Londres”&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;lucy&lt;/span&gt;     &lt;span class="n"&gt;a&lt;/span&gt;       &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;lucy&lt;/span&gt;     &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;   &lt;span class="nv"&gt;"Lucy"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;lucy&lt;/span&gt;     &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;bornIn&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;idaho&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;idaho&lt;/span&gt;    &lt;span class="n"&gt;a&lt;/span&gt;       &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;idaho&lt;/span&gt;    &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;   &lt;span class="nv"&gt;"Idaho"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;idaho&lt;/span&gt;    &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;   &lt;span class="nv"&gt;"state"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;idaho&lt;/span&gt;    &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;within&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;usa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;usa&lt;/span&gt;      &lt;span class="n"&gt;a&lt;/span&gt;       &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;usa&lt;/span&gt;      &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;   &lt;span class="nv"&gt;"United States"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;usa&lt;/span&gt;      &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;   &lt;span class="nv"&gt;"country"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;usa&lt;/span&gt;      &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;within&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;namerica&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;namerica&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;       &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;namerica&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;   &lt;span class="nv"&gt;"North America"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;namerica&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;   &lt;span class="nv"&gt;"continent"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Nota.&lt;/strong&gt; → La web3 (web semantica) se basa en ese modelo&lt;br&gt;
&lt;a href="https://www.programstrategyhq.com/post/web3-meaning-explained" rel="noopener noreferrer"&gt;https://www.programstrategyhq.com/post/web3-meaning-explained&lt;/a&gt;&lt;/p&gt;

</description>
      <category>data</category>
      <category>sql</category>
      <category>nosql</category>
      <category>dataengineering</category>
    </item>
    <item>
      <title>Capítulo 9 - Consistencia y Consenso</title>
      <dc:creator>Pablo Arango Ramirez</dc:creator>
      <pubDate>Tue, 15 Oct 2024 01:54:37 +0000</pubDate>
      <link>https://dev.to/pabloar/capitulo-9-consistencia-y-consenso-20ci</link>
      <guid>https://dev.to/pabloar/capitulo-9-consistencia-y-consenso-20ci</guid>
      <description>&lt;h1&gt;
  
  
  Capítulo 9 - Consistencia y Consenso
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;“&lt;em&gt;Is it better to be alive and wrong or right and dead”&lt;/em&gt;  Jay Kreps&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F1b9d8785-c37a-4a76-b47c-c79368d73993%2Fb9c5b5ba-3a8d-45a7-8f45-e8b0cff9f76a%2FUntitled.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F1b9d8785-c37a-4a76-b47c-c79368d73993%2Fb9c5b5ba-3a8d-45a7-8f45-e8b0cff9f76a%2FUntitled.png" alt="Untitled" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Consistencia y consenso →&lt;/strong&gt; Algoritmos y protocolos para construir sistema distribudios &lt;strong&gt;tolerantes a fallas&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Se asume que todos los problemas que pueden ocurrir en un sistema distirbuido &lt;strong&gt;van a ocurrir&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Paquetes perdidos, reordenados o duplicados&lt;/li&gt;
&lt;li&gt;Demoras arbitrarias en la red&lt;/li&gt;
&lt;li&gt;Relojes desincronizados&lt;/li&gt;
&lt;li&gt;Puasas de nodos&lt;/li&gt;
&lt;li&gt;Nodos que se caen&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;La mejor forma para construir sistemas distribuidos tolerantes a fallas es mediante &lt;strong&gt;abstracciones de proposito general con garantias utiles.&lt;/strong&gt;
&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Consenso&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;def.&lt;/strong&gt; Garantía de que todos los nodos del sistema van a estar de acuerdo en algo&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Garantías de Consistencia&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Aislamiento de transacciones

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Serializabilidad&lt;/strong&gt; → prevenir condiciones de carrera&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Consistencia distribuida

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Linealizabilidad&lt;/strong&gt; → Coordinar el estado de las replicas en entornos donde hay demoras de red y fallos de nodos&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Linealizabilidad (Consistencia atómica)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;La garantía de consistencia más fuerte utlizada comunmente por los sistemas de datos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;def.&lt;/strong&gt; Dar la ilusión de que en el sistema solo hay “&lt;em&gt;Una copia de los datos”&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;En un sistema linealizable, todas las operaciones leen la versión más reciente de los datos. Se abstrae el hecho de que los datos están &lt;strong&gt;distribuidos,&lt;/strong&gt; dandole la ilusión a los clientes de que los datos están todos almacenados en el mismo sitio.&lt;/li&gt;
&lt;li&gt;Es una garantía de &lt;strong&gt;actualidad&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;El sistema se comporta como si solo existiera una copia de los datos, donde cada operación es atómica. Esto significa que por cada dos operaciones, &lt;strong&gt;siempre se puede señalar cual ocurrrió primero.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;a href="https://stackoverflow.com/questions/9762101/what-is-linearizability" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://stackoverflow.com/questions/9762101/what-is-linearizability" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/9762101/what-is-linearizability&lt;/a&gt;
&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Contra-Ejemplo →&lt;/strong&gt; Sistema No Linealizable&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F1b9d8785-c37a-4a76-b47c-c79368d73993%2F99e21f57-0879-4967-bf9f-865b65ada5b2%2FUntitled.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F1b9d8785-c37a-4a76-b47c-c79368d73993%2F99e21f57-0879-4967-bf9f-865b65ada5b2%2FUntitled.png" alt="Untitled" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bob leé datos de una nodo que no ha sido actualizado. El sistema &lt;strong&gt;no se comporta como si solo hubiera una copia de los datos.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Ejemplo -&lt;/strong&gt; Sistema Linealizable&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F1b9d8785-c37a-4a76-b47c-c79368d73993%2Fcb3c7c93-db1b-4711-9377-717c88e4522e%2FUntitled.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F1b9d8785-c37a-4a76-b47c-c79368d73993%2Fcb3c7c93-db1b-4711-9377-717c88e4522e%2FUntitled.png" alt="Untitled" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Después de que alguna operación de escritura leé el valor actualizado &lt;strong&gt;x=1,&lt;/strong&gt; todas las operaciones que le siguen &lt;strong&gt;deben leer el mismo valor.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Linealizabilidad ≠ Serializabilidad&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Serializabilidad&lt;/strong&gt; es una propiedad de &lt;strong&gt;aislamiento&lt;/strong&gt; de las transacciones → Garantiza que las transacciones se van a comportar como si se hubieran ejecutado serialmente, una detrás de otra&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linealizabilidad&lt;/strong&gt; es una propiedad de &lt;strong&gt;actualidad&lt;/strong&gt; en las operaciones de escritura y lectura de un registro de datos. No agrupa las operaciones en transacciones, por eso no previene problemas como las lecturas o escrituras sesgadas.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Casos de uso para usar Linealizabilidad&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Candados distribuidos → escoger un nodo para que sea el lider

&lt;ul&gt;
&lt;li&gt;Todos los nodos deben estar de acuerdo en quien es el lider&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Restricciones y univocidad&lt;/strong&gt; → Requerimiento para tener un valor único y actualizado donde todos los nodos deben estar de acuerdo

&lt;ul&gt;
&lt;li&gt;Nombres de usuarios unicos&lt;/li&gt;
&lt;li&gt;No balances negativos&lt;/li&gt;
&lt;li&gt;No personas reservando el mismo asiento&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Implementación de sistemas linealizables&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Replicación un solo lider → Linealizable&lt;/li&gt;
&lt;li&gt;Replicación multilider → No linealizable

&lt;ul&gt;
&lt;li&gt;Varios lideres se deben sincronizar de forma asíncrona&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Sin lider (&lt;em&gt;Leaderless&lt;/em&gt;) → No linealizale

&lt;ul&gt;
&lt;li&gt;La penalidad de linealizarlo es muy alta&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  El Costo de Linealizar → Teorema CAP
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F1b9d8785-c37a-4a76-b47c-c79368d73993%2F289885ba-c00f-47c7-a0cf-7774e12bda11%2FUntitled.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F1b9d8785-c37a-4a76-b47c-c79368d73993%2F289885ba-c00f-47c7-a0cf-7774e12bda11%2FUntitled.png" alt="Untitled" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Caso&lt;/strong&gt;: Cuando hay una interrupción de red, se debe escoger entre linealizabilidad (consistencia) o disponibilidad. Si los nodos de un sistema no se pueden comunicar y usted quiere que el sistema siga sirviendo tráfico, entonces el sistema no va a ser consistente, pero sí va a estar disponible. Por otro lado, si usted quiere preservar la consistencia, el sistema no va a estar disponible por un tiempo.

&lt;ul&gt;
&lt;li&gt;Cuando se construyen sistemas distribuidos en los que los componentes se conectan mediante una red que no es fiable (IP, Ethernet, etc.), se van a tener problemas de red. Trade-off entre disponibilidad y consistencia → &lt;strong&gt;Teorema CAP&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Teorema CAP →&lt;/strong&gt; &lt;em&gt;Consistency (Linearizability), Availability, Partition tolerance&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Si una aplicación requiere ser linealizable (consistente) y las réplicas (nodos) se desconectan, se debe esperar a que el error de red se resuelva para poder mantener la consistencia del sistema. Durante ese tiempo, los nodos que no tengan comunicación con el líder no estarán disponibles.  &lt;strong&gt;Consistencia (Linealizablidad) pero no disponibilidad&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Si una aplicación &lt;strong&gt;NO&lt;/strong&gt; requiere linealizabilidad y las replicas se desconectan del lider, cada nodo puede seguir procesando datos de forma independiente. Durante ese tiempo, el sistema no va a ser consistente entre sus nodos. &lt;strong&gt;No consistencia pero si disponibilidad&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F1b9d8785-c37a-4a76-b47c-c79368d73993%2Fb5790feb-8493-420d-83a3-718a0388a910%2FUntitled.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F1b9d8785-c37a-4a76-b47c-c79368d73993%2Fb5790feb-8493-420d-83a3-718a0388a910%2FUntitled.png" alt="Untitled" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;CAP&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consistencia → No hay datos desactualizados (desincronizados) entre las replicas del sistema. &lt;strong&gt;NUNCA&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Disponibilidad → Los clientes siguen recibiendo respuestas, inclusive si un nodo está fallando&lt;/li&gt;
&lt;li&gt;Tolerancia a particiones &lt;em&gt;(partition tolerance) →&lt;/em&gt; Sistema se mantiene funcional asi ocurran errores de red&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Nota.&lt;/strong&gt; El término CAP es un poco engañoso. Las particiones (errores) de red no son algo que usted pueda escoger. Si o si van a ocurrir. La forma indicada de plantear el teorema CAP es asi:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Consistente o disponible **cuando&lt;/em&gt;* ocurran particiones de red*&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Cuando hayan particiones de red, usted puede escoger entre mantener disponibilidad del sistema o ser consistente. &lt;strong&gt;NO AMBOS&lt;/strong&gt;&lt;/p&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Nota.&lt;/strong&gt; Si bien la linealizabilidad es una garantía util, &lt;strong&gt;pocos sistemas en la práctica son 100% linealizables.&lt;/strong&gt; Esto se debe a que la linealizabilidad es &lt;strong&gt;costosa&lt;/strong&gt; en terminos de desempeño. Soportar linealizabilidad hace que el sistema sea más lento.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Garantías de Orden
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ordenamiento y causalidad →&lt;/strong&gt; El orden ayuda a preservar la causalidad en un sistema&lt;/li&gt;
&lt;li&gt;La causalidad impone un ordenamiento de eventos

&lt;ul&gt;
&lt;li&gt;Causa viene antes del efecto&lt;/li&gt;
&lt;li&gt;Ejemplos → &lt;strong&gt;Dependencias causales&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Mensaje se envía antes de que el mensaje se reciba&lt;/li&gt;
&lt;li&gt;La pregunta viene antes de la respuesta&lt;/li&gt;
&lt;li&gt;Un nodo lee datos y escribe algo como resultado de la lectura de esos datos&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;Si un sistema obedece el ordenamiento impuesto por la causalidad de eventos es &lt;strong&gt;&lt;em&gt;causalmente consistente&lt;/em&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Ej: Aislamiento con snapshot es causalmente consistente&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;La linealizabilidad implica causalidad

&lt;ul&gt;
&lt;li&gt;Todo sistema linealizable preserva la causalidad de eventos correctamente&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Para que un sistema sea &lt;strong&gt;causalmente consistente,&lt;/strong&gt; no necesita ser linealizable. Hay formas de lograrlo que no tienen efectos tan negativos en el desempeño como la linealizabilidad pura.

&lt;ul&gt;
&lt;li&gt;Para preservar causalidad, se debe saber &lt;strong&gt;que operacion ocurrió antes de cualquier otra operación →&lt;/strong&gt; orden parcial&lt;/li&gt;
&lt;li&gt;Las operaciones concurrentes se procesan en cualquier orden, pero si una operación ocurre antes de otra, entonces se debe mantener el orden de procesamiento en el resto de replicas. Para lograr esto, se necesita un mecanismo para describir el &lt;strong&gt;conocimiento&lt;/strong&gt; de un nodo en el sistema.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Formas de capturar dependencias causales&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Ordenamiento secuencial →&lt;/strong&gt; numeros secuenciales o timestamps para ordenar eventos&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Estampilla Lamport&lt;/strong&gt; (Lamport timestamp) → Cada nodo almacena una pareja de (&lt;strong&gt;contador, Id Nodo) donde&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Contador: Número de operaciones que ha procesado&lt;/li&gt;
&lt;li&gt;Id Nodo: Identificador del nodo que actualizó el objeto&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F1b9d8785-c37a-4a76-b47c-c79368d73993%2F5dde85fa-cc8a-4913-afc7-b670106fe5ff%2FUntitled.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F1b9d8785-c37a-4a76-b47c-c79368d73993%2F5dde85fa-cc8a-4913-afc7-b670106fe5ff%2FUntitled.png" alt="Untitled" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Las estampillas de tiempo lamport proveen un ordenamiento consistente con causalidad

&lt;ul&gt;
&lt;li&gt;Si tiene dos timestamps, la que tiene el valor de contador más alto es el timestamp más reciente. Si ambas tienen el mismo valor en el contador, la que tiene el &lt;strong&gt;NodeId&lt;/strong&gt; mayor es la más reciente.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;IMPORTANTE.&lt;/strong&gt; Las garantía de ordenamiento no son suficientes para satisfacer todos los requerimientos de consistencia en un sistema distribuido, como asegurarse que solo existan &lt;em&gt;usernames ú*nicos en el sistema. Cuando dos usuarios tratan de crear el mismo *username,&lt;/em&gt; escoger la operación con menor timestamp solo funciona en retrospectiva. &lt;strong&gt;Un nodo no puede decidir inmediatamente si la petición de un username debe ser aceptada, sin antes saber si otro nodo está procesando la misma petición por otro usuario.&lt;/strong&gt; Verificar que ningun nodo esté procesando la misma operación no es eficiente. Por eso, *&lt;strong&gt;*el sistema también debe conocer cuando una operación finaliza para asegurarse que ningun otro nodo pueda realizar la misma operación. Esto se conoce como **broadcast de orden total&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Broadcast de orden total (&lt;em&gt;total order broadcast)&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Broadcast de Orden Total (&lt;em&gt;Total Order Broadcast)&lt;/em&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;def.&lt;/strong&gt; Protocolo de comunicación entre nodos de un sistema distribuido para intercambiar mensajes&lt;/li&gt;
&lt;li&gt;También se conoce como &lt;strong&gt;broadcast atómico&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;El protocolo dicta que estas propiedades &lt;strong&gt;siempre&lt;/strong&gt; se deben satisfacer para la comunicación entre partes del sistema

&lt;ul&gt;
&lt;li&gt;Entrega fiable &lt;em&gt;(reliable delivery&lt;/em&gt;) → No hay mensajes perdidos

&lt;ul&gt;
&lt;li&gt;Si un mensaje se entrega a un nodo, se le entrega a &lt;strong&gt;todos los nodos&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Entrega de orden total &lt;em&gt;(totally ordered delivery) →&lt;/em&gt; Los mensajes se entregan a cada nodo en el mismo orden&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Nota.&lt;/strong&gt; El broadcast de orden total es la forma más adecuada de implementar &lt;strong&gt;replicación&lt;/strong&gt; en una base de datos&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/skoya76/total-order-broadcast-5ccl"&gt;Total order broadcast&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F1b9d8785-c37a-4a76-b47c-c79368d73993%2F05cd9fba-8c56-4f17-a10a-379a1933c95e%2FUntitled.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F1b9d8785-c37a-4a76-b47c-c79368d73993%2F05cd9fba-8c56-4f17-a10a-379a1933c95e%2FUntitled.png" alt="Untitled" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Broadcast de orden total ≠ Linealizabilidad&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Broadcast atómico&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Linealizabilidad&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;¿Qué es?&lt;/td&gt;
&lt;td&gt;Protocolo de comunicación&lt;/td&gt;
&lt;td&gt;Modelo de consistencia&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enfoque&lt;/td&gt;
&lt;td&gt;La entrega y ordenamiento de mensajes&lt;/td&gt;
&lt;td&gt;Apariencia y orden de operaciones&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Objetivo&lt;/td&gt;
&lt;td&gt;Asegurarse que los mensajes se entreguen de cierta forma&lt;/td&gt;
&lt;td&gt;Asegurarse que el sistema entero se comporte como si solo existiera una copia de los datos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aplicaciones&lt;/td&gt;
&lt;td&gt;Mecanismo de bajo nivel para implementar modelos de consistencia como &lt;strong&gt;linealizabilidad&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Propiedad del sistema como tal&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Transacciones Distribuidas y Consenso
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Consenso&lt;/strong&gt; (definición informal) → Hacer que varios nodos estén de acuerdo en algo

&lt;ul&gt;
&lt;li&gt;No es algo fácil de implementar&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Situaciones donde los nodos de un sistema deben estar de acuerdo

&lt;ul&gt;
&lt;li&gt;Escoger un lider → Todos los nodos deben estar de acuerdo en quien es el lider&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;commit atómico&lt;/strong&gt; → Todos los nodos deben estar de acuerdo en el resultado de una transacción

&lt;ul&gt;
&lt;li&gt;Problema: Una transacción puede abortarse en un nodo pero ser exitosa en otro nodo&lt;/li&gt;
&lt;li&gt;Solución: Commit de dos fases &lt;strong&gt;&lt;em&gt;(two-phase commit)&lt;/em&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Commit de dos fases (&lt;em&gt;two-phase commit -&lt;/em&gt; 2PC*)*
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;def.&lt;/strong&gt; algoritmo para lograr transacciones atómicas que involucran multiples nodos

&lt;ul&gt;
&lt;li&gt;Es la forma para implementar &lt;strong&gt;&lt;em&gt;commits atómicos&lt;/em&gt;&lt;/strong&gt; en un sistema distribuido&lt;/li&gt;
&lt;li&gt;Sistema de un solo nodo → Un solo dispositivo controla el exito de un commit. El unico requisito es que la operación se efectue en el log en disco&lt;/li&gt;
&lt;li&gt;Sistema de multiples nodos → La operación puede abortarse en un nodo pero ser exitosa en otro nodo

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Un nodo solo puede hacer commit si está seguro que el resto de nodos también puedne hacer commit&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;Commit de dos fases → Implementación&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F1b9d8785-c37a-4a76-b47c-c79368d73993%2Fcc567979-1b5e-457a-b198-93ea73ba9d01%2FUntitled.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F1b9d8785-c37a-4a76-b47c-c79368d73993%2Fcc567979-1b5e-457a-b198-93ea73ba9d01%2FUntitled.png" alt="Untitled" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Coordinador → Componente adicional que se encarga de administrar las transacciones&lt;/li&gt;
&lt;li&gt;Pasos

&lt;ol&gt;
&lt;li&gt;App cliente realiza operación de escritura en varios nodos → Le avisa al coordinador&lt;/li&gt;
&lt;li&gt;Coordinador empieza la fase 1 → Enviar petición de &lt;strong&gt;&lt;em&gt;prepare&lt;/em&gt;&lt;/strong&gt; a los nodos

&lt;ol&gt;
&lt;li&gt;Petición de prepare: &lt;em&gt;“Eres capaz de hacer commit?”&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Coordinador recibe respuesta de los nodos&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Coordinador empieza la fase 2 → commit o rollback

&lt;ol&gt;
&lt;li&gt;Si todos los nodos respindieron &lt;strong&gt;SI&lt;/strong&gt; en la fase 1 → &lt;strong&gt;commit&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Si &lt;strong&gt;algun&lt;/strong&gt; nodo respondió &lt;strong&gt;NO&lt;/strong&gt; en la fase 1 → &lt;strong&gt;rollback&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nota.&lt;/strong&gt; Si un nodo retorna &lt;strong&gt;SI&lt;/strong&gt; en la petición de preparación, &lt;strong&gt;debe&lt;/strong&gt; hacer commit si el coordinador lo solicita en la segunda fase. Si por alguna razón el nodo se cae, el coordinador va a reintentar la operación hasta que se haga commit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2 promesas&lt;/strong&gt; aseguran la atomicidad del 2PC

&lt;ul&gt;
&lt;li&gt;Si un nodo promete hacer commit en la fase 1, debe si o si hacerlo si el coordinador lo solicita en la fase 2&lt;/li&gt;
&lt;li&gt;Una vez el coordinador toma una decision, es irrevocable&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Transacciones Distirbuidas en la Práctica
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Dos notas importantes sobre las transacciones distribuidas

&lt;ol&gt;
&lt;li&gt;Ofrecen la garantía de seguridad con el commit de dos fases&lt;/li&gt;
&lt;li&gt;Causan problemas operacionales e impactan el desempeño

&lt;ol&gt;
&lt;li&gt;Ej. Las transacciones distribuidas en MySQL son 10 veces más lentas que las transacciones en un solo nodo&lt;/li&gt;
&lt;li&gt;Muchos servicios en la nube deciden no implementar transacciones distribuidas debido a sus implicaciones en desempeño&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;2 tipos de transacciones dsitribudas

&lt;ul&gt;
&lt;li&gt;Internas → Mismo sistema de almacenamiento

&lt;ul&gt;
&lt;li&gt;DBs que usan replicación y particionamiento en su configuración estandar soportan transacciones internas entre los nodos de la BD&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Heterogeneas → Multiples sistemas de almacenamiento

&lt;ul&gt;
&lt;li&gt;Dos BDs de vendors distintos (MySQL replication)&lt;/li&gt;
&lt;li&gt;Brokers de mensajería (Kafka)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Procesameinto de mensajers -&lt;/strong&gt; Garantía de &lt;em&gt;“Exactly once”&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;Las transacciones distribuidas heterogenas permiten que sistemas diversos se integren de formas muy poderosas

&lt;ul&gt;
&lt;li&gt;Ejemplo: Un mensaje de un broker (Kafka, pubsub) pueder ser reconocido como procesado &lt;strong&gt;si y solo si&lt;/strong&gt; la transacción en la BD transaccional fue &lt;strong&gt;commited&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Protocolo atómico que soporta las transacciones distribuidas en sistemas heterogeneos → &lt;strong&gt;Transacciones XA&lt;/strong&gt;
&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Transacciones XA
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;def.&lt;/strong&gt; Open XA Transacciones → &lt;em&gt;eXtended Architecture Transactions&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;¿Qué es? Estandar para implementar 2PC en tecnologías heterogeneas, soportado por muchas BDs relacionales y brokers de mensajería&lt;/li&gt;
&lt;li&gt;Basicamente es un API para interactuar con un coordinador de transacciones, permitiendo que multiples recursos transaccionales interactuen entre si para participar en una transacción global intersistemas&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://dev.mysql.com/doc/refman/8.4/en/xa.html" rel="noopener noreferrer"&gt;MySQL :: MySQL 8.4 Reference Manual :: 15.3.8 XA Transactions&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Coordinador → Libreria que se incluye en algun proceso como una aplicación

&lt;ul&gt;
&lt;li&gt;Hace seguimiento de los participantes en las transacciones&lt;/li&gt;
&lt;li&gt;Recolecta las respuestas de los participantes despues del &lt;strong&gt;&lt;em&gt;prepare&lt;/em&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Utiliza un log en su disco local para llevar registro de los &lt;strong&gt;commits y rollbacks&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Las transacciones XA resuelven el problema de mantener varios sistemas de datos consistentes entre si, pero también tienen limitantes

&lt;ul&gt;
&lt;li&gt;Los coordinadores no replicados son puntos únicos de fallo que pueden causar bloqueos a nivel de sistema&lt;/li&gt;
&lt;li&gt;Muchos coordinadores no soportan alta disponibilidad&lt;/li&gt;
&lt;li&gt;aplicaciones sin estado pueden escalar facilmente, pero añadir un coordinador las hace &lt;strong&gt;&lt;em&gt;stateful&lt;/em&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Las transacciones XA no puden detectar &lt;strong&gt;&lt;em&gt;deadlocks&lt;/em&gt;&lt;/strong&gt; entre varios sistemas&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Consenso Tolerante a Fallas
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Consenso →&lt;/strong&gt; Hacer que multiples nodos estén de acuerdo en algo

&lt;ul&gt;
&lt;li&gt;Si muchas personas tratan de reservar el último puesto en un avión, el algoritmo de consenso debe determinar cuál de estas &lt;strong&gt;operaciones mutualmente incompatibles&lt;/strong&gt; es la ganadora.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;em&gt;“The Consensus Problem”&lt;/em&gt; → Uno o más nodos puede proponer valores, y el algoritmo de consenso decide alguno de esos valores.&lt;/li&gt;

&lt;li&gt;Un algoritmo de consenso debe satisfacer las siguiente propiedades

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Acuerdo uniforme&lt;/strong&gt; (&lt;em&gt;Uniform agreement&lt;/em&gt; ) → Ningún nodo decide de manera diferente al resto de los nodos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integridad&lt;/strong&gt; → Ningún nodo decide dos veces&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validez&lt;/strong&gt; → Si un nodo decide el valor &lt;strong&gt;V,&lt;/strong&gt; entonces &lt;strong&gt;V&lt;/strong&gt; fue propuesto por algún otro nodo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Terminación&lt;/strong&gt; → Cada nodo que no se bloquea, eventualmente decide algún valor.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Broadcast de orden total y consenso:&lt;/strong&gt; El broadcast de orden total es lo mismo que rondas repetidas de consenso

&lt;ul&gt;
&lt;li&gt;Debido a la propiedad de acuerdo del consenso, todos los nodos deciden entregar los mismos mensajes en el mismo orden&lt;/li&gt;
&lt;li&gt;Debido a la propiedad de integridad, los mensajes no se duplican&lt;/li&gt;
&lt;li&gt;Debido a la propiedad de validez, los mensajes no se corrompen ni se crean de la nada&lt;/li&gt;
&lt;li&gt;Debido a la propiedad de terminación, los mensajes no se pierden&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Algunos algoritmos de consenso

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Viewstamped Replication →&lt;/em&gt; &lt;a href="https://medium.com/@polyglot_factotum/understand-viewstamped-replication-with-rust-automerge-and-tla-7a94e9e4d553" rel="noopener noreferrer"&gt;https://medium.com/@polyglot_factotum/understand-viewstamped-replication-with-rust-automerge-and-tla-7a94e9e4d553&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Raft → &lt;a href="https://www.geeksforgeeks.org/raft-consensus-algorithm/" rel="noopener noreferrer"&gt;https://www.geeksforgeeks.org/raft-consensus-algorithm/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Zab → &lt;a href="https://medium.com/@adityashete009/the-zab-algorithm-502781c54498" rel="noopener noreferrer"&gt;https://medium.com/@adityashete009/the-zab-algorithm-502781c54498&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Apache Zookeeper
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://zookeeper.apache.org/" rel="noopener noreferrer"&gt;https://zookeeper.apache.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;def.&lt;/strong&gt; Herramienta de codigo abierto que provee

&lt;ul&gt;
&lt;li&gt;algoritmo de Consenso&lt;/li&gt;
&lt;li&gt;Detección de fallos&lt;/li&gt;
&lt;li&gt;Servicio de membresía&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Herramientas como ZooKeeper&lt;/strong&gt;: Proporcionan consenso y detección de fallos, evitando la necesidad de desarrollar algoritmos propios.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Para&lt;/strong&gt; implementar sistemas dsitribuidos&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Muchos sistemas comunes utilizan Zookeeper por debajo

&lt;ul&gt;
&lt;li&gt;Apache Kafka&lt;/li&gt;
&lt;li&gt;HBase&lt;/li&gt;
&lt;li&gt;Hadoop Yarn&lt;/li&gt;
&lt;li&gt;Redis&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Resumen&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Linealizabilidad →&lt;/strong&gt; modelo de consistencia con el objetivo de dar la ilusión de que los datos replicados se comporten como si solo existiera una copia de los datos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Causalidad&lt;/strong&gt;: Ordena eventos según causa y efecto, permite concurrencia y reduce la sobrecarga de coordinación.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consenso →&lt;/strong&gt; Hacer que todos los nodos de un sistema estén de acuerdo en algo

&lt;ul&gt;
&lt;li&gt;Muchos en la práctica de los sistemas distribuidos se pueden reducir al problema de lograr consenso&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commit atómico&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Una BD debe decidir si le hace &lt;strong&gt;commit&lt;/strong&gt; o &lt;strong&gt;abort&lt;/strong&gt; a una transacción distribuida&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Broadcast de orden total&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Un sistema debe deciri en que orden entregar los mensajes a los nodos&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Restricción de univocidad&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Cuando varias transacciones concurrentes intentan crear records conflictivos con la misma llave, se debe decidir cuales operaciones permitir y cuales rechazar&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Registros linealizables&lt;/strong&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Base de datos con un solo líder&lt;/strong&gt;: Proporciona linealizabilidad pero falla si el líder es inaccesible.

&lt;ul&gt;
&lt;li&gt;Opciones para manejar fallos:

&lt;ul&gt;
&lt;li&gt;Esperar la recuperación del líder&lt;/li&gt;
&lt;li&gt;Conmutación manual por fallos&lt;/li&gt;
&lt;li&gt;Algoritmo de consenso automático&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

</description>
    </item>
  </channel>
</rss>
