¿Clave primaria o índice único?

127

En el trabajo tenemos una gran base de datos con índices únicos en lugar de claves primarias y todo funciona bien.

Estoy diseñando una nueva base de datos para un nuevo proyecto y tengo un dilema:

En la teoría DB, la clave primaria es un elemento fundamental, está bien, pero en proyectos REALES, ¿cuáles son las ventajas y desventajas de ambos?

¿Qué utilizas en proyectos?

EDITAR: ... y ¿qué pasa con las claves principales y la replicación en el servidor MS SQL?

Cicik
fuente
2
Hay algunas consideraciones adicionales discutidas aquí (aunque con el contexto adicional de un índice de cobertura) - dba.stackexchange.com/questions/21554/…
StuartLC
NOTA: SQLite es diferente porque permiten que la clave primaria sea nula, en comparación con el estándar común debido a un problema heredado. sqlite.org/lang_createtable.html
bitinn

Respuestas:

168

¿Qué es un índice único?

Un índice único en una columna es un índice en esa columna que también impone la restricción de que no puede tener dos valores iguales en esa columna en dos filas diferentes. Ejemplo:

CREATE TABLE table1 (foo int, bar int);
CREAR ÍNDICE ÚNICO ux_table1_foo EN la tabla1 (foo); - Crear un índice único en foo.

INSERTE EN LA TABLA 1 (foo, bar) VALORES (1, 2); -- OKAY
INSERTE EN LA TABLA 1 (foo, bar) VALORES (2, 2); -- OKAY
INSERTE EN LA TABLA 1 (foo, bar) VALORES (3, 1); -- OKAY
INSERTE EN LA TABLA 1 (foo, bar) VALORES (1, 4); - ¡Falla!

Entrada duplicada '1' para la clave 'ux_table1_foo'

La última inserción falla porque viola el índice único en la columna foocuando intenta insertar el valor 1 en esta columna por segunda vez.

En MySQL, una restricción única permite múltiples NULL.

Es posible hacer un índice único en varias columnas.

Clave primaria versus índice único

Cosas que son iguales:

  • Una clave primaria implica un índice único.

Cosas que son diferentes:

  • Una clave primaria también implica NO NULL, pero un índice único puede ser anulable.
  • Solo puede haber una clave principal, pero puede haber múltiples índices únicos.
  • Si no hay un índice agrupado definido, la clave principal será el índice agrupado.
Mark Byers
fuente
44
Tenga en cuenta que un índice único es un índice en una columna que no es del todo exacto, ya que un índice único o clave principal puede incluir más de una columna.
Alex Jasmin
2
@Alexandre Jasmin: reparado gracias. La parte sobre columnas múltiples se menciona más adelante.
Mark Byers
Con referencia a los valores nulos, los estándares ansi permiten múltiples valores nulos en un conjunto de datos con una restricción única, y esa es también la implementación en Oracle y PostgreSQL. Sin embargo, creo que SQL Server solo permite un valor nulo.
David Aldridge
3
pero aún así no lo entendí, como cuándo usar la clave primaria o cuándo usar un índice único. o puede ser a la vez en las mismas situaciones.
Amit
33

Puedes verlo así:

Una clave primaria es única

Un valor único no tiene que ser la representación del elemento

¿Sentido?; Bueno, se usa una clave principal para identificar el elemento, si tiene una "Persona", le gustaría tener un Número de Identificación Personal (SSN o tal) que sea Primario para su Persona.

Por otro lado, la persona puede tener un correo electrónico que es único, pero no identifica a la persona.

Siempre tengo claves primarias, incluso en las tablas de relaciones (la tabla media / tabla de conexión) podría tenerlas. ¿Por qué? Bueno, me gusta seguir un estándar al codificar, si la "Persona" tiene un identificador, el Coche tiene un identificador, bueno, ¡la Persona -> Coche también debería tener un identificador!

Filip Ekberg
fuente
En sus tablas de relaciones: ¿quiere decir que introduce una nueva columna con una clave primaria artificial (un número entero, por ejemplo) o utiliza una clave primaria compuesta (person_id, car_id)?
3
La clave primaria (person_id, car_id) sería la mejor. Pero, en general, creo una nueva columna, seguro que proporciona algo de sobrecarga, pero he considerado que es buena. Nunca se sabe si desea relacionarse con una relación específica en un escenario posterior.
Filip Ekberg
1
La otra cosa que hace la clave primaria sustituta para su tabla compuesta / de unión es facilitar el mantenimiento de las tareas manuales.
Robert C. Barth
2
Solo necesita una clave principal si va a tener hijos. ¿Por qué agregar una columna y una secuencia si el valor no aparece en ninguna parte, si el valor no se utiliza para nada? Es hacer un trabajo para evitar que Access solicite una PK. Haga un PK si necesita identificar el registro en un niño, de lo contrario es un desperdicio.
3
Si no tiene nada que ver con las relaciones, ¿con qué tiene que ver? Señalas un campo y dices, eso es primario. ¿Y? Entonces que pasa? Y si no hay un paquete natural, agrego una columna y una secuencia y un disparador y todo porque ____? Algunos solo necesitan ser primarios. Evito las reglas sin razones.
10

