Estoy teniendo una discusión interesante con otro diseñador de bases de datos sobre la normalización. En este ejemplo, tenemos una tabla de GameTitles y cada registro debe contener el año en que se lanzó el juego. Él dice que 2NF exige que todo debe normalizarse, por lo tanto, para cumplir, el campo del año debe dividirse en una tabla ReleaseYears con su propia clave principal a la que hace referencia la tabla GameTitles. Digo que debería permanecer como un campo en la tabla GameTitles.
Mi argumento para esto es que un año es solo un valor numérico no primitivo que es estático por su propia naturaleza (es decir, 2011 siempre será 2011). Debido a esto, sirve como su propio identificador y no necesita nada para referenciarlo, ya que es lo que es. Esto también introduce mantenimiento adicional, ya que ahora debe agregar un nuevo año a la tabla solo para referenciarlo. Si rellena previamente la tabla con una amplia gama de años, entonces tiene registros adicionales que potencialmente no tendrán referencias a ellos en absoluto. Esto también aumenta el tamaño de la base de datos, ya que ahora tiene una tabla adicional, gastos generales de registro y la clave primaria adicional para el año en sí. Si mantiene el año como un campo en la tabla GameTitles, eliminará todo este mantenimiento adicional y gastos generales.
¿Pensamientos sobre esto?
editar: destinado a publicar esto en StackOverflow. ¿Alguien puede votar para eliminar esto o marcarlo para llamar la atención?
fuente
Respuestas:
El otro diseñador de bases de datos simplemente está equivocado, pero su razonamiento también está equivocado. Suponga que comienza con esta tabla, que tiene una sola clave candidata, "game_title".
Usted evalúa si está en 2NF haciéndose estas preguntas.
Q: En primer lugar, es en 1NF?
R: Sí, lo es.
P: ¿Cuáles son los atributos principales (atributos que forman parte de una clave candidata)?
R: "GAME_TITLE" es el atributo único primer.
Q: ¿Cuáles son los atributos que no son primos?
A: "year_first_released" es el único.
Q: ¿Es "year_first_released" funcionalmente dependiente de la totalidad de "GAME_TITLE", o en sólo una parte de ella?
R: La única clave candidata, "game_title", es una sola columna; Ni siquiera tiene partes. Por lo tanto, "year_first_released" depende funcionalmente del conjunto de "game_title".
Voilà. Has encontrado 2NF.
Puede cortar algunos de los términos formales preguntando primero si está en 1NF y luego respondiendo esta pregunta.
P: ¿Hay claves candidatas compuestas?
A: no.
Voilà. Has encontrado 2NF de nuevo.
Por definición, para que una tabla viole 2NF, debe tener al menos una clave candidata que tenga más de una columna.
Aquí están sus razones para rechazar la opinión de su amigo.
Ninguna de estas razones tiene nada que ver con si una tabla está en 2NF.
Al diseñar una base de datos, no está mal considerar los problemas de mantenimiento, el tamaño de la base de datos, las filas sin referencia, las restricciones de rango, etc. Es simplemente incorrecto llamar a esas cosas normalización.
Ah, y esa tabla de dos columnas que proporcioné arriba, está en 5NF.
fuente
Crear una tabla separada para cualquier atributo no tiene nada que ver con la normalización. 2NF, 3NF, BCNF, 4NF, 5NF se preocupan por eliminar las dependencias no clave. Si elimina cualquier atributo individual a una nueva tabla y lo reemplaza con un atributo de clave externa, entonces las dependencias en la tabla serán lógicamente las mismas que antes, por lo que la versión revisada de la tabla no está más o menos normalizada de lo que está. Fue antes.
fuente
Desde mi punto de vista, una tabla de años separada solo tendría sentido si el "año de publicación" no es un año calendario, sino, por ejemplo, un año fiscal que podría abarcar varios años calendario (por ejemplo, de octubre a octubre).
Esa tabla mantendría la definición (fecha real de inicio y finalización) del año fiscal
fuente
De http://en.wikipedia.org/wiki/Second_normal_form :
No indicó si el año es parte de la clave del candidato o no, pero no estoy seguro de que importe, porque en cualquier caso 2NF estaría satisfecho en lo que respecta al año.
A nivel práctico, es una mala idea separar el año por todas las razones que mencionó.
fuente
No me gusta el argumento en contra de la tabla separada debido a su tamaño o que tendrá filas no utilizadas. Incluso si pones 1000 años en esta tabla, el tamaño será insignificante.
Dicho esto, no creo que la mesa sea necesaria en absoluto. ¿Cuál es el punto de tener una mesa separada para el año? Estos datos ya están en la tabla principal y no guarda absolutamente nada al crear una segunda tabla.
El argumento puede ser diferente para una tabla de calendario, donde cada fila representa un día y puede tener otros atributos (día de la semana, desplazamiento UTC, ya sea un día festivo, etc.).
Pero año solo? No, no veo ningún beneficio en absoluto ... Y como otros han señalado, pregúntales por qué piensan que eso es más normalizado. O lo que ganan? Si intentas escribir consultas como
En lugar de
Entonces trataría de persuadirlo de que este último es mucho mejor para el rendimiento (suponiendo que dt esté indexado) y el almacenamiento. Si la simplicidad de codificación es primordial, diría que una columna calculada persistente sería mejor que otra tabla.
fuente
Estoy totalmente de acuerdo con la respuesta de Catcall, excepto en un punto: "año" puede no ser siempre un valor primitivo, pero supongo que es más un concepto de lógica de negocios que un diseño de base de datos.
Manteniendo el mismo diseño, supongamos que los años solo deberían ser aquellos años que están permitidos para su lanzamiento. De esta manera, no está tratando con valores numéricos primitivos, sino con un subconjunto de ellos, y como tal subconjunto no tiene una implementación primitiva, debe hacer lo suyo (¿una tabla separada?) Y hacer referencia a él (con un FK). De esa manera, todavía estamos hablando de años, pero necesitamos administrarlos de una manera diferente, porque conceptualmente cambiaron su significado. Sin embargo, todavía son "año de lanzamiento", pero conceptualmente diferentes en términos de lo que significan para alguien en el dominio del conocimiento.
Para este caso específico, nuevamente digo que la respuesta de Catcall es correcta, pero solo quería señalarlo. (Lo siento, todavía no tengo suficiente representante para comentar).
fuente