Uno de los elementos en Joshua Bloch's Effective Java es la noción de que las clases deberían permitir la mutación de las instancias lo menos posible, y de preferencia ninguna.
A menudo, los datos de un objeto se conservan en una base de datos de alguna forma. Esto me ha llevado a pensar en la idea de la inmutabilidad dentro de una base de datos, especialmente para aquellas tablas que representan una sola entidad dentro de un sistema más grande.
Algo con lo que he estado experimentando recientemente es la idea de intentar minimizar las actualizaciones que hago en las filas de la tabla que representan estos objetos, y tratar de realizar inserciones tanto como pueda.
Un ejemplo concreto de algo con lo que estaba experimentando recientemente. Si sé que podría agregar un registro con datos adicionales más adelante, crearé otra tabla para representar eso, algo así como las siguientes dos definiciones de tabla:
create table myObj (id integer, ...other_data... not null);
create table myObjSuppliment (id integer, myObjId integer, ...more_data... not null);
Es de esperar que sea obvio que estos nombres no son textuales, sino solo para demostrar la idea.
¿Es este un enfoque razonable para el modelado de persistencia de datos? ¿Vale la pena tratar de limitar las actualizaciones realizadas en una tabla, especialmente para rellenar valores nulos para datos que podrían no existir cuando se creó originalmente el registro? ¿Hay momentos en que un enfoque como este puede causar dolor severo más adelante?
fuente
UPDATE
). Como los registros médicos del doctor.Respuestas:
El objetivo principal de la inmutabilidad es garantizar que no haya un instante en el tiempo cuando los datos en la memoria estén en un estado no válido. (El otro se debe a que las anotaciones matemáticas son en su mayoría estáticas, por lo que las cosas inmutables son más fáciles de conceptualizar y modelar matemáticamente). En la memoria, si otro hilo intenta leer o escribir datos mientras se está trabajando, podría terminar corrompiéndose, o podría estar en un estado corrupto. Si tiene varias operaciones de asignación a los campos de un objeto, en una aplicación multiproceso, otro subproceso podría intentar trabajar con él en algún momento intermedio, lo que podría ser malo.
La inmutabilidad soluciona esto al escribir primero todos los cambios en un nuevo lugar en la memoria y luego hacer la asignación final como un paso de reescritura del puntero al objeto para señalar el nuevo objeto, que en todas las CPU es atómico operación.
Las bases de datos hacen lo mismo con las transacciones atómicas : cuando inicia una transacción, escribe todas las actualizaciones nuevas en un nuevo lugar en el disco. Cuando finaliza la transacción, cambia el puntero en el disco a donde están las nuevas actualizaciones, lo que hace en un breve instante durante el cual otros procesos no pueden tocarlo.
Esto también es exactamente lo mismo que su idea de crear nuevas tablas, excepto que es más automática y más flexible.
Entonces, para responder a su pregunta, sí, la inmutabilidad es buena en las bases de datos, pero no, no necesita hacer tablas separadas solo para ese propósito; puede usar cualquier comando de transacción atómica disponible para su sistema de base de datos.
fuente
Depende de los beneficios que espere obtener de la inmutabilidad. La respuesta de Rei Miyasaka se dirigió a uno (evitar estados intermedios no válidos), pero aquí hay otro.
La mutación a veces se denomina actualización destructiva : cuando mutas un objeto, el estado anterior se pierde (a menos que tomes medidas adicionales para preservarlo explícitamente de alguna manera). En contraste, con datos inmutables, es trivial representar simultáneamente el estado antes y después de alguna operación, o representar múltiples estados sucesores. Imagine intentar implementar una búsqueda de amplitud mutando un solo objeto de estado.
Esto probablemente aparece en el mundo de la base de datos con mayor frecuencia como datos temporales . Digamos el mes pasado que estaba en el plan Básico, pero el día 16 se cambió al plan Premium. Si simplemente sobrescribimos algún campo que indicara en qué plan está, podríamos tener dificultades para realizar la facturación correctamente. También podríamos perder la capacidad de analizar tendencias. (¡Oye, mira lo que hizo esta campaña publicitaria local!)
Eso es lo que viene a mi mente cuando dices "inmutabilidad en el diseño de bases de datos", de todos modos.
fuente
Customer
tabla solo para recordar que el usuario cambió el plan no trae nada más que un gran inconveniente de rendimiento, selecciones más lentas con el tiempo, minería de datos más complicada (en comparación con los registros) y más espacio desperdiciado.Si está interesado en los beneficios que puede obtener de la inmutabilidad en una base de datos, o al menos en una base de datos que ofrece la ilusión de la inmutabilidad, marque Datomic.
Datomic es una base de datos inventada por Rich Hickey en alianza con Think Relevance, hay muchos videos donde explican la arquitectura, los objetivos y el modelo de datos. Buscar infoq, uno en particular se titula Datomic, Database as a Value . En confreaks puede encontrar una nota clave que Rich Hickey dio en la conferencia euroclojure en 2012. confreaks.com/videos/2077-euroclojure2012-day-2-keynote-the-datomic-architecture-and-data-model
Hay una charla en vimeo.com/53162418 que está más orientada al desarrollo.
Aquí hay otro de stuart halloway en.pscdn.net/008/00102/videoplatform/kv/121105techconf_close.html
Ahora, dado que la información se almacena como hechos a tiempo:
La base de datos es un valor y un parámetro para el motor de consulta, el QE gestiona la conexión y el almacenamiento en caché. Como puede ver la base de datos como un valor y una estructura de datos inmutable en la memoria, puede fusionarla con otra estructura de datos hecha a partir de valores "en el futuro" y pasarla al QE y consultar con valores futuros, sin cambiar la base de datos real .
Hay un proyecto de código abierto de Rich Hickey, llamado codeq , puede encontrarlo en github Datomic / codeq, que amplía el modelo git y almacena referencias a objetos git en una base de datos libre de datos, y realiza consultas de su código, usted puede ver un ejemplo de cómo usar datomic.
Puede pensar en datomic como un ACID NoSQL, con datums puede modelar tablas o documentos o tiendas Kv o gráficos.
fuente
La idea de evitar actualizaciones, y preferir las inserciones, es uno de los pensamientos detrás de la construcción de su almacenamiento de datos como fuente de eventos, una idea que a menudo encontrará utilizada junto con CQRS. En un modelo de origen de eventos, no hay actualización: un agregado se representa como la secuencia de su "transformación" (eventos) y, como resultado, el almacenamiento es de solo agregado.
Este sitio contiene discusiones interesantes sobre CQRS y el abastecimiento de eventos, si tiene curiosidad al respecto.
fuente
Esto tiene una relación muy estrecha con lo que se conoce como "Dimensiones que cambian lentamente" en el mundo del almacenamiento de datos, y las tablas "Temporales" o "Bitemporales" en otros dominios.
La construcción básica es:
Las ventajas de este esquema es que puede recrear el "estado" de su entidad lógica en cualquier momento, tiene un historial de su entidad a lo largo del tiempo y minimiza la contención si su "entidad lógica" se usa mucho.
Las desventajas son que almacena muchos más datos y necesita mantener más índices (como mínimo en Logical Key + ValidFrom + ValidTo). Un índice en Logical Key + Latest Version acelera enormemente la mayoría de las consultas. ¡También complica tu SQL!
Si esto vale la pena hacerlo a menos que realmente necesite mantener un historial y tenga un requisito para recrear el estado de sus entidades en un momento dado, depende de usted.
fuente
Otra posible razón para tener una base de datos inmutable sería admitir un mejor procesamiento paralelo. Las actualizaciones que se producen fuera de servicio pueden alterar los datos de forma permanente, por lo que debe producirse un bloqueo para evitarlo y destruir el rendimiento paralelo. Muchas inserciones de eventos pueden ir en cualquier orden, y el estado finalmente será correcto siempre que se procesen todos los eventos. Sin embargo, en la práctica, es tan difícil trabajar con esto en comparación con las actualizaciones de la base de datos que realmente necesitaría mucho paralelismo para considerar hacer las cosas de esta manera; no lo recomiendo.
fuente
Descargo de responsabilidad: soy prácticamente un novato en DB: p
Dicho esto, este enfoque de satélites de datos tiene un impacto inmediato en el rendimiento:
dependiendo de sus requisitos, puede aceptar esto o no, pero sin duda es un punto a tener en cuenta.
fuente
No veo cómo su esquema puede llamarse "inmutable".
¿Qué sucede cuando cambia un valor almacenado en la tabla suplementaria? Parece que necesitaría realizar una actualización en esa tabla.
Para que una base de datos sea realmente inmutable, debería ser mantenida únicamente por "INSERTOS". Para esto, necesita algún método para identificar la fila "actual". Esto casi siempre termina siendo terriblemente ineficiente. Tiene que copiar todos los valores sin cambios anteriores o juntar el estado actual de varios registros cuando realiza una consulta. La selección de la fila actual generalmente necesita un SQL terriblemente desordenado como (
where updTime = (SELECT max(updTime) from myTab where id = ?
).Este problema surge mucho en DataWarehousing, donde debe mantener un historial de los datos a lo largo del tiempo y poder seleccionar el estado para cualquier momento dado. La solución suele ser tablas "dimensionales". Sin embargo, mientras resuelven el problema de DW "quién fue el representante de ventas en enero pasado". No proporcionan ninguna de las ventajas que ofrecen las clases inmutables de Javas.
En una nota más filosófica; existen bases de datos para almacenar el "estado" (saldo bancario, consumo de electricidad, puntos de brownie en StackOverflow, etc., etc.) intentar crear una base de datos "sin estado" parece un ejercicio bastante inútil.
fuente
WHERE id = {} ORDER BY updTime DESC LIMIT 1
generalmente no es demasiado ineficiente.