Las claves foráneas funcionan con restricciones únicas, así como las claves primarias. De libros en línea:

Una restricción FOREIGN KEY no tiene que estar vinculada solo a una restricción PRIMARY KEY en otra tabla; también se puede definir para hacer referencia a las columnas de una restricción ÚNICA en otra tabla

Para la replicación transaccional, necesita la clave primaria. De libros en línea:

Las tablas publicadas para la replicación transaccional deben tener una clave primaria. Si una tabla está en una publicación de replicación transaccional, no puede deshabilitar ningún índice asociado con columnas de clave principal. Estos índices son necesarios para la replicación. Para deshabilitar un índice, primero debe descartar la tabla de la publicación.

Ambas respuestas son para SQL Server 2005.

Jonas Lincoln
fuente
ESO me asusta muchísimo (primera cita). ¿Por qué? Tengo una tabla de persona con una ID arbitraria que es mi PK, pero decido agregar un Reino Unido al teléfono, correo electrónico y número de seguro social ... ¿entonces ahora 4 tablas diferentes se unen a la persona en 4 columnas diferentes? Creo que renunciaría a cualquier flexibilidad que pueda obtener por coherencia.
5

La elección de cuándo usar una clave primaria sustituta en lugar de una clave natural es complicada. Respuestas como, siempre o nunca, rara vez son útiles. Me parece que depende de la situación.

Como ejemplo, tengo las siguientes tablas:

CREATE TABLE toll_booths (
    id            INTEGER       NOT NULL PRIMARY KEY,
    name          VARCHAR(255)  NOT NULL,
    ...
    UNIQUE(name)
)

CREATE TABLE cars (
    vin           VARCHAR(17)   NOT NULL PRIMARY KEY,
    license_plate VARCHAR(10)   NOT NULL,
    ...
    UNIQUE(license_plate)
)

CREATE TABLE drive_through (
    id            INTEGER       NOT NULL PRIMARY KEY,
    toll_booth_id INTEGER       NOT NULL REFERENCES toll_booths(id),
    vin           VARCHAR(17)   NOT NULL REFERENCES cars(vin),
    at            TIMESTAMP     DEFAULT CURRENT_TIMESTAMP NOT NULL,
    amount        NUMERIC(10,4) NOT NULL,
    ...
    UNIQUE(toll_booth_id, vin)
)

Tenemos dos tablas de entidades ( toll_boothsy cars) y una tabla de transacciones ( drive_through). La toll_boothtabla utiliza una clave sustituta porque no tiene ningún atributo natural que no se garantiza que cambie (el nombre se puede cambiar fácilmente). La carstabla usa una clave primaria natural porque tiene un identificador único que no cambia ( vin). La drive_throughtabla de transacciones utiliza una clave sustituta para una fácil identificación, pero también tiene una restricción única sobre los atributos que se garantiza que son únicos en el momento en que se inserta el registro.

http://database-programmer.blogspot.com tiene algunos excelentes artículos sobre este tema en particular.

aekeus
fuente
4

No hay desventajas de las claves primarias.

Para agregar solo algo de información a las respuestas de @MrWiggles y @Peter Parker, cuando la tabla no tiene clave principal, por ejemplo, no podrá editar datos en algunas aplicaciones (terminarán diciendo que algo así no puede editar / eliminar datos sin Clave primaria). Postgresql permite que múltiples valores NULL estén en una columna ÚNICA, PRIMARY KEY no permite NULLs. Además, algunos ORM que generan código pueden tener algunos problemas con las tablas sin claves principales.

ACTUALIZAR:

Hasta donde sé, no es posible replicar tablas sin claves primarias en MSSQL, al menos sin problemas ( detalles ).

empi
fuente
Hay una sobrecarga cuando se insertan nuevas filas o se actualiza esa columna.
3

Si algo es una clave primaria, dependiendo de su motor de base de datos, toda la tabla se ordena por la clave primaria. Esto significa que las búsquedas son mucho más rápidas en la clave primaria porque no tiene que hacer ninguna desreferenciación, ya que tiene que ver con cualquier otro tipo de índice. Además de eso, es solo teoría.

