¿Hay ejemplos de enfoques que no sean CRUD?

14

Soy programador, pero también he trabajado como archivista. Como archivista se trata de mantener datos.

A menudo entro en discusiones con colegas cuando se trata de operaciones con datos. No me gusta demasiado la U y la D en CRUD. En lugar de actualizar un registro, prefiero agregar uno nuevo y tener una referencia al registro anterior. De esa manera construyes un historial de cambios. Tampoco me gusta eliminar registros, sino marcarlos como inactivos.

¿Hay un término para esto? ¿Básicamente solo creando y leyendo datos? ¿Hay ejemplos de este enfoque?

    
pregunta Pieter B 16.11.2012 - 18:57
fuente

8 respuestas

16

Marcar un registro como eliminado se conoce como eliminación suave . Nunca he escuchado una frase alternativa para actualizar, pero creo que eso es porque borras el registro anterior y creas uno nuevo.

Cabe señalar, esta es una técnica controvertida. Consulte los enlaces: Con vs Pro .

    
respondido por el pdr 16.11.2012 - 19:02
fuente
11

Uno de los problemas para retener un historial de cambios es que desordena la base de datos y puede aumentar dramáticamente su tamaño (según los patrones de uso). Por lo tanto, una buena idea sería almacenar la pista de auditoría en un lugar separado y mantener las tablas de la aplicación real llenas solo con datos relevantes. Por lo tanto, cada vez que la aplicación realiza una operación CRUD, el cambio se registra en las tablas de auditoría, y la operación CRUD se realiza en las tablas de la aplicación (sin borrados de software).

Al mantener el registro de auditoría separado, se obtiene un almacén de datos prístinos para que su aplicación interactúe, al tiempo que conserva el historial de cambios en caso de que lo necesite. Ahora también puede archivar la pista de auditoría por separado o incluso destruirla, según los requisitos de su negocio.

    
respondido por el System Down 16.11.2012 - 19:59
fuente
5

EventSourcing suena como el patrón que puede estar buscando.

Tomemos un ejemplo utilizando un objeto simple "coche" del que querríamos hacer un seguimiento del color (a continuación se muestra el código pseudo C #).

public class Car {
  public string Color { get; set; }
  public Car() { this.Color = "Blue"; }
}

Con una implementación de CRUD cuando actualizamos el color del automóvil, el color anterior se perdería.

MyCar.Color = "Red";
MyCar.Save();  // Persist the update to the database and lose the previous data

Esta pérdida de información me suena como lo que más te gustaría evitar (por lo tanto, no me gusta la actualización y eliminar parte del patrón CRUD).

Si tuviéramos que volver a escribir la clase de automóvil para responder a los eventos al actualizar su cambio, podría verse así:

public class Car {
    public string Color { get; private set; } // Cannot be set from outside the class

    public void ApplyEvent(CarColorChangedEvent e) {
      this.Color = e.Color;
    }
}

Ahora, ¿cómo actualizaríamos el color de este objeto? Podríamos crear un evento CarColorChanged !

var evnt = new CarColorChangedEvent("Red");
MyEventStore.save(evnt);
MyCar.ApplyEvent(evnt);

¿Observa la falta de guardar en el objeto del modelo real? Esto se debe a que, en lugar de persistir directamente en el modelo, persisten los eventos que ponen al modelo en el estado actual. Estos eventos deben ser inmutable .

Ahora vamos a avanzar y cambiar el color unas cuantas veces más:

var evnt = new CarColorChangedEvent("Green");
MyEventStore.save(evnt);
MyCar.ApplyEvent(evnt);

var evnt = new CarColorChangedEvent("Purple");
MyEventStore.save(evnt);
MyCar.ApplyEvent(evnt);

Si observáramos nuestro almacenamiento de eventos (podría ser una base de datos de relaciones, archivos, etc.) veríamos una serie de eventos relacionados con nuestro objeto de automóvil:

CarColorChangedEvent => Red
CarColorChangedEvent => Green
CarColorChangedEvent => Purple

Si quisiéramos reconstruir ese objeto de automóvil, podríamos hacerlo simplemente creando un nuevo objeto de automóvil y aplicando los eventos de nuestro almacén de eventos a dicho objeto.

var MyCar = new Car();
var events = MyDatabase.SelectEventsForCar("CarIdentifierHere");
foreach(var e in events) {
  MyCar.ApplyEvent(e);
}
Console.WriteLine(MyCar.Color); // Purple

Con el flujo de eventos podemos hacer retroceder el estado del automóvil a un período de tiempo anterior simplemente creando un nuevo objeto de automóvil y solo aplicar los eventos que deseamos:

var MyCar = new Car();
var event = MyDatabase.GetFirstEventForCar("CarIdentifierHere");
MyCar.ApplyEvent(e);
Console.WriteLine(MyCar.Color); // Red
    
respondido por el Mike 16.11.2012 - 23:17
fuente
5

Event Sourcing es el camino a seguir, y deberías echar un vistazo a lo que Greg Young tiene que decir al respecto.

enlace

También eche un vistazo a esta presentación en su base de datos (Event Store). Puedes encontrar otros videos también.

enlace

No buscaría la respuesta de "borrados suaves" a menos que específicamente necesite poder buscar elementos eliminados, pero luego no debería pensar en ellos como borrados sino archivados. Creo que la terminología es bastante importante aquí.

Tampoco me gustaría mantener una "tabla de versiones". Todas las "tablas de versiones" que he visto (incluidas las que estoy tratando de limpiar en este momento - 7 años de datos corrompidos debido a errores ... y no hay manera de recuperar eso aunque tengamos datos históricos). datos ... porque eso es igual de corrupto) terminan dañados debido a errores en el código y al final aún pierdes datos porque nunca puedes volver atrás y recrear los datos que dañaron la corrupción.

