Decidir entre una clave primaria artificial y una clave natural para una tabla de Productos

Básicamente, tendré que combinar datos de productos de múltiples proveedores en una única base de datos (es más complejo que eso, por supuesto) que tiene varias tablas que deberán unirse para la mayoría de las operaciones OLTP.

Iba a mantener el valor predeterminado y utilizar un entero de incremento automático como la clave principal, pero mientras un proveedor suministra su propio campo “ProductiD”, el rest no y tendría que hacer una gran cantidad de mapeo manual a la otra tablas para cargar los datos (ya que primero tendría que cargarlo en la tabla Productos, luego sacar el ID y agregarlo junto con la otra información que necesito para las otras tablas).

Alternativamente, podría usar el SKU del producto como clave principal, ya que el SKU es único para un solo producto, y todos los proveedores suministran un SKU en sus feeds de datos. Si uso el SKU como PK, podría cargar fácilmente los feeds de datos ya que todo está basado en el SKU, que es como funciona en el mundo real. Sin embargo, el SKU es alfanumérico y probablemente será un poco menos eficiente que una clave basada en números enteros.

¿Alguna idea sobre la cual debería mirar?

Esta es una elección entre claves primarias sustitutas y naturales .

En mi humilde opinión, siempre prefiero las claves primarias sustitutas. Las claves primarias no deberían tener significado porque ese significado puede cambiar. Incluso los nombres de los países pueden cambiar y los países pueden aparecer y desaparecer, y mucho menos los productos. No se recomienda cambiar las claves principales, lo que puede ocurrir con las teclas naturales.

Más sobre claves sustitutas vs claves primarias :

Entonces, ¿las claves sustitutas ganan? Bueno, revisemos y veamos si alguna de las contras de clave natural se aplica a las claves sustitutas:

  • Con 1: Tamaño de clave principal: las claves sustitutas generalmente no tienen problemas con el tamaño del índice, ya que generalmente son una sola columna de tipo int. Eso es casi tan pequeño como se pone.
  • Con 2: Tamaño de clave externa: no tienen problemas de tamaño de índice foráneo o de clave externa por la misma razón que Con 1.
  • Con 3: Asthetics – Bueno, es un ojo del tipo espectador, pero ciertamente no implican escribir tanto código como con las teclas naturales compuestas.
  • Con 4 y 5: Opcionalidad y aplicabilidad: las claves sustitutas no tienen problemas con personas o cosas que no desean o que no pueden proporcionar los datos.
  • Con 6: Unicidad: están 100% garantizados para ser únicos. Eso es un alivio.
  • Con 7: Privacidad: no tienen preocupaciones de privacidad si una persona inescrupulosa las obtiene.
  • Con 8: Denormalización accidental: no puede desnormalizar accidentalmente datos no comerciales.
  • Con 9: Actualizaciones en cascada: las claves sustitutas no cambian, por lo que no se preocupe por cómo ponerlas en cascada en la actualización.
  • Con 10: velocidad de unión de Varchar: generalmente son int, por lo que generalmente son tan rápidos como se puede unir.

¿Y también hay claves sustitutas vs claves naturales para la clave principal?

En todas las situaciones internas menos simples, recomiendo ir siempre por la clave sustituta. Le brinda opciones en el futuro y lo protege de incógnitas.

No hay ninguna razón para que las claves adicionales, como un SKU, no se puedan convertir en no nulas para aplicarlas, pero al menos al eliminar su dependencia de terceros, se está dando la opción de elegir, en lugar de tener que tomarlos de usted y soportar una reescritura dolorosa en una etapa posterior.

Ya sea que busque el entero autoincrementado o determine la próxima clave primaria usted mismo, habrá complicaciones. Con el método de incremento automático, puede insertar el registro fácilmente y dejar que asigne su propia clave, pero puede tener problemas para identificar exactamente qué clave recibió su registro (y no se garantiza que la clave máxima sea la suya).

Tiendo a buscar la clave autoasignada porque tiene más control y, en el servidor sql, puede recuperar su clave de una tabla de claves centrales y asegurarse de que nadie más obtenga la misma clave, todo en una sola statement:

DECLARE @Key INT UPDATE KeyTable WITH (rowlock) SET @Key = LastKey = LastKey + 1 WHERE KeyType = 'Product' 

La tabla registra la última clave utilizada. El sql anterior incrementa esa clave directamente en la tabla y devuelve la nueva clave, asegurando su singularidad.

Por qué deberías evitar las claves primarias alfanuméricas:

Tres problemas principales: rendimiento, colación y espacio.

Rendimiento: aunque hay un costo de rendimiento, como Razzie a continuación, no puedo citar ningún número, pero es menos eficiente para indexar alfanuméricos que números.

Intercalación: sus desarrolladores pueden crear la misma clave con diferentes intercalaciones en diferentes tablas (sucede) lo que lleva a utilizar constantemente los comandos ‘intercalar’ cuando se unen a estas tablas en consultas y eso se vuelve realmente rápido.

Espacio: un SKU de nueve caracteres como el de David toma nueve bytes, pero un entero toma solo cuatro (2 para smallint, 1 para tinyint). Incluso un bigint solo toma 8 bytes.

El peligro siempre presente con las claves naturales es que sus supuestos iniciales se probarán incorrectos ahora o en el futuro cuando se realice algún cambio fuera de su control, o en algún lugar necesitará hacer referencia a un registro donde pasar un campo significativo no es correcto. deseado (por ejemplo, una aplicación web que utiliza el número de seguridad social de un empleado como la clave principal, y luego tiene que usar URL como /employee.php?ssn=xxxxxxx)

Desde mi experiencia personal con SKU “únicos” y feeds de datos de proveedores, ¿está absolutamente seguro de que le están enviando un feed con SKU completas, únicas y bien formadas?

He tenido que lidiar personalmente con todo lo siguiente cuando obtengo feeds de proveedores que tienen distintos niveles de TI y competencia administrativa:

  • A los productos les falta su SKU por completo (“”)
  • Los empleados han utilizado SKU de marcador de posición en su base de datos como 999999999 y 00000000 y nunca los corrigieron
  • Aquellos que hacen la entrada de datos o la importación han confundido varios números de productos, mezclando cosas como UPC con SCC, o incluso encontrando formas de manipularlos juntos (he visto códigos SCC con dígitos de verificación imposibles al final, porque simplemente copiaron el UPC y agregó 01 o 10, sin corregir el dígito de control)
  • Por razones especiales, o simplemente por incompetencia, el vendedor ingresó el mismo producto dos veces en su base de datos (por ejemplo, rev. 1 y rev. 2 de la misma placa madre tienen el mismo SKU, pero existen como 2 registros en la base de datos de proveedores y datos porque rev 2. tiene nuevas características)

También iría con una clave primaria de incremento automático. El impacto en el rendimiento por tener una clave principal alfanumérica está ahí, aunque no me atrevo a nombrar ningún número. Sin embargo, si el rendimiento es importante en su aplicación, una razón más para ir con la columna de clave principal de autoincrement.

Aconsejo tener un entero “sin sentido” autoincrementado como clave principal. Si a alguien se le ocurre la idea de reorganizar las identificaciones de productos, al menos su base de datos no tendrá problemas.

Muy similar a mi pregunta hace unos meses …

¿Debo tener un campo de clave principal dedicado?

Fui con un PK autoincrementable al final.

Como está tratando con datos de múltiples proveedores fuera de su control, usaría una clave sustituta. No desea tener que volver a crear el diseño de su base de datos un día cuando uno de ellos le envíe un duplicado.

Una clave sustituta (campo INT de incremento automático) identificará de forma única una fila en la tabla. Por otro lado, una clave natural única (productName) evitará que los datos duplicados del producto entren en la tabla.

Con un campo de clave natural único, dos o más filas nunca pueden tener los mismos datos.

Con un campo clave sustituto, las Filas pueden ser únicas debido al campo INT de incremento automático, pero los datos en las filas no serán únicos porque la clave sustituta no tiene relación con los datos.

Tomemos un ejemplo de una tabla de usuario, el campo de clave natural de la tabla (nombre de usuario) evitará que el mismo usuario se registre dos veces, pero el campo INT de incremento automático (ID de usuario) no lo hará.

Si cada producto tendrá un SKU y el SKU es único para cada producto, no veo por qué no desea utilizarlo para una posible clave principal.

Siempre puedes tomar un hash del SKU que se deshace de los alfas. Tendría que codificar posibles colisiones (que deberían ser muy raras), lo que es una complicación adicional.

Usaría el hash para completar la clave primaria y facilitar la importación inicial, pero cuando la use en el dB siempre la tratará como si fuera un número aleatorio. De esta forma, la clave principal perderá su significado (y tendrá todas las ventajas de una clave autoincrementada), lo que permitirá flexibilidad en el futuro.