¿Cuál es la diferencia entre la captura de datos de cambio y el abastecimiento de eventos?

Ambas son formas de modelar datos, especialmente a escala, utilizando una combinación de una base de datos mutable y un registro. La principal diferencia es si la base de datos es el registro primario o el registro, pero probablemente sea más fácil comenzar con un ejemplo. Consideremos el voto positivo que puede dar esta respuesta después de leerla. La forma tradicional de almacenar eso podría ser tener una tabla llamada algo así como UserAnswerUpvote (tal vez relacional, tal vez no) en la que insertemos un registro una vez que se produce un voto positivo (por ejemplo, el registro podría verse como [upvoterUserId, answerId, time]. Si se elimina un voto a favor, esa entrada se eliminaría (o actualizaría para marcarla como eliminada).

Ahora, imagine que el voto a favor también necesita aumentar el conteo de votos a favor de la respuesta. Todavía podríamos usar nuestra misma tabla y simplemente consultar el número de conteo cuando lo necesitemos (normalización). A escala, esto comenzará a ser muy lento, pero tal vez podamos implementar algún valor en caché de ese recuento que se ensucia en ciertos eventos. Por otro lado, podríamos crear una tabla separada, AnswerUpvoteCounts, y el evento upvote podría insertar una entrada en nuestra tabla original y también incrementar el valor de conteo en nuestra nueva tabla (desnormalización). Sin embargo, ahora nuestras escrituras se han vuelto lentas y debemos preocuparnos por la coherencia (¿qué pasa si una escritura tiene éxito y la otra falla?). Ahora imagine que también queremos un recuento del total de votos positivos que ha recibido el usuario, necesitamos una capa analítica que sea fácil de consultar, etc. Imagine también que tenemos millones de usuarios y que las respuestas y los votos positivos suceden a un ritmo realmente rápido. Puedes ver por qué en este mundo, tanto la normalización como la desnormalización comienzan a descomponerse.

Cambiar la captura de datos (CDC) es una técnica para manejar este problema. En ese mundo, mantenemos nuestra base de datos como el sistema de registro, pero cualquier cambio en la base de datos se escribiría en un registro. Otros consumidores de esos datos escucharían, o se “suscribirían” a ese registro, y realizarían los cambios apropiados (por ejemplo, aumentar un conteo). Técnicamente, aún necesita dos escrituras en el momento del evento (base de datos y registro), pero ese es el máximo (y de hecho, muchas bases de datos transaccionales están haciendo esas dos escrituras de todos modos). El principal beneficio aquí es que no tiene que alejarse demasiado de su modelo de base de datos original.

El abastecimiento de eventos es un patrón más extremo. La principal diferencia es que, en lugar de que su base de datos (o al menos una tabla) sea su sistema de registro, el registro se convierte en el sistema de registro. Cualquier evento solo se escribe directamente en un registro inmutable de solo agregado. Todas las tablas de la base de datos se suscribirán a ese registro y realizarán las actualizaciones apropiadas. Los beneficios incluyen la inmutabilidad, lo que significa que el rendimiento es mucho más rápido y obtienes un acoplamiento más flexible entre la escritura de datos y todos sus diferentes consumidores. En muchos sentidos, también es una forma más “correcta” de modelar datos, ya que el estado siempre se puede reconstruir a partir de eventos, pero no al revés.

Entonces, ¿por qué el abastecimiento de eventos no es más frecuente? El patrón ha existido durante siglos, pero las herramientas (para tener fácilmente registros distribuidos solo anexados, para garantizar la coherencia, etc.) simplemente no estaban allí, y muchos desarrolladores (incluido yo mismo) cablearon nuestros cerebros y construyeron sistemas alrededor del ” modelo de base de datos mutable “, y esa fricción es difícil de superar. Es posible que no valga la pena la sobrecarga cuando no está a gran escala, pero generalmente es cuando se deben tomar decisiones arquitectónicas.