Claves primarias compuestas versus campo ID de objeto único


Heredé una base de datos construida con la idea de que las claves compuestas son mucho más ideales que usar un campo de ID de objeto único y que al crear una base de datos, un único ID nunca se utilizará como clave primaria. Debido a que estaba construyendo un front-end de Rails para esta base de datos, me encontré con dificultades para que se ajustara a las convenciones de Rails (aunque era posible usar vistas personalizadas y algunas gemas adicionales para manejar claves compuestas).

El razonamiento detrás de este diseño de esquema específico de la persona que lo escribió tenía que ver con cómo la base de datos maneja los campos de identificación de una manera no eficiente y cuando está construyendo índices, las clases de árbol son defectuosas. Esta explicación carecía de profundidad y todavía estoy tratando de envolver mi cabeza alrededor del concepto (estoy familiarizado con el uso de claves compuestas, pero no el 100% del tiempo).

¿Puede alguien ofrecer opiniones o añadir mayor profundidad a este tema?

Author: Brian, 2008-10-01

15 answers

La mayoría de los motores de uso común (MS SQL Server, Oracle, DB2, MySQL, etc.) no experimentaría problemas notables utilizando un sistema de claves sustitutas. Algunos incluso pueden experimentar un aumento del rendimiento del uso de una sustituta, pero los problemas de rendimiento son altamente específicos de la plataforma.

En términos generales, la clave natural (y por extensión, la clave compuesta) los versículos que sustituyen a la clave el debate tiene una larga historia sin una probable "respuesta correcta" a la vista.

Los argumentos para las claves naturales (singular o compuesto) por lo general incluyen algunos de los siguientes:

1) ya están disponibles en el modelo de datos. La mayoría de las entidades modeladas ya incluyen uno o más atributos o combinaciones de atributos que satisfacen las necesidades de una clave con el propósito de crear relaciones. Agregar un atributo adicional a cada tabla incorpora una redundancia innecesaria.

2) eliminan la necesidad de ciertas combinaciones. Por ejemplo, si tiene clientes con códigos de cliente, y facturas con números de factura (ambos son claves" naturales"), y desea recuperar todos los números de factura para un código de cliente específico, simplemente puede usar "SELECT InvoiceNumber FROM Invoice WHERE CustomerCode = 'XYZ123'". En el enfoque clásico de la clave sustituta, el SQL se vería algo como esto: "SELECT Invoice.InvoiceNumber FROM Invoice INNER JOIN Customer ON Invoice.CustomerID = Customer.CustomerID WHERE Customer.CustomerCode = 'XYZ123'".

3) Contribuyen a un enfoque de aplicación más universal para el modelado de datos. Con las claves naturales, el mismo diseño se puede usar sin cambios entre diferentes motores SQL. Muchos enfoques clave sustitutos utilizan técnicas específicas del motor SQL para la generación de claves, lo que requiere una mayor especialización del modelo de datos para implementarlo en diferentes plataformas.

Los argumentos para las claves sustitutas tienden a girar en torno a problemas que son específicos del motor SQL:

1) Permiten cambios más fáciles en los atributos cuando cambian los requisitos/reglas del negocio. Esto se debe a que permiten que los atributos de datos se aislen en una sola tabla. Esto es principalmente un problema para los motores SQL que no lo hacen de manera eficiente implementar construcciones SQL estándar como dominios. Cuando un atributo está definido por una instrucción DOMAIN, los cambios en el atributo se pueden realizar en todo el esquema mediante una instrucción ALTER DOMAIN. Diferentes motores SQL tienen diferentes características de rendimiento para alterar un dominio, y algunos motores SQL no implementan DOMINIOS en absoluto, por lo que los modeladores de datos compensan estas situaciones agregando claves sustitutas para mejorar la capacidad de realizar cambios en los atributos.

2) permiten más fácil implementaciones de concurrencia que las claves naturales. En el caso de la clave natural, si dos usuarios están trabajando simultáneamente con el mismo conjunto de información, como una fila de cliente, y uno de los usuarios modifica el valor de la clave natural, entonces una actualización por el segundo usuario fallará porque el código de cliente que están actualizando ya no existe en la base de datos. En el caso de la clave sustituta, la actualización se procesará correctamente porque los valores de ID inmutables se utilizan para identificar las filas en la base de datos, no códigos de cliente mutables. Sin embargo, no siempre es deseable permitir la segunda actualización – si el código de cliente cambió es posible que el segundo usuario no se le permita continuar con su cambio porque la "identidad" real de la fila ha cambiado – el segundo usuario puede estar actualizando la fila incorrecta. Ni las llaves sustitutas ni las llaves naturales, por sí solas, abordan este problema. Las soluciones integrales de concurrencia deben abordarse fuera de la implementación de la clave.

