DEV Community

Pablo Arango Ramirez
Pablo Arango Ramirez

Posted on

Capítulo 2 - Modelos de Datos y Lenguajes de Consulta

Crédito de la imagen: Martin Kleppmann, *Designing Data-Intensive Applications*, O'Reilly Media, 2017.

Crédito de la imagen: Martin Kleppmann, *Designing Data-Intensive Applications*, O'Reilly Media, 2017.

Tipos de modelos de datos

  • Jerarquico (El modelo inicial) → no se adaptaba bien a las relaciones many-to-many
  • Relacional (SQL) → Solución al modelo jeraquico. Poco flexible
  • Documental → Datos que vienen en documentos autocontenidos (JSON). Poco soporte de relación entre documentos
  • Modelo de grafos → Nodos y ejes

El Modelo Relacional

  • Propuesto por Edgar Codd en 1970
  • Los datos se organizan en relaciones (tablas) donde cada relación es una colección no ordenada de tuplas (filas)
  • Casos de uso originales
    • Procesamiento transaccional → operaciones de movimiento de dinero en un banco, reservas de aerolineas
    • Procesamiento analitico en lotes → reportes, payroll, analítica
  • Sigue el paradigma de schema-on-write (Esquema al escribir)
    • 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

NoSQL

  • Surgió con un hashtah de Twitter en el 2009
  • def. Not ONLY SQL
  • Sigue el paradigma de schema-on-read (Esquema al leer)
  • Surgió debido a estos factores:
    • Necesidad de mayor escalabilidad que las BDs relacionales
    • Preferencia por software open-source gratis envés de productos de BDs relacionales empresariales
    • Operaciones de consultas especializadas que no están bien soportadas por el modelo relacional
    • Frustración con las restricciones de los esquemas relacionales
    • Necesidad de un modelo más dinamico y expresivo

Problema: Objetos vs Relaciones → Desajuste por Impedancia

  • Impedance Mismatch: Problema de incongruencia entre el modelo relacional y los objetos en el codigo de la aplicacion. Es el conjunto de dificultades técnicas y conceptuales que surgen cuando se almacenan objetos de programación en bases de datos con modelos relacionales
    • Si los objetos en la app se almacenan en una BD con modelo relacional (SQL), se necesita una capa de traducción entre el codigo de la app y la modelo de la BD
  • Solucion → Mapeo Objeto-Relacional (ORM: Object-relational mapping)
    • Frameworks de ORM
    • Reducen el codigo boilerplate requerido para esa capa de transición
  • Ejemplos: Apache OpenJPA, SQLAlchemy, TypeORM

Expresiones en distintos Modelos

  • Perfil de Linkedin
    • Modelo Relacional

Image description
Martin Kleppmann, Designing Data-Intensive Applications, O'Reilly Media, 2017.

- Modelo Documental NoSQL (JSON)
Enter fullscreen mode Exit fullscreen mode
    ```json
    {
        "user_id": 251,
        "first_name": "pedro",
        "positions": [
            {"job_title": "founder", "organization": "planny"},
            {"job_title": "ceo", "organization": "nombre undefined"}
        ],
    ...
    }
    ```
Enter fullscreen mode Exit fullscreen mode
    - Con el modelo JSON, la estructura de árbol implicita en el perfil de Linkedin, se vuelve explicita en el modelo de datos
Enter fullscreen mode Exit fullscreen mode

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

  • En algun punto va a necesitar many-to-many y por ende utilizar joins
  • Ejemplo Linkedin → Representar la organización donde trabaja la persona como una entidad.

    Untitled

