orm - example - nosql tutorial
La vida sin UNIONES... comprensión y prácticas comunes (7)
Creo que en estas situaciones vas a estar completamente solo y vas a tener que tirar todo tú mismo. No he estado allí, pero lo he considerado para algunos de nuestros proyectos. Puede hacerse bastante grande con DB relacionales (como lo demuestra SO), así que continuaré disfrutando la bondad relacional por el momento.
Muchos de los "BAW" (sitios web grandes) están usando técnicas de almacenamiento y recuperación de datos que dependen de tablas enormes con índices, y usan consultas que no pueden / no pueden usar JOIN en sus consultas (BigTable, HQL, etc.) para tratar con la escalabilidad y la fragmentación de bases de datos. ¿Cómo funciona eso cuando tienes montones y montones de datos que están muy relacionados?
Solo puedo especular que gran parte de esta unión tiene que hacerse en el lado de la aplicación de las cosas, ¿pero eso no empieza a ser costoso? ¿Qué pasa si tiene que hacer varias consultas a varias tablas diferentes para obtener información para compilar? ¿No está llegando a la base de datos muchas veces empezando a ser más costoso que el uso de combinaciones? Supongo que depende de la cantidad de datos que tienes?
Y para los ORM comúnmente disponibles, ¿cómo tienden a lidiar con la imposibilidad de usar uniones? ¿Hay soporte para esto en los ORM que están en uso pesado hoy en día? ¿O la mayoría de los proyectos que tienen que acercarse a este nivel de datos tienden a rodar los suyos de todos modos?
Entonces esto no es aplicable a ningún proyecto actual que estoy haciendo, pero es algo que ha estado en mi cabeza desde hace varios meses y que solo puedo especular sobre cuáles son las "mejores prácticas". Nunca tuve la necesidad de abordar esto en ninguno de mis proyectos porque nunca llegaron a una escala en la que se requiere. Espero que esta pregunta también ayude a otras personas ...
Como alguien dijo a continuación, los ORM "no funcionan" sin combinaciones. ¿Hay otras capas de acceso a datos que ya están disponibles para los desarrolladores que trabajan con datos en este nivel?
EDITAR: Para alguna aclaración, Vinko Vrsalovic dijo:
"Creo que Snicker quiere hablar sobre NO-SQL, donde los datos transaccionales se desnormalizan y se usan en los esquemas de Hadoop, BigTable o Cassandra".
Esto es de hecho de lo que estoy hablando.
Puntos de bonificación para aquellos que atrapan la referencia xkcd.
Cuando desnormaliza sus datos de esta manera, lo hace para evitar el costo de unir elementos dispares; usted acepta que algunos datos pueden estar duplicados y que ciertas formas de combinarlo pueden ser difíciles, por el beneficio de rendimiento de usar consultas simples.
Si tiene que hacer una gran cantidad de reuniones en el nivel de aplicación, implica que no lo ha denormalizado lo suficiente.
Idealmente, podrá hacer una consulta para cualquier conjunto de datos que desee. En la práctica, no debería tener que usar más de dos o tres consultas para ningún aspecto de su aplicación, y cualquier unión a nivel de aplicación será una recuperación más trivial de elementos de los resultados separados para su inserción en la vista.
Este tipo de cosas solo son realmente necesarias para conjuntos de datos verdaderamente masivos, y hay todo tipo de compensaciones involucradas. Para dar solo un ejemplo: BigTable no puede hacer consultas agregadas, como darle un conteo. Se puede usar para proporcionarle una cifra que es más o menos precisa, en el sentido de que si tiene, por ejemplo, 12.149.173 registros de los cuales se agregaron 23.721 en la última hora, realmente no importa si lo mejor que puede descubrir es que tienes "alrededor de 12,100,000 registros". Si su aplicación depende de conocer la cifra exacta en un momento dado, entonces no debe utilizar BigTable para ello, es la actitud general.
En general, el almacenamiento de datos se basa en el uso de combinaciones y datos divididos en dimensiones y tablas de hechos (con los denominados "esquemas en estrella", etc.)
Las uniones a menudo se calcularán previamente y se almacenarán como tablas des-normalizadas.
No conozco ninguna herramienta ORM que funcione con sistemas de bases de datos que no permitan combinaciones, ya que generalmente no se ven como bases de datos relacionales tradicionales.
Estás comenzando desde una suposición errónea.
El almacenamiento de datos no normaliza los datos de la misma manera que una aplicación de transacción se normaliza. No hay "muchas" combinaciones. Hay relativamente pocos.
En particular, las infracciones segunda y tercera del Formulario Normal no son un "problema", ya que los almacenes de datos rara vez se actualizan. Y cuando se actualizan, por lo general, solo se modifica el indicador de estado para convertir las filas de una dimensión en "actual" frente a "no actual".
Ya que no tiene que preocuparse por las actualizaciones, no descompone las cosas en el nivel 2NF donde una actualización no puede conducir a relaciones anómalas. Sin actualizaciones significa que no hay anomalías; y sin descomposición y sin uniones. Puedes preunir todo.
En general, los datos DW se descomponen según un esquema en estrella. Esto lo guía a descomponer los datos en las tablas numéricas de "hechos" que contienen las medidas (números con unidades) y referencias de claves externas a la dimensión.
Una dimensión (o "entidad comercial") se considera mejor como una cosa del mundo real con atributos. A menudo, esto incluye cosas como geografía, tiempo, producto, cliente, etc. Estas cosas a menudo tienen jerarquías complejas. Las jerarquías suelen ser arbitrarias, definidas por diversas necesidades de informes empresariales, y no se modelan como tablas separadas, sino simplemente columnas en la dimensión utilizada para la agregación.
Para abordar algunas de sus preguntas.
"esta unión tiene que hacerse en el lado de la aplicación de las cosas". Mas o menos. Los datos están "preintegrados" antes de ser cargados. Los datos de dimensión a menudo son una combinación de datos fuente relevantes sobre esa dimensión. Se une y se carga como una estructura relativamente plana.
No está actualizado. En lugar de actualizaciones, se insertan registros históricos adicionales.
"¿Pero eso no comienza a ser caro?". Mas o menos. Se necesita cierto cuidado para cargar los datos. Sin embargo, no hay muchas uniones de informes / análisis. Los datos están pre-unidos.
Los problemas de ORM son en gran parte discutibles ya que los datos están pre-unidos. Su ORM asigna el hecho o la dimensión según corresponda. Excepto en casos especiales, las dimensiones tienden a ser pequeñas y totalmente en memoria. La excepción es cuando estás en Finanzas (Banca o Seguros) o Servicios Públicos y tienes bases de datos masivas de clientes. Esta dimensión del cliente rara vez cabe en la memoria.
La forma en que lo veo, una base de datos relacional es una herramienta de propósito general para cubrir tus apuestas. Las computadoras modernas son lo suficientemente rápidas, y los RDBMS están lo suficientemente optimizados como para que pueda crecer a un tamaño bastante respetable en una sola caja. Al elegir un RDBMS, se está otorgando un acceso muy flexible a sus datos, y la capacidad de tener poderosas restricciones de corrección que hacen que sea mucho más fácil codificar en contra de los datos. Sin embargo, el RDBMS no va a representar una buena optimización para ningún problema en particular, solo le da la flexibilidad de cambiar los problemas fácilmente.
Si comienza a crecer rápidamente y se da cuenta de que tendrá que escalar más allá del tamaño de un solo servidor de bases de datos, de repente tendrá que tomar decisiones mucho más difíciles. Deberá comenzar a identificar los cuellos de botella y eliminarlos. El RDBMS va a ser un desagradable nudo gruñón de codependencia que tendrás que separar. Mientras más interconectados estén tus datos, más trabajo tendrás que hacer, pero quizás no tendrás que desenmarañarlo por completo. Si lees mucho, tal vez puedas salir adelante con una simple replicación. Si está saturando su mercado y el crecimiento se está nivelando, tal vez pueda desnormalizar y fragmentar parcialmente una cantidad fija de servidores de bases de datos. Tal vez solo tiene un puñado de tablas de problemas que se pueden mover a un almacén de datos más escalable. Tal vez su perfil de uso sea muy amigable con el caché y solo puede migrar la carga a un clúster de memcached gigante.
Donde tiendas escalables de valores clave como BigTable entran cuando ninguno de los anteriores puede funcionar, y usted tiene tantos datos de un solo tipo que, incluso cuando se desnormaliza, una sola tabla es demasiado para un servidor. En este punto, debe poder particionarlo arbitrariamente y aún tener una API limpia para acceder a él. Naturalmente, cuando los datos se distribuyen en tantas máquinas no se pueden tener algoritmos que requieran que estas máquinas se comuniquen entre sí, lo que requerirían muchos de los algoritmos relacionales estándar. Como sugiere, estos algoritmos de consulta distribuidos tienen el potencial de requerir más potencia de procesamiento total que el equivalente JOIN en una base de datos relacional correctamente indexada, pero debido a que están paralelizados, el rendimiento en tiempo real es órdenes de magnitud mejor que cualquier máquina individual (asumiendo una máquina que podría contener todo el índice incluso existe).
Ahora, una vez que puede escalar su enorme conjunto de datos horizontalmente (simplemente conectando más servidores), la parte más difícil de la escalabilidad ya está hecha. Bueno, no debería decir hecho , porque las operaciones y el desarrollo constantes a esta escala son mucho más difíciles que la aplicación de servidor único, pero el punto es que los servidores de aplicaciones son típicamente triviales para escalar a través de una arquitectura sin contenido mientras puedan obtenerlos. los datos que necesitan de manera oportuna.
Para responder a su pregunta acerca de cómo los ORM comúnmente utilizados manejan la incapacidad de usar JOINs, la respuesta corta es que no lo hacen . ORM significa Object Relational Mapping, y la mayor parte del trabajo de un ORM es simplemente traducir el poderoso paradigma relacional de lógica de predicados estructuras de datos orientadas a objetos simples. La mayor parte del valor de lo que le dan simplemente no será posible desde una tienda de valores-clave. En la práctica, probablemente necesitará construir y mantener su propia capa de acceso a datos que se adapte a sus necesidades particulares, porque los perfiles de datos a estas escalas van a variar drásticamente y creo que hay demasiadas ventajas y desventajas para que emerja una herramienta de uso general. y se vuelven dominantes de la misma forma que los RDBMS. En resumen, siempre tendrá que hacer más trabajo a esta escala.
Dicho esto, definitivamente será interesante ver qué clase de funcionalidad agregada relacional u otra se puede construir sobre las primitivas del almacén de clave-valor. Realmente no tengo suficiente experiencia aquí para comentar específicamente, pero hay un montón de conocimiento en informática empresarial sobre esto desde hace muchos años (por ejemplo, Oracle), una gran cantidad de conocimientos teóricos no explotados en el mundo académico, una gran cantidad de conocimientos prácticos en Google, Amazon, Facebook y otros, pero el conocimiento que se ha filtrado a la comunidad de desarrollo en general todavía es bastante limitado.
Sin embargo, ahora que muchas aplicaciones se están moviendo a la Web y cada vez más de la población mundial está en línea, inevitablemente habrá cada vez más aplicaciones que escalar y las mejores prácticas comenzarán a cristalizar. La brecha de conocimiento se reducirá desde ambos lados por los servicios en la nube como AppEngine y EC2, así como las bases de datos de código abierto como Cassandra. En cierto sentido, esto va de la mano con la computación paralela y asíncrona que también está en pañales. Definitivamente un momento fascinante para ser un programador.
Las aplicaciones como Facebook tienen muy pocos cambios en los datos, la mayoría de las veces los usuarios publican nuevos artículos. Por lo tanto, el hecho de que los registros de multiplicación necesitan actualización cuando se cambia un elemento es un problema menor.
Esto permite que los datos no se normalicen sin solucionar los problemas comunes de las actualizaciones.
Aplicaciones como Amazon pueden permitirse cargar todos los datos de un solo usuario en la memoria RAM (¿qué tan grande es un carrito de compras después de todo?), Luego actualizar los datos en la memoria RAM y escribirlos como un único elemento de datos.
Una vez más eliminando la necesidad de tener la mayoría de los datos normalizados.
Está comercializando escalas para facilitar el desarrollo de aplicaciones, por lo que si no necesita escalar a grandes alturas, es posible que desee mantener la facilidad de desarrollo de aplicaciones que ofrecen RDBMS.
Un JOIN
es un término relacional puro y no todas las bases de datos son relacionales.
Otros modelos de bases de datos tienen otras formas de construir relaciones.
Las bases de datos de red utilizan las infinitas cadenas de find a key - fetch the reference - find a key
que debe programarse con un lenguaje de programación común.
El código se puede ejecutar en el lado de la aplicación o en el del servidor, pero no es SQL
y ni siquiera está basado en conjunto.
Si se diseña correctamente, una base de datos de red puede ser mucho más rápida que una relacional.
Por ejemplo, una base de datos de red puede almacenar una referencia a otra entidad como un puntero directo a un desplazamiento en un archivo o incluso un bloque en un disco donde se almacena la información sobre esta entidad.
Esto hace que recorrer las redes sea más rápido, si escribiste un código eficiente para hacerlo.
Una base de datos relacional solo puede almacenar referencias como pares de valores básicos como enteros (o triples o tuplas de orden superior).
Para encontrar esos valores en la base de datos relacional, el motor debe hacer lo siguiente:
- Descubra dónde reside la tupla que contiene el primer valor
- Encuentra el segundo valor
- Encuentra la dirección de la raíz en un
B-Tree
contiene los datos a los que se refiere el segundo número - Atraviesa este árbol
- Encuentre el puntero a la tabla real (que puede almacenarse como un
B-Tree
, en cuyo caso el puntero es el valor de laPRIMARY KEY
de la fila que buscamos) - Encuentre la fila de la tabla por el puntero o recorra la tabla
- Finalmente, consigue el resultado.
Y puedes controlar esto solo hasta cierto punto. Después de, solo emite la consulta SQL
y espera.
Modelo relacional hecho para simplificar la vida del desarrollador, no para lograr la súper velocidad siempre y pase lo que pase.
Esto es lo mismo que el ensamblaje frente a los lenguajes de alto nivel, siendo el modelo relacional un lenguaje de alto nivel.
Es posible que desee leer el artículo en mi blog
, en el que trato de explicar las diferencias entre varios modelos de bases de datos de uso común.