Orientación para usar claves compuestas para identificar filas

8

¿Es una buena práctica (o tendría algún efecto adverso) usar un conjunto de 4 columnas para identificar una fila como única (una es una clave extranjera y las otras tres son tipos de datos flotantes)? Estoy intentando crear una tabla que (con 4 teclas vinculadas) describa una entrada única en la tabla. Tengo curiosidad si este es un buen plan de ataque o si hay una mejor manera.

Para fines visuales, imagine la siguiente tabla. Tenemos elementos de inventario que están organizados como la siguiente tabla: ( [K]es simbólico de la clave primaria, las líneas son relaciones)

    Sheet_Class        Sheet_Type         Sheet_Size
    ===========        ==========         ==========
[K] Sheet_Class-.  [K] Sheet_Type--.  [K] Sheet_Size
                 '---- Sheet_Class  '---- Sheet_Type
                                          Length
                                          Width
                                          Thickness

Los datos pueden presentarse de la siguiente manera, pero por brevedad he excluido traer las columnas vinculadas:

 Sheet_Class    Sheet_Type    Sheet_Size                        (Tables)
[Sheet_Class]  [Sheet_Type]  [Length], [Width], [Thickness]     (Column Values)
=============  ============  ==============================

Aluminum
               5052-H32
                             48, 96, 0.032
                             48, 96, 0.040
                             48, 96, 0.063

               6061-T6
                             60, 120,0.032
                             60, 120,0.040
                             60, 120,0.063

Steel
               1018-CRS
                             48, 96, 0.018
                             48, 96, 0.023
                             48, 96, 0.031

Tal como está (y lo he mostrado en mi "esquema" arriba), utilizo una clave primaria entera (incremento automático) simple para las entradas en la tabla Sheet_Size . Sin embargo, me gustaría saber si es mejor usar una combinación de las columnas Sheet_Type , Length , Width y Thickness . Dado que cada entrada en Sheet_Size debería compartir todas estas cualidades únicas, y que un campo de incremento automático no demostraría esto lo suficientemente bien, ¿es esta la mejor ruta a seguir?

Si no estoy explicando la situación lo suficientemente bien, hágamelo saber. Me encuentro necesitando dividir estas porciones (Clase vs. Tipo vs. Tamaños reales de existencias) de un material inventariado para otros propósitos lógicos, pero estoy preparado para cualquier otro tipo de retroalimentación.

Cualquier orientación sería apreciada.

Actualización (08-12-2011)

Después de las respuestas publicadas, he decidido hacer una combinación de la respuesta de la marca y la respuesta de X-Zero . Decidí que es una buena idea colocar una restricción única en las columnas de longitud, ancho y grosor, pero también me gusta la idea de dividir tamaños de material en filas únicas y vincularlas con una relación.

Desafortunadamente, no puedo aceptar ambas respuestas, por lo que voy a aceptar X-Zeros por considerar (lo que siento) una mirada más crítica al problema y ofrecer un ajuste de esquema.

Gracias a todos por sus respuestas.

Brad Christie
fuente

Respuestas:

6

Después de pensar en esto, revisaría la estructura de su tabla solo un poco.
Primero, revise su tabla de tamaño de hoja:

Sheet_size
===========
Id
Length
Width
Thickness

En segundo lugar, cree una tabla de relación de tamaño de hoja / tipo:

Sheet_size_type
================
Sheet_Type_Id
Sheet_Size_Id

Luego, cree las siguientes restricciones:

  1. La clave primaria (e índice) de Sheet_size debería ser la columna id
  2. Debe haber algún tipo de clave única (e índice) aplicada en las dimensiones en Sheet_size . Considere, ¿son dos hojas de dimensiones (48, 96, .5) y (96, 48, .5) iguales (es decir, ¿importa la dirección de las dimensiones)? Este tipo de problema puede ser difícil de aplicar si se usan las columnas como parte de la clave primaria, pero se vuelve más manejable cuando se usan restricciones y procedimientos almacenados.
  3. La clave primaria (e índice) de Sheet_size_typedebe usar ambas claves externas, comenzando con la que tiene la cardinalidad más baja (probablemente sheet_type, dado su ejemplo). Es posible que desee un índice adicional en la otra dirección, pero puede que no sea necesario.

Esta revisión le ahorrará espacio en la base de datos (como una proporción del número de tipos de hoja que usan el mismo tamaño) y no debería afectar demasiado la sobrecarga.


Hay otras preocupaciones potenciales sobre la igualdad / unicidad si está utilizando un floattipo de datos, ya que la imprecisión puede hacer que se tropiece inesperadamente. Debería considerar si un tipo de punto fijo, con cierta precisión dada, sería más apropiado.

Clockwork-Muse
fuente
Estaba planeando limitar la longitud y el ancho a un solo (posible dos) puntos decimales, y el grosor (como máximo) se extendería a tres. Más allá de eso, nos estamos volviendo demasiado finitos (y el stock en sí mismo nunca llega a los números de descripción de todos modos). Aparte de eso, me gusta la idea de dividir los tamaños de las hojas, pero el problema al que me enfrento son las otras columnas involucradas (que he excluido). (necesita más espacio, ver próximo post)
Brad Christie
Debido a que esta es una lista de existencias inventariadas, tengo que incluir otra información como la densidad y el costo / lb (que se basa en gran medida en el tipo (y el grosor, incluso. Por ejemplo, "Steel" / "1018" podría ser $ 0.55 / lb a 0.018-0.125 "de grosor, pero se convierte en $ 0.65 / lb una vez que el grosor supera los 0.125". (Y esto también puede diferir entre un tamaño de hoja de 48 "x96" x0.250 "de 1018 versus 5052-H32). En su ejemplo, Solo tendría una entrada para 48 "x96" x0.125 "(aunque supongo que la tabla de relaciones podría tener estas métricas adicionales)
Brad Christie
Si solo necesita un pequeño número de decimales, entonces sí, use una precisión fija. Sí, ahí es donde (en este caso) pondría información como esa (el costo es una dependencia del tipo y tamaño de la hoja, por ejemplo), aunque es posible que desee generar tablas adicionales a las que se pueda hacer referencia. También puede considerar crear tipos de datos personalizados (como la densidad) para que las personas no intenten consultar sus datos de manera inesperada.
Clockwork-Muse
6

Se parece a un naturales vs sustituto decisión clave, opinión sobre el cual oscila entre considerado y práctico a académicos , lindando con el dogma. Dependiendo del RDBMS, existen consideraciones para el modelo físico que pueden tener implicaciones de rendimiento significativas , por ejemplo, elección de clave en clúster en SQL Server.

Personalmente, si tengo una clave candidata estrecha y de un solo atributo, me siento tentado a utilizarla. Teclas anchas y / o compuestas, por defecto estoy agregando un sustituto al modelo. En su caso, votaría por la columna de identidad en Sheet_Size como clave principal agrupada y una restricción única en tipo / longitud / ancho / grosor.

Mark Storey-Smith
fuente
Pero dado que ahora tiene una clave "arbitraria" dada a la fila, ¿cómo hace único para que las columnas (cuando se combinan) no puedan tener valores duplicados? Tengo entendido que el atributo único se relaciona con la clave. Que está diciendo Sheet_Size INT PRIMARY KEYy Length UNIQUE, Width UNIQUE, Thickness UNIQUE? Todavía no entiendo cómo eso evita duplicados en la tabla (sin aplicar lógica a la interfaz de inserción). (¿Tal vez me estoy perdiendo algo?)
Brad Christie
Una restricción única en las tres columnas: ALTER TABLE dbo.Sheet_Size ADD CONSTRAINT UC_LengthWidthThickness UNIQUE ([Length], [Width], [Thickness])
Mark Storey-Smith
Gracias por los comentarios. Estoy de acuerdo en que una restricción única en las columnas sería una gran solución, pero también me gusta la recomendación de X-Zero de dividir los tamaños en una nueva tabla (vinculada con una nueva tabla). Entonces, para combinar ideas, aplicaré la restricción única a la tabla de tamaños "Despojado", mientras elimino la información de densidad y costo / lb y la coloco en la tabla de relaciones.
Brad Christie
4

Te redirigiré un poco a esta respuesta de una pregunta anterior .

Cita: "En cuanto a la forma de diseñar esa clave principal, hay dos escuelas de pensamiento:

  • uno que hace que el PK sea una columna separada, generalmente autogenerada, como un GUID o un INT de incremento automático (en su caso, una columna de identificador único separada);
  • uno que hace que la PK como una columna (o conjunto de columnas) sea interna a la tabla (en su caso sería un nombre de usuario o correo electrónico o SSN, lo que hace que ese usuario sea único) que identifique de forma única un registro.

A qué línea te adhieres, es solo cuestión de gustos ".

Los efectos secundarios de cualquier solución elegida podrían ser:

  • El uso de teclas compuestas en todas partes probablemente

    • aumentar el almacenamiento para todas las mesas involucradas;
    • aumentar / complicar índices en FK de uso frecuente;
    • complicar un poco la escritura de todas sus declaraciones de unión
    • haga feliz al Sr. Joe Celko :-) (las referencias sobre sus opiniones con respecto a las llaves naturales o artificiales se pueden encontrar aquí y aquí , y principalmente en todas partes donde se le preguntó sobre el tema)
  • el uso de claves generadas probablemente:

    • simplifica los 3 pasos anteriores
    • complicar la situación de replicar una tabla con identidad PK (referencias aquí , aquí o aquí )

Personalmente, prefiero las claves de IDENTIFICACIÓN INT generadas, pero lo que le convenga debería estar bien.

Mariana
fuente
2

La clave compuesta tiene mucho sentido. La implementación de esa clave garantiza que los atributos del negocio no se puedan duplicar. Eso es algo bueno porque registrar los mismos datos varias veces causaría ambigüedad, dependencias indeseables y haría que los errores del usuario y los datos incorrectos sean más probables.

La clave de incremento automático por sí sola no protegerá la integridad de sus datos comerciales. Si la clave de incremento automático no sirve para propósitos particulares (por ejemplo, como el objetivo de una referencia de clave externa en otra tabla), entonces se puede descartar de forma segura.

nvogel
fuente
... Excepto soltar el incremento automático ya que la clave externa requeriría usar todas las columnas de dimensión como parte de la clave externa (es decir, las cuatro columnas , cuando se incluye el tipo). No es algo que quiera como mi clave foránea, punto, solo columnas individuales, por favor. Estoy de acuerdo en que es una buena idea poner una clave única (y / o verificar la restricción) en las dimensiones (y tipo, dependiendo del diseño de la tabla).
Clockwork-Muse
@ X-Zero, destaqué las referencias de claves externas en mi segundo párrafo. La pregunta que leí es si implementar la clave compuesta, no si también tener un incremento automático.
nvogel