Con el modelo de fuentes de eventos, este no es el caso. Siempre puedes reproducir exactamente lo que hizo el usuario. Esta es la diferencia muy importante entre CRUD y Event Sourcing. La arquitectura de Event Sourcing guarda eventos en un almacén de eventos, y no objetos de datos u objetos de modelo de dominio. Un evento podría fácilmente impactar múltiples objetos. Simplemente piense en una solución de carrito de compras en la que convierta cada artículo del carrito de compras en un pedido real. Un evento afecta a todos los objetos del artículo, así como a los objetos del carrito de compras, que se transforma en un objeto de pedido.

Si mantuviste una copia versionada de cada fila en cada tabla de la base de datos, imagina el horror de tener que retroceder a una marca de tiempo específica, por no mencionar la gran cantidad de espacio y sobrecarga de rendimiento en el mantenimiento de esa tabla de versiones.

Con Event Sourcing, puede rebobinar fácilmente, simplemente reproduciendo eventos hasta cierto punto en el tiempo. Los avances rápidos se pueden implementar mediante el uso de instantáneas, pero eso es todo una cuestión de implementación.

Pero la verdadera ventaja que creo que le gustará, ya que está particularmente interesado en no perder datos, es que si descubre un error en el código que guarda estos datos, no necesita volver atrás y limpie los datos (lo que a menudo es imposible porque los datos casi nunca están completos). En su lugar, simplemente corrija el error y repita todos los eventos. Entonces tendrás una base de datos con datos correctos y buenos.

En el caso de la depuración, ¿con qué frecuencia le ha pedido al usuario que le diga lo que hizo ... por qué no vuelve a reproducir lo que hizo y luego pasa por el código? Bastante ingenioso eh.

Espero que esto ayude.

    
respondido por el Jay Pete 17.11.2012 - 00:39
fuente
2

No es precisamente su ejemplo, pero en sistemas financieros anteriores tenía WORM . Si necesitaba "actualizar", escribió un nuevo registro y siempre se refirió al último registro como actual, pero no se podrían sobrescribir los datos confirmados.

Mucha gente llevó esa idea a sistemas posteriores. He escuchado que lo que usted describe se refiere a tablas WORM, pero solo en esos círculos.

    
respondido por el Bill 16.11.2012 - 20:36
fuente
2

Sí, es bastante común en los sistemas empresariales, básicamente hay dos enfoques: -

  • "bi - temporal" en el que cada registro tiene una validez y una marca de tiempo válidas (el registro "actual" tiene una fecha válida de "para siempre": nulo, "9999-12-31" o algo similar) valor). Los registros nunca se eliminan, en lugar de eso, la fecha "válida para" se establece en la hora actual y, en el caso de una actualización, se inserta un nuevo registro con una fecha de validez actual y una fecha válida para siempre.
  • "tabla de historial": cada vez que se modifica un registro, se vuelca una copia del registro anterior en una tabla de historial / registro con una marca de tiempo para el evento.

Hay grandes variaciones en la granularidad para ambos enfoques. p.ej. Si se modifica la cantidad de widgets en un artículo de pedido, ¿mantiene el historial de todo el pedido o solo ese artículo?

En términos generales, "bi-temporal" es un montón de trabajo adicional y solo vale la pena si tiene muchos casos de uso como "el auditor obtiene el estado de la orden a partir del 31 de diciembre".

    
respondido por el James Anderson 15.08.2014 - 04:18
fuente
1

Puede usar "borrados suaves" como se sugiere en pdr . En cuanto a las actualizaciones, puede mantener un historial de registros, algo como mi respuesta aquí: enlace donde el OP quería poder realizar un seguimiento de todas las versiones de ciertos tipos de datos.

    
respondido por el FrustratedWithFormsDesigner 16.11.2012 - 19:37
fuente
-2

básicamente crud no puede completarse sin estas 4 cosas. Crud significa crear, leer, actualizar y eliminar, de modo que cuando solo intenta leer datos, puede utilizar una consulta simple para eso, pero todas estas tres cosas se adjuntan a una y a otras y a conceptos simples de base de datos     

respondido por el Tayyab Vohra 17.11.2012 - 07:39
fuente

Lea otras preguntas en las etiquetas