Ray Hidayat
fuente
3
la tabla se ordenará por el índice agrupado, no necesariamente por la clave primaria.
Ray Booysen
1
Sucede que la mayoría de las personas configuran su clave principal como el índice agrupado.
Ray Booysen
Lo que sabemos es a menudo una idea realmente mala, a menos que nos gusten los puntos calientes y los árboles de índice desequilibrados en nuestras tablas, por supuesto ...
Mike Woodhouse
1
No siempre es una idea realmente mala. Conozca sus datos, conozca su RDBMS, sepa qué significan las opciones. Rara vez es la elección SIEMPRE buena o mala. Si SIEMPRE fue uno, la base de datos lo obligaría o no. Te dan la opción porque 'Depende'.
2

Además de lo que han dicho las otras respuestas, algunas bases de datos y sistemas pueden requerir una presencia primaria. Me viene a la mente una situación; Cuando se utiliza la replicación empresarial con Informix, debe haber una PK para que una tabla participe en la replicación.

tddmonkey
fuente
2

Siempre que no permita NULL para un valor, deben manejarse de la misma manera, pero el valor NULL se maneja de manera diferente en las bases de datos (AFAIK MS-SQL no permite más de un (1) valor NULL, mySQL y Oracle lo permiten , si una columna es ÚNICA) Por lo tanto, debe definir esta columna NO NULO ÍNDICE ÚNICO

Peter Parker
fuente
1
MS-SQL permite múltiples valores NULL en una columna que tiene un índice único, como debería hacerlo cada RDBMS. Piénselo de esta manera: NULL no es un valor, por lo que cuando inserta un segundo NULL, nunca coincidirá con uno existente. La expresión (NULL == NULL) no se evalúa como verdadera o falsa, sino que se evalúa como NULL.
gregmac
Gracias Gregmac, no estaba seguro, si MS sigue esto. Recordé algunos EM Peculiaridades con esto, sin embargo, hace unos años (pre 2000) y también podría ser un viejo acceso DB- tos
Peter Parker
2

No existe una clave principal en la teoría de datos relacionales, por lo que su pregunta debe responderse a nivel práctico.

Los índices únicos no son parte del estándar SQL. La implementación particular de un DBMS determinará cuáles son las consecuencias de declarar un índice único.

En Oracle, declarar una clave primaria dará como resultado la creación de un índice único en su nombre, por lo que la pregunta es casi discutible. No puedo contarte sobre otros productos DBMS.

Estoy a favor de declarar una clave primaria. Esto tiene el efecto de prohibir NULL en la (s) columna (s) clave (s), así como prohibir duplicados. También estoy a favor de declarar restricciones de REFERENCIAS para hacer cumplir la integridad de la entidad. En muchos casos, declarar un índice sobre las coulmn (s) de una clave extranjera acelerará las uniones. Este tipo de índice en general no debe ser único.

Walter Mitty
fuente
Una clave principal en MS SQL Server siempre es ÚNICA y NO NULA, por ejemplo, es realmente un índice único, pero con la restricción añadida de que no puede ser NULL.
marc_s
Oracle puede aplicar una restricción única con un índice no único. Me sorprendería si MSSS no pudiera. Decir "es realmente solo un índice único" es un mal servicio.
"En muchos casos, declarar un índice sobre las coulmn (s) de una clave extranjera acelerará las uniones". Esto casi siempre no es cierto en un mundo de almacenamiento de datos donde se preferirían las combinaciones hash si estuvieran disponibles.
JAC2703
El OP no mencionó los almacenes. No estoy seguro de cómo funcionan los lomos hash en el servidor sql. Cuánto del trabajo se puede hacer en el momento de la actualización del almacén.
Walter Mitty
2

Hay algunas desventajas de los ÍNDICES AGRUPADOS frente a los ÍNDICES ÚNICOS.

Como ya se dijo, un ÍNDICE CLUSTERADO ordena físicamente los datos en la tabla.

Esto significa que cuando tiene mucho si inserta o elimina en una tabla que contiene un índice agrupado, cada vez (bueno, casi, dependiendo de su factor de relleno) cambia los datos, la tabla física debe actualizarse para mantenerse ordenada.

En tablas relativamente pequeñas, esto está bien, pero al llegar a tablas que tienen el valor de GB de datos, y los insertadores / eliminaciones afectan la ordenación, se encontrará con problemas.

Nico Bester
fuente
¿Cuál es la ventaja, entonces? consultas ordenadas son más rápidas? ¿Es esto mejor para un caso de uso cuando escribe la mayoría de sus datos una vez (o rara vez) y los consulta todo el tiempo?
Buffalo
1

Casi nunca creo una tabla sin una clave primaria numérica. Si también hay una clave natural que debería ser única, también le pongo un índice único. Las uniones son más rápidas en enteros que las claves naturales de varias columnas, los datos solo necesitan cambiar en un lugar (las claves naturales tienden a actualizarse, lo que es malo cuando está en la clave primaria: relaciones de clave externa). Si va a necesitar replicación, use un GUID en lugar de un número entero, pero en su mayor parte prefiero una clave que pueda leer el usuario, especialmente si necesitan verla para distinguir entre John Smith y John Smith.

