Desventajas entre la normalización y la desnormalización

Descubra la diferencia entre los esquemas normalizados y desnormalizados para modelar los datos, y algunas de las desventajas de cada uno.

Normalización

La normalización es una forma de definir el esquema de su base de datos de una manera que está optimizada para una rápida y alta integridad writes asegurando que no hay datos redundantes a través de las tablas.

El estándar para la normalización es disparar para 3rd normal form (3nf).

Un breve recuento de los criterios para lograr el 3nf:

  • Los registros de una tabla deben contener primary_keys que los referencien de forma única (1nf)

  • No debe haber columnas repetidas en una tabla (1nf)

  • No debe haber no debería haber claves funcionalmente dependientes (2nf)

  • No debería haber claves funcionalmente dependientes de forma transitoria (3nf)

Como las tablas no contienen datos redundantes, el storage necesario para los nuevos registros de cualquier tabla es relativamente pequeño.

Como las escrituras son pequeñas, también son fast.

También se garantiza que las escrituras dejan la base de datos en un consistent estado, debido a las referential integrity garantías de las restricciones de clave foránea entre tablas relacionadas.

Denormalización

La normalización es el acto de añadir redundancias o valores derivados en su esquema para optimizar para reads que de otro modo sería caro en un esquema normalizado.

Piensa por un momento en una base de datos totalmente normalizada…

Todo está en su propia tabla…

Todo tiene su propia primary_key…

Las referencias entre tablas se mantienen mediante foreign_key constraints…

… esto es genial desde una perspectiva de almacenamiento e integridad, pero puede llevar a que las piezas de una consulta se distribuyan en muchas tablas, lo que lleva a uniones lentas y complejas para obtener la imagen completa de una consulta.

Si usted es capaz de anticipar los tipos de consultas que sus usuarios podrían estar haciendo, podría tener sentido almacenar algunos valores de forma redundante en su sistema para acelerar el rendimiento de las consultas.

Añadir valores desnormalizados hace que las inserciones y actualizaciones sean más complicadas: usted necesita asegurarse de que los valores desnormalizados se mantienen adecuadamente, ya que la integridad de estos valores no se aplica automáticamente por el esquema.

La elección de desnormalizar debe hacerse conscientemente. Debe ser documentada, probada y debe ser comunicada a través de un equipo para que todos sean conscientes de esta consideración adicional al escribir en tablas desnormalizadas.

Ejemplo de desnormalización

Estoy construyendo una aplicación llamada CashBackHero, que implica el modelado de las relaciones entre las tarjetas de crédito y los usuarios a través de una entidad llamada cartera. Un esquema 3nf normalized para estas entidades podría ser algo así:

Monedero

.

id valor
1 3
2 4
3 5

Tarjetas

.

id nombre cash_back_id
1 Perseguir 2
2 Descubrir 1
3 Amex 3

Bolsas

.

id nombre
1 Billetera de Brian
2 Billetera de Alex 3 Billetera de Lauren

Carteras (asociaciones entre carteras y tarjetas)

.

5

id cartera_id card_id
1 1 1
2 1 3
3 2 2
4 3 2
3 1

Las tablas anteriores son normalized, ya que no contienen datos redundantes. Las relaciones entre las tablas se mantienen a través de foreign_key restricciones a otras tablas. Esto almacena los datos en su forma más compact.

La falta de datos redundantes también optimiza la writes a la base de datos. Las escrituras más frecuentes son las adiciones y eliminaciones en la tabla CardWallets, que sólo implican columnas de id que contienen referencias a otras tablas que contienen información.

La normalización de los datos también hace que las actualizaciones sean muy sencillas, ya que cada tabla es una única fuente de verdad para la información que contiene.

Una base de datos normalizada también optimiza algunos tipos de lecturas, como la aparición de una lista de todos los valores en una tabla en particular (como obtener todas las tarjetas).

Las lecturas en las que los datos se encuentran en varias tablas, sin embargo, se vuelven más difíciles. Una consulta al esquema normalizado anterior para obtener los nombres y valores de devolución de dinero de las tarjetas del monedero 1 implica unir las tablas Wallets y Cards a la tabla CardWallets, y luego unir la tabla CashBackValue a la tabla Cards. Si estas tablas se hacen grandes, las consultas podrían volverse lentas en comparación con una versión desnormalizada en la que todos los datos viven en una sola tabla.

Hablando de desnormalizado…

Ejemplo desnormalizado

Mira cómo sería el esquema normalizado presentado anteriormente si estuviera totalmente desnormalizado:

Esquema de CashBack

.

2

.

id nombre de la tarjeta nombre de la cartera valor de cash_back
1 Bolsa de Adrián 4
Amex Bolsa de Cartera 5
3 Descubrir Billetera de Alex 3
4 Descubrir Billetera de Lauren 3
5 Perseguir La Cartera de Lauren 4

¡Es una mesa monstruosa!

Bien… sólo son 5 filas… pero te haces a la idea de que una tabla desnormalizada puede ser a menudo más fácil de leer, ya que todos los datos existen en un solo lugar.

En lugar de tener que unir 4 tablas para obtener las tarjetas y cash_back_value de la cartera de un usuario, ahora sólo podemos ejecutar una sentencia select a la tabla CashBackSchema anterior.

La búsqueda de tarjetas únicas se vuelve un poco más lenta, ya que hay que leer toda la tabla para determinar los nombres de las tarjetas únicas.

Las actualizaciones también son un poco más complicadas: tenemos que asegurar la integridad de nuestros datos logically. Por ejemplo, si queremos actualizar el cash_back_value de la tarjeta Chase en la cartera de Brian, también tenemos que tener en cuenta si necesitamos actualizar también el cash_back_value de la tarjeta Chase en la cartera de Lauren. Las actualizaciones tienen que hacerse en varios lugares, lo que puede ser lento para las tablas grandes.

En un esquema normalizado, las actualizaciones de algo como «wallet_display_name» sólo pueden hacerse en un lugar (la tabla Wallets), en lugar de tener que peinar toda la tabla CashBackSchema para asegurarse de que cada fila con el nombre «Cartera de Brian» se actualiza adecuadamente.