¿Puedo descomponer sin pérdidas esta tabla?


10

Me topé con un problema de diseño de base de datos que está fuera de mi alcance, y mi gurú de DBA está en simulacros de incendio.

En esencia, tengo una tabla con la siguiente clave primaria (PK por brevedad):

child_id   integer
parent_id  integer
date       datetime

child_idy parent_idson claves foráneas para las tablas de entidad. La tabla "secundaria" en sí también contiene una clave foránea para la tabla "principal", y he aquí, cada una child_idsiempre hace referencia a la misma parent_idque la tabla anterior. De hecho, resulta que hay un código adicional que mantiene los dos sincronizados.

Lo que hace que este principiante de normalización demasiado entusiasta diga "¡Debería eliminar la redundancia en su lugar!"

Me descompongo a lo siguiente:

Table_1 PK:
child_id   integer
date       datetime

Table_2 PK:
parent_id  integer
date       datetime

Table_3: (already exists)
child_id   integer PRIMARY KEY
parent_id  integer FOREIGN KEY

Y he aquí, cuando me uno a estos tipos juntos de forma natural, recupero la tabla original. Es mi entendimiento lo que hace que este 5NF.

Sin embargo, ahora me doy cuenta de que hay una regla comercial oculta.

Normalmente, las fechas asociadas con un determinado child_iddeben ser un subconjunto de las fechas asociadas con el correspondiente parent_id. Puede ver que la primera tabla impone esta regla.

Mi descomposición no impone la regla, porque puede agregarla libremente a la Tabla 1 hasta que las fechas sean demasiado grandes.

Lo que me lleva aquí, con las siguientes preguntas:

  1. ¿Es esta descomposición 5NF? Si bien diría que permite anomalías de inserción, también parece seguir el ejemplo de Wiki, que en sí mismo sigue esta guía . La frase (énfasis mío) "podemos reconstruir todos los hechos verdaderos a partir de una forma normalizada que consta de tres tipos de registros separados" me da una pausa especial, ya que no importa la cantidad de basura que bombeo Table_1, la unión natural todavía lo ignora.

  2. Supongamos que no me gusta esta descomposición (no me gusta). Reconozco libremente que la solución práctica es dejar la tabla y el código como están. Pero, en teoría, ¿hay alguna forma de descomponer y / o agregar restricciones de manera que me salga de la primera tabla y conserve mis reglas comerciales?


1
¿Cuáles son las claves en su tabla original? ¿Qué dependencias se supone que satsify? Parece que está diciendo que child_id-> parent_id, en cuyo caso child_id y parent_id no pueden ser parte de la misma clave en esa tabla.
nvogel

1
@trevor: ¿Alguna vez revisaste las respuestas aquí? Visto por última vez 19 minutos después de preguntar. Las respuestas llegaron después.
gbn

Respuestas:


9

La normalización se basa en dependencias funcionales. Las dependencias funcionales tienen que ver con la semántica; tienen que ver con lo que significan los datos . Cuando simplifica un problema del mundo real al nivel de "parent_id, child_id, date", y no incluye ningún dato de muestra, realmente limita la cantidad de ayuda que un diseñador de bases de datos puede brindarle.

El hecho de que tenga una clave {child_id, parent_id, date} en una tabla y que tenga (parece) un par único {child_id, parent_id} en la tabla secundaria no significa necesariamente que parte de la combinación sea redundante . Puede significar que en la tabla que tiene {child_id, parent_id, date} como la clave principal, el par de atributos {child_id, parent_id} debería hacer referencia a la tabla secundaria en primer lugar.

Si ese es el caso, puede usar FOREIGN KEY (child_id, parent_id) REFERENCES child (child_id, parent_id). Para hacer eso, necesita una restricción ÚNICA en el par de columnas (child_id, parent_id) en la tabla "child", que no debería ser un problema si child_id es su clave principal.

Pero no hay forma de saberlo sin saber qué significan los datos, y usted es el único en este hilo que lo sabe. (Pero nos complacerá que nos lo explique).

En lo que respecta a la tabla original, parece que estás diciendo que child_id -> parent_id. Si ese es el caso, ¿por qué es parent_id en la tabla original en primer lugar? ¿Por qué la clave no es solo (child_id, date), con una referencia de clave externa a la tabla "child"? Me parece que el tipo de redundancia de la que estás hablando podría resolverse soltando la columna "parent_id".

SQL DDL y datos de muestra en forma de instrucciones INSERT nos ayudan a ayudarlo. Las declaraciones DDL e INSERT son más precisas que las descripciones.


1
+2 para el recordatorio de "dependencia funcional"
jcolebrand

3

Prueba esto...

  • Agregar restricción única a (child_id,parent_id) en la tabla secundaria
  • Su tabla actual (PK,FK:child_id, PK,FK:parent_id, PK:date)permanece como está, el FK está en 2 columnas a la nueva restricción única

o

  • Eliminar el FK de la tabla secundaria actual
  • Crea una nueva tabla (PK,FK:child_id, FK:parent_id) que sea 1: 1 con hijo
  • Su tabla actual (PK,FK: child_id, PK,FK: parent_id, PK:date)permanece como está. pero el FK está en 2 columnas a la nueva tabla

Si nada más, puede inspirarte ...

Si lo he entendido correctamente, eliminará la redundancia y el código ...

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.