Las pocas veces que no creo una clave sustituta es cuando tengo una tabla de unión que está involucrada en una relación de muchos a muchos. En este caso, declaro ambos campos como la clave principal.

HLGEM
fuente
"Casi nunca creo una tabla sin una clave primaria numérica": ¿por qué siempre numérica? Una clave primaria no necesita ser numérica (ni debe ser AUTO_INCREMENT por cierto).
Hibou57
@ Hinou57, porque he descubierto que las claves naturales rara vez son realmente únicas y que casi siempre son cambiables. Las uniones adicionales en los números enteros son generalmente mucho más rápidas que las uniones en las claves naturales varcahrr o las claves compuestas peores. No los usaría la mayor parte del tiempo. Esto puede variar según el tipo de información que almacene en su base de datos, pero en mi experiencia personal he encontrado que las claves naturales son extremadamente poco confiables con el tiempo.
HLGEM
Gracias por la respuesta HLGEM. ¿Qué quieres decir con poco confiable? ¿Actuación? (Espero que no sea una cuestión de fiabilidad en el sentido de la integridad de los datos). Estoy un poco sorprendido por sus palabras, ya que aunque utilizo teclas enteras o teclas más naturales como VARCHAR corto, probablemente haga una pequeña diferencia ya que el hash se usa en todas partes, incluso con los motores DB más simples.
Hibou57
No son confiables en muchos casos porque no son confiables únicos a pesar de que se supone que son. No son confiables porque cambian y eso puede afectar millones de registros en una actualización. Esta es mi experiencia al haber visto y administrado o consultado datos o importado datos de cientos de bases de datos que almacenan datos sobre muchos tipos diferentes de información.
HLGEM
1

Tengo entendido que una clave primaria y un índice único con una restricción no nula son lo mismo (*); y supongo que uno elige uno u otro dependiendo de lo que la especificación explícitamente indique o implique (una cuestión de lo que desea expresar y hacer cumplir explícitamente). Si requiere unicidad y no nulo, conviértalo en una clave principal. Si sucede que todas las partes de un índice único no son nulas sin ningún requisito para ello, simplemente conviértalo en un índice único.

La única diferencia restante es que puede tener múltiples índices únicos no nulos, mientras que no puede tener múltiples claves primarias.

(*) Exceptuando una diferencia práctica: una clave primaria puede ser la clave única predeterminada para algunas operaciones, como definir una clave externa. Ex. si uno define una clave externa que hace referencia a una tabla y no proporciona el nombre de la columna, si la tabla referenciada tiene una clave primaria, entonces la clave principal será la columna referenciada. De lo contrario, la columna a la que se hará referencia deberá nombrarse explícitamente.

Otros aquí han mencionado la replicación de DB, pero no lo sé.

Hibou57
fuente
0

El índice único puede tener un valor NULL. Crea un índice no agrupado. La clave primaria no puede contener un valor NULL. Crea un índice agrupado.

Chirag
fuente
0

En MSSQL, las claves primarias deberían aumentar de forma monotónica para obtener el mejor rendimiento en el índice agrupado. Por lo tanto, un número entero con inserción de identidad es mejor que cualquier clave natural que podría no estar aumentando monotónicamente.

Markus
fuente
-1

Si fuera por mí...

Debe satisfacer los requisitos de la base de datos y de sus aplicaciones.

Agregar un entero de incremento automático o una columna de identificación larga a cada tabla para que sirva como clave principal se ocupa de los requisitos de la base de datos.

Luego agregaría al menos otro índice único a la tabla para que lo use su aplicación. Este sería el índice en employee_id, o account_id, o customer_id, etc. Si es posible, este índice no debería ser un índice compuesto.

Yo preferiría los índices en varios campos individualmente sobre los índices compuestos. La base de datos usará los índices de campo único siempre que la cláusula where incluya esos campos, pero solo usará un compuesto cuando proporcione los campos exactamente en el orden correcto, lo que significa que no puede usar el segundo campo en un índice compuesto a menos que proporcione tanto el primero como el segundo en su cláusula where.

Estoy a favor de usar índices calculados o de tipo Function, y recomendaría usarlos sobre índices compuestos. Hace que sea muy fácil usar el índice de función al usar la misma función en su cláusula where.

Esto se ocupa de los requisitos de su aplicación.

Es muy probable que otros índices no primarios sean, en realidad, asignaciones de los valores de clave de índices a un valor de clave primaria, no los de rowid (). Esto permite que se produzcan operaciones de ordenación física y eliminaciones sin tener que volver a crear estos índices.

Rodney P. Barbati
fuente