Debate: ¿Cómo representar de mejor forma las relaciones de las entidades en una base de datos?

  • Discusión más vieja que los esquemas NoSQL. Viene desde los primeros sistemas de bases de datos computacionales
  • Caso: La IMS de IBM utilizaba el modelo jerarquico. Este modelo no soportaba JOINs. En los 60s, los desarrolladores tenian que decidir entre duplicar datos (Normalizar) o resolver manualmente las referencias de un record a otro. Este es el mismo problema que tienen los desarrolladores hoy en dia con las BDs documentales
  • La solución a esto en su entonces fue el modelo relacional de SQL
    • El modelo relacional permitió poner todos los datos al descubierto con una lista de tuplas (tabla). El optimizador de consultas en una BD relacional automaticamente decide que aprtes de la consulta ejecutar y en que orden hacerlo. Estas decisiones ya no las toma un desarrollador
      • “Solo se construye un optimizador de consultas una vez. Todas las apps que utilicen la BD se benefician de el”
    • Las BDs documentales de devolvieron al modelo jerarquico → almacena records embebidos (many-to-one) en el mismo record, no en otra tabla
  • Cuando se trata de relaciones many-to-many, el modelo documental y el modelo relacional no son muy distintos. En ambos, el item relacionado se referencia con un identificador unico que se utiliza como llave foranea en el otro item en el modelo relacional, pero como una referenia a un documento en el modelo documental

Modelo Relacional vs Modelo Documental

  • Documental
    • Flexibilidad de esquema
    • Mejor localidad de datos → Capacidad para mover computo (objetos) a datos almacenados
    • Mejor desempeño
    • Poco soporte de JOINS
  • Relacional
    • Buen soporte de joins
    • Buen soporte de relaciones many-to-one y many-to-many
    • Poca flexibilidad de esquema
  • Convergencia entre el modelo relacional y documental?
    • Postgres ya soporta documentos JSON como tipo de datos desde la versión 9
    • Hay drivers de Mongo que automaticamente resuelven las referencias de documento
      • Resuelve el problema desde el lado del cliente
    • 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 si. Si una BD soporta document-like, y tambien soporta consultas relacionales, las aplicaciones pueden utilizar la combinación de ambas funcionalidades que mejor se ajuste a sus necesidades.
  • Por ahora
    • Use documentales cuando
      • Tiene datos con relaciones one-to-many
      • Necesita que un árbol de datos embebidos se cargue en la aplicación desde el inicio
      • Estructura de datos tipo documento
    • Use relacionales cuando
      • Necesita muy buen soporte de joins
      • Tiene relaciones many-to-many

Lenguajes de Consulta

  • Dos tipos de lenguajes: Declarativo e Imperativo

    • Declarativo → SQL

      • Le digo a la máquina que datos y transformaciones quiero realizar frente a los datos, pero no le digo como realizar la consulta

        SELECT * FROM animals WHERE family = "sharks"
        
    • Imperativo → Lenguajes de programación (Java, python, JS)

      • Le digo a la máquina, como ejecutar la consulta

        function getSharks(){
            var sharks = [];
            for (var i=0; i<animals.length; i++){
                if(animals[i].family === "sharks"){
                    sharks.push(animals[i]);
                }
            }
        return sharks;
        }
        
    • La misma consulta se puede expresar de forma generica con algebra relacional

      Untitled

    SQL Provee mejor soporte para algunos tipos de consultas

    • Consultas tipo Map Reduce (Documentales) → Je: Obtener número de tiburones por mes

      • SQL

        SELECT date_trunc('month', observation_timestamp) AS observation_month, 1
               sum(num_animals) AS total_animals
        FROM observations
        WHERE family = 'Sharks'
        GROUP BY observation_month;
        
      • Documental (Mongo)

        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
            }
        );
        

    Modelo de Grafos

    • Base de datos que almacena los datos como relaciones entre nodos conectados por ejes

      Untitled

    • Ejemplo: Representar el matrimonio de dos personas

      Untitled

    • Estructura→ ejemplo Neo4J

      • Cada vertice (Nodo) consiste de
        • ID
        • Ejes hacia afuera
        • Ejes hacia adentro
        • prpiedades llave-valor
      • Cada eje consiste de
        • Id
        • Vertice origen
        • Vertice destino
        • etiqueta
        • Propiedades llave - valor
    • Los grafos son muy buenos para la evolucionabilidad del sistema. Un grafo se puede extender facilmente para acomodar cambios en las estrucutras de datos de la app.

    • Ejemplo de lenguaje para BDs de grafos → Cypher (Lenguaje de consultas utilizado en Neo4J)

      • Ej: Insertar el hecho que Idaho queda en USA y que USA queda en America del norte. Insertar que Lucy nació en Idaho
      CREATE
      (NAmerica:Location {name: 'north america', type: 'continent'}),
      (USA:Location {name:'united staes', type: 'country'}),
      (Idaho:Location {name: 'idaho', type 'state'}),
      (Lucy: Person {name:'Lucy'}),
      (Idaho) -[:WITHIN] -> (USA) -[:WITHIN] -> (NAmerica)
      (Lucy) -[:BORN_IN] -> (Idaho)
      
      • Este modelo le permite soportar consultas muy compleas

        • Ejemplo: Encuentre los nombres de las personas que emigraron de USA a Europa
        MATCH
          (person) -[:BORN_IN]->  () -[:WITHIN*0..]-> (us:Location {name:'United States'}),
          (person) -[:LIVES_IN]-> () -[:WITHIN*0..]-> (eu:Location {name:'Europe'})
        RETURN person.name
        
        //[:WITHIN*0..] -> follow a within edge, zero or more times
        
        • Encuentra todos los vertices (personas) que
          • Tengan un born_in eje a un vertice. Desde ese vertice siga una cadena ejes WITHINs hasta que llegue a una ubicación que sea USA
          • Ese mismo vertice (persona) tenga un eje lives_in que lleve a un vertices que pertenezca a Europa
        • Si fuera a hacer la misma consulta en SQL, sería algo asi

          -- in_usa is the set of vertex IDs of all locations within the United States
            in_usa(vertex_id) AS (
                SELECT vertex_id FROM vertices WHERE properties->>'name' = 'United States' 1
              UNION
                SELECT edges.tail_vertex FROM edges 2
                  JOIN in_usa ON edges.head_vertex = in_usa.vertex_id
                  WHERE edges.label = 'within'
            ),
          
            -- in_europe is the set of vertex IDs of all locations within Europe
            in_europe(vertex_id) AS (
                SELECT vertex_id FROM vertices WHERE properties->>'name' = 'Europe' 3
              UNION
                SELECT edges.tail_vertex FROM edges
                  JOIN in_europe ON edges.head_vertex = in_europe.vertex_id
                  WHERE edges.label = 'within'
            ),
          
            -- born_in_usa is the set of vertex IDs of all people born in the US
            born_in_usa(vertex_id) AS ( 4
              SELECT edges.tail_vertex FROM edges
                JOIN in_usa ON edges.head_vertex = in_usa.vertex_id
                WHERE edges.label = 'born_in'
            ),
          
            -- lives_in_europe is the set of vertex IDs of all people living in Europe
            lives_in_europe(vertex_id) AS ( 5
              SELECT edges.tail_vertex FROM edges
                JOIN in_europe ON edges.head_vertex = in_europe.vertex_id
                WHERE edges.label = 'lives_in'
            )
          
          SELECT vertices.properties->>'name'
          FROM vertices
          -- join to find those people who were both born in the US *and* live in Europe
          JOIN born_in_usa     ON vertices.vertex_id = born_in_usa.vertex_id 6
          JOIN lives_in_europe ON vertices.vertex_id = lives_in_europe.vertex_id;
          

Triple store & SPARQL → Almacenar toda la información en forma de sentencias de tres partes

  1. Sujeto
  2. Predicato
  3. Objeto
  4. ejemplo: Juan Gustan bananos
  5. Modelo “Lucy vive en Londres”

    _:lucy     a       :Person.
    _:lucy     :name   "Lucy".
    _:lucy     :bornIn _:idaho.
    _:idaho    a       :Location.
    _:idaho    :name   "Idaho".
    _:idaho    :type   "state".
    _:idaho    :within _:usa.
    _:usa      a       :Location.
    _:usa      :name   "United States".
    _:usa      :type   "country".
    _:usa      :within _:namerica.
    _:namerica a       :Location.
    _:namerica :name   "North America".
    _:namerica :type   "continent".
    
  • Nota → La web3 (web semantica) se basa en ese modelo

Top comments (0)