3) Funcionan mejor que las teclas naturales. El rendimiento se ve más directamente afectado por el motor SQL. El mismo esquema de base de datos implementado en el mismo hardware usando diferentes motores SQL a menudo tendrá características de rendimiento dramáticamente diferentes, debido a los mecanismos de almacenamiento y recuperación de datos de los motores SQL. Algunos motores SQL se aproximan mucho a los sistemas de archivos planos, donde los datos se almacenan de forma redundante cuando el mismo atributo, como un código de cliente, aparece en varios lugares en el esquema de base de datos. Este almacenamiento redundante del motor SQL puede causar problemas de rendimiento cuando es necesario realizar cambios en los datos o el esquema. Otros motores SQL proporcionan una mejor separación entre el modelo de datos y el sistema de almacenamiento/recuperación, lo que permite cambios más rápidos de datos y esquemas.

4) Las claves sustitutas funcionan mejor con ciertas bibliotecas de acceso a datos y marcos GUI. Debido a la naturaleza homogénea de la mayoría de los diseños de claves sustitutas (ejemplo: todos los diseños relacionales las claves son enteros), las bibliotecas de acceso a datos, los frameworks y los marcos GUI pueden trabajar con la información sin necesidad de un conocimiento especial de los datos. Claves naturales, debido a su naturaleza heterogénea (diferentes tipos de datos, tamaño, etc.), no funcionan tan bien con herramientas y bibliotecas automatizadas o semiautomáticas. Para escenarios especializados, como bases de datos SQL incrustadas, puede ser aceptable diseñar la base de datos con un kit de herramientas específico en mente. En otros escenarios, las bases de datos son información empresarial los recursos, a los que acceden simultáneamente múltiples plataformas, aplicaciones, sistemas de informes y dispositivos, y por lo tanto no funcionan tan bien cuando se diseñan con un enfoque en cualquier biblioteca o marco en particular. Además, las bases de datos diseñadas para trabajar con conjuntos de herramientas específicos se convierten en una responsabilidad cuando se introduce el próximo gran conjunto de herramientas.

Tiendo a caer del lado de las teclas naturales (obviamente), pero no soy fanático al respecto. Debido al entorno en el que trabajo, donde ayudo a cualquier base de datos el diseño puede ser utilizado por una variedad de aplicaciones, utilizo claves naturales para la mayoría del modelado de datos, y rara vez introduzco sustitutos. Sin embargo, no me esfuerzo por intentar volver a implementar las bases de datos existentes que utilizan sustitutos. Los sistemas Subrogate-key funcionan bien, sin necesidad de cambiar algo que ya está funcionando bien.

Hay algunos recursos excelentes discutiendo los méritos de cada uno enfoque:

Http://www.google.com/search?q=natural + clave+sustituto + clave

Http://www.agiledata.org/essays/keys.html

Http://www.informationweek.com/news/software/bi/201806814

 85
Author: JeremyDWill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-30 18:59:12

He estado desarrollando aplicaciones de base de datos durante 15 años y aún no he encontrado un caso en el que una clave no sustitutiva fuera una mejor opción que una clave sustitutiva.

No estoy diciendo que tal caso no exista, solo estoy diciendo que cuando se tienen en cuenta los problemas prácticos de desarrollar realmente una aplicación que accede a la base de datos, generalmente los beneficios de una clave sustituta comienzan a abrumar la pureza teórica de las claves no sustitutas.

 31
Author: Darrel Miller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-01 19:05:54

La clave primaria debe ser constante y sin sentido ; las claves no sustitutivas generalmente fallan uno o ambos requisitos, eventualmente

  • Si la clave no es constante, tiene un problema de actualización futura que puede ser bastante complicado

  • Si la clave no carece de sentido, entonces es más probable que cambie, es decir, que no sea constante; véase más arriba

Tomemos un ejemplo simple y común: una tabla de artículos de inventario. Puede ser tentador hacer el número de artículo (sku número, código de barras, código de parte, o lo que sea) la clave principal, pero luego un año después todos los números de artículo cambian y te quedas con un problema muy desordenado de actualización de toda la base de datos...

EDITAR: hay un tema adicional que es más práctico que filosófico. En muchos casos vas a encontrar una fila en particular de alguna manera, luego actualizarla o encontrarla de nuevo (o ambas). Con las claves compuestas hay más datos para realizar un seguimiento y más contraindicaciones en la cláusula WHERE para el re-find o actualizar (o eliminar). ¡También es posible que uno de los segmentos clave haya cambiado mientras tanto!. Con una clave sustituta, siempre hay un solo valor que retener (el ID sustituto) y, por definición, no puede cambiar, lo que simplifica significativamente la situación.

 20
Author: Steven A. Lowe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-05 15:52:27

Suena como si la persona que creó la base de datos estuviera en el lado de las claves naturales del gran debate de claves naturales vs.claves sustitutas.

Nunca he oído hablar de ningún problema con btres en los campos de ID, pero tampoco lo he estudiado en gran profundidad...

Caigo en el lado de la clave sustituta: Tiene menos repetición cuando usa una clave sustituta, porque solo está repitiendo un solo valor en las otras tablas. Dado que los humanos rara vez se unen a las mesas a mano, no nos importa si es un número o no. Además, dado que solo hay una columna de tamaño fijo para buscar en el índice, es seguro asumir que los sustitutos también tienen un tiempo de búsqueda más rápido por clave primaria.

 11
Author: Powerlord,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-01 18:53:37

El uso de campos 'unique (object) ID' simplifica las uniones, pero debe intentar que la otra clave (posiblemente compuesta) siga siendo única NOT NO relaje las restricciones no nulas y mantenga la restricción única.

Si el DBMS no puede manejar enteros únicos de manera efectiva, tiene grandes problemas. Sin embargo, usar tanto un 'ID único (objeto)' como la otra clave usa más espacio (para los índices) que solo la otra clave, y tiene dos índices para actualizar en cada operación de inserción. Así que no es un gratis but pero mientras mantengas la llave original, también, estarás bien. Si elimina la otra clave, está rompiendo el diseño de su sistema; todo el infierno se desatará eventualmente (y puede o no detectar que el infierno se desató).

 5
Author: Jonathan Leffler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-01 18:46:05

Básicamente soy miembro del equipo de subrogate key, e incluso si aprecio y entiendo argumentos como los presentados aquí por JeremyDWill, todavía estoy buscando el caso donde la clave "natural" es mejor que la subrogada ...

Otras publicaciones que tratan este tema generalmente se refieren a la teoría de bases de datos relacionales y el rendimiento de las bases de datos. Otro argumento interesante, siempre olvidado en este caso, está relacionado con normalización de tablas y productividad de código:

Cada vez que cree una tabla, perder tiempo

  1. identificando su clave primaria y su características físicas (tipo, tamaño)
  2. recordar estas características cada vez que quiero hacer referencia a ella en mi código?
  3. explicando mi elección PK a otros desarrolladores en el equipo?

Mi respuesta es no a todas estas preguntas:

  1. No tengo tiempo que perder tratando de identificar "la mejor Clave Primaria" cuando tratar con una lista de persona.
  2. No quiero recordar que la Clave primaria de mi tabla" computer" es una cadena larga de 64 caracteres (hace Windows acepta que muchos caracteres ¿por un nombre de computadora?).
  3. No quiero explicar mi elección a otros desarrolladores, donde uno de ellos finalmente dirá " Sí hombre, pero tenga en cuenta que usted tiene que manejar computadoras en diferentes dominios? Permite esta cadena de 64 caracteres almacenar el nombre de dominio + el ¿nombre de la computadora?".

Así que he estado trabajando durante los últimos cinco años con una regla muy básica: cada tabla (llamémosla 'myTable') tiene su primer campo llamado 'id_MyTable' que es de tipo uniqueIdentifier. Incluso si esta tabla soporta una relación "muchos-a-muchos", como una tabla 'ComputerUser', donde la combinación de 'id_Computer' y 'id_User' forma una Clave Primaria muy aceptable, prefiero crear este campo 'id_ComputerUser' siendo un uniqueIdentifier, solo para atenerme a la regla.

La principal ventaja es que no tiene que preocuparse por el uso de animore Clave Principal y / o Clave Externa dentro de su código. Una vez que tenga el nombre de la tabla, sabrá el nombre y tipo de PK. Una vez que sepa qué enlaces se implementan en su modelo de datos, sabrá el nombre de las claves foráneas disponibles en la tabla.

No estoy seguro de que mi regla sea la mejor. Pero es muy eficiente!

 5
Author: Philippe Grondier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-29 17:55:51

Usar teclas naturales hace una pesadilla usando cualquier automatic automático como capa de persistencia. Además, las claves foráneas en varias columnas tienden a superponerse entre sí y esto dará más problemas al navegar y actualizar la relación de una manera OO.

Aún así, podría transformar la clave natural en una restricción única y agregar un id generado automáticamente; esto no elimina el problema con las claves foráneas, sin embargo, tendrán que cambiarse a mano; esperemos que varias columnas y las restricciones superpuestas serán una minoría de toda la relación, por lo que podría concentrarse en refactorizar donde más importa.

Pk natural tienen su motivación y usos escenario y no son una mala cosa(tm), simplemente tienden a no llevarse bien con OR.

Mi sensación es que, como cualquier otro concepto, las claves naturales y la normalización de la tabla deben usarse cuando sean sensatas y no como restricciones de diseño ciegas

 3
Author: Lorenzo Boccaccia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-01 18:55:51

Voy a ser breve y dulce aquí: las claves primarias compuestas no son buenas en estos días. Agregue claves arbitrarias sustitutas si puede y mantenga los esquemas de claves actuales a través de restricciones únicas. OR es feliz, tú eres feliz, programador original no tan feliz, pero a menos que sea tu jefe, entonces puede lidiar con ello.

 3
Author: MattC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-01 19:29:18

Un enfoque práctico para desarrollar una nueva arquitectura es el que utiliza claves sustitutas para tablas que contendrán miles de registros de varias columnas altamente únicos y claves compuestas para tablas descriptivas cortas. Por lo general, encuentro que las universidades dictan el uso de claves sustitutas, mientras que los programadores del mundo real prefieren las claves compuestas. Realmente necesita aplicar el tipo correcto de clave primaria a la tabla, no solo de una manera u otra.

 3
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-21 20:33:13

Las claves compuestas pueden ser buenas - pueden afectar el rendimiento - pero no son la única respuesta, de la misma manera que una clave única (sustituta) no es la única respuesta.

Lo que me preocupa es la vaguedad en el razonamiento para elegir claves compuestas. La mayoría de las veces, la vaguedad sobre algo técnico indica una falta de comprensión, tal vez siguiendo las pautas de otra persona, en un libro o artículo....

No hay nada malo con un único ID único-de hecho si tienes una aplicación conectada a un servidor de base de datos y puedes elegir qué base de datos estás usando, todo será bueno, y puedes hacer prácticamente cualquier cosa con tus claves y no sufrir demasiado.

Se ha escrito y se escribirá mucho sobre esto, porque no hay una sola respuesta. Hay métodos y enfoques que deben aplicarse cuidadosamente y de manera experta.

He tenido muchos problemas con los identificadores proporcionados automáticamente por la base de datos, y evítelos siempre que sea posible, pero utilícelos de vez en cuando.

 2
Author: Richard Harrison,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-01 19:22:09

... cómo la base de datos maneja los campos de identificación de una manera no eficiente y cuando está construyendo índices, las clases de árbol son defectuosas ...

Esto fue casi sin duda una tontería, pero puede estar relacionado con el problema de la contención de bloques de índice al asignar números incrementales a un PK a una tasa alta desde diferentes sesiones. Si es así, entonces el índice DE CLAVE INVERSA está ahí para ayudar, aunque a expensas de un tamaño de índice más grande debido a un cambio en el algoritmo de división de bloques. http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/schema.htm#sthref998

Ir sintético, sobre todo si ayuda a un desarrollo más rápido con su conjunto de herramientas.

 2
Author: David Aldridge,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-01 20:09:46

No soy un experimentado, pero todavía estoy a favor de Usar la clave primaria como id aquí está la explicación usando un ejemplo..

El formato de los datos externos puede cambiar con el tiempo. Por ejemplo, podría pensar que el ISBN de un libro sería una buena clave primaria en una tabla de libros. Después de todo, los ISBN son únicos. Pero a medida que se escribe este libro en particular, la industria editorial en los Estados Unidos se está preparando para un cambio importante a medida que se agregan dígitos adicionales a todos los ISBN. Si lo hiciéramos utiliza el ISBN como la clave principal en una tabla de libros, tendríamos que actualizar cada fila para reflejar este cambio. Pero entonces tendríamos otro problema. Habrá otras tablas en la base de datos que hacen referencia a filas en la tabla books a través de la clave primaria. No podemos cambiar la clave en la tabla books a menos que primero revisemos y actualicemos todas estas referencias. Y eso implicará eliminar las restricciones de clave externa, actualizar las tablas, actualizar la tabla de libros y, finalmente, restablecer las restricciones. Todo en general, esto es una especie de dolor. Los problemas desaparecen si usamos nuestro propio valor interno como clave principal. Ningún tercero puede venir y decirnos arbitrariamente que cambiemos nuestro esquema: controlamos nuestro propio espacio de claves. Y si algo como el ISBN necesita cambiar, puede cambiar sin afectar ninguna de las relaciones existentes en la base de datos. En efecto, hemos desacoplado el tejido de las filas de la representación externa de los datos en esas filas.

Aunque el la explicación es bastante libresca, pero creo que explica las cosas de una manera más simple.

 2
Author: Mohit Jain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-21 07:06:47

@ JeremyDWill

Gracias por proporcionar un equilibrio tan necesario al debate. En particular, gracias por la información sobre DOMAIN s.

En realidad uso claves sustitutas en todo el sistema en aras de la consistencia, pero hay compensaciones involucradas. La causa más común para mí para maldecir el uso de claves sustitutas es cuando tengo una tabla de búsqueda con una lista corta de valores canónicos-Usaría menos espacio y todas mis consultas serían más cortas / más fáciles / más rápidas si hubiera hecho los valores el PK en lugar de tener que unirse a la mesa.

 1
Author: Hank Gay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-02 08:42:11

Puede hacer ambas cosas - dado que cualquier base de datos de grandes empresas es probable que sea utilizada por varias aplicaciones, incluidos los DBA humanos que ejecutan consultas únicas e importaciones de datos, diseñarla puramente para el beneficio de los sistemas OR no siempre es práctico o deseable.

Lo que tiendo a hacer en estos días es agregar una propiedad "RowID" a cada tabla - este campo es un GUID, y tan único para cada fila. Esta NO es la clave principal, es una clave natural (si es posible). Sin embargo, cualquier capa OR trabajando sobre esta base de datos puede usar el RowID para identificar sus objetos derivados.

Así que usted podría tener:

CREATE TABLE dbo.Invoice (
  CustomerId varchar(10),
  CustomerOrderNo varchar(10),
  InvoiceAmount money not null,
  Comments nvarchar(4000),
  RowId uniqueidentifier not null default(newid()),

  primary key(CustomerId, CustomerOrderNo)
)

Así que su DBA está feliz, su arquitecto OR está feliz, y la integridad de su base de datos se conserva!

 1
Author: Keith Williams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-24 15:03:11

Solo quería agregar algo aquí que nunca veo cubierto cuando se discuten los campos de identidad enteros generados automáticamente con bases de datos relacionales (porque los veo mucho), y es decir, su tipo base puede un desbordamiento de voluntad en algún momento.

Ahora no estoy tratando de decir que esto automáticamente hace que los ID compuestos sean el camino a seguir, pero es solo una cuestión de hecho que a pesar de que se podrían agregar más datos lógicamente a una tabla (que sigue siendo única), la única identidad entera generada automáticamente podría evitar que esto suceda.

Sí, me doy cuenta de que para la mayoría de las situaciones es poco probable, y el uso de un entero de 64 bits le da un montón de espacio libre, y siendo realistas, la base de datos probablemente debería haber sido diseñado de manera diferente si alguna vez se produjo un desbordamiento como este.

Pero eso no impide que alguien lo haga... una tabla que utiliza un único entero de 32 bits generado automáticamente como identidad, que se espera que almacene todas las transacciones a nivel global para una comida rápida en particular compañía, va a fallar tan pronto como intenta insertar es 2,147,483,648 th transacción (y que es un escenario completamente factible).

Es solo algo a tener en cuenta, que la gente tiende a pasar por alto o simplemente ignorar por completo. Si alguna tabla se va a insertar con regularidad, se deben tener en cuenta la frecuencia y la cantidad de datos que se acumularán con el tiempo, y si se debe usar o no un identificador basado en enteros.

 0
Author: Xorcist,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-08 15:52:05