¿Debería una clave primaria ser inmutable?

26

Una pregunta reciente sobre stackoverflow provocó una discusión sobre la inmutabilidad de las claves primarias. Pensé que era una especie de regla que las claves primarias deberían ser inmutables. Si existe la posibilidad de que algún día se actualice una clave principal, pensé que debería usar una clave sustituta. Sin embargo, no está en el estándar SQL y algunas características de "actualización en cascada" de RDBMS permiten cambiar una clave principal.

Entonces mi pregunta es: ¿sigue siendo una mala práctica tener una clave primaria que pueda cambiar? ¿Cuáles son las desventajas, si las hay, de tener una clave primaria mutable?

Vincent Malgrat
fuente

Respuestas:

25

Solo necesita que la clave primaria sea inmutable si está vinculada a una clave externa, o si se usa como un identificador fuera de la base de datos (por ejemplo, en una URL que apunta a una página para el elemento).

Por otro lado, solo necesita tener una clave mutable si contiene alguna información que pueda cambiar. Siempre uso una clave sustituta si el registro no tiene un identificador simple e inmutable que pueda usarse como clave.

Guffa
fuente
77
¿Por qué " necesita que la clave primaria sea inmutable si está vinculada a una clave externa"? Como mencionó el OP, la mayoría de los RDBMS tienen la función de actualización "en cascada".
Thanatos
1
@Thanatos la mayoría (de hecho, todo lo que he encontrado) rdbms no permitirá que las claves primarias mutables aún tengan actualizaciones en cascada. Una clave primaria, en la sabiduría de dba generalmente aceptada, no debe contener información, ser solo un identificador de registro único (por lo que ni siquiera una marca de tiempo, rango de registro diferido, etc.).
Jwenting
55
@jwenting: ¿Estamos hablando de lo mismo? "la mayoría de los rdbms no permitirán claves primarias mutables" ¿qué incluye? MySQL y PostgreSQL permiten claves primarias mutables y respetan las actualizaciones en cascada ... como creo que SQL estándar dice que deberían. Además, "la sabiduría dba generalmente aceptada" He conocido a muchos DBA que argumentan en contra de las claves sustitutas, y muchos que argumentan en contra de las claves naturales.
Thanatos
2
@Thanatos Los argumentos a favor de "todas las tablas deben tener un sustituto" carecen de referencias bibliográficas, citan "sabiduría de dba generalmente aceptada" pero nunca citan un libro. Los libros canónicos dicen que debe usar un sustituto si: A. no existe una clave natural, B. la clave de varias columnas excede las 3 columnas, o, C. Cambiará la clave todo el tiempo. Entonces: natural cuando encajan, sustitutos cuando los naturales no encajan.
Tulains Córdova
44
@ user61852: ¿Qué?
Guffa
15

Una clave primaria debe estar compuesta por las tuplas necesarias para determinar la unicidad. Si los datos pueden cambiar o no es irrelevante. Solo importa la unicidad del registro. Ese es el diseño conceptual de la base de datos.

Cuando pasamos al ámbito de la implementación, lo más seguro es simplemente usar una clave sustituta.

Chris Holmes
fuente
15

Sí, en mi opinión, una clave principal debería ser inmutable.

Incluso si hay claves candidatas obvias, siempre uso una clave sustituta. En las pocas ocasiones en que no he hecho esto, casi siempre me arrepiento. Y no importa cuán inmutable creas que es la clave, no puedes protegerte contra los errores de entrada de datos: decirles a los usuarios que no pueden editar esa parte de información porque es una clave principal que no se lava tristemente.

richeym
fuente
Buen punto sobre los errores de entrada de datos
Tim Goodman
richeym, parece que está argumentando por qué las claves NO deben ser inmutables: los usuarios pueden querer cambiarlas.
nvogel
44
@dportas: mi punto es que me gusta que las PK sean inmutables, así que siempre use claves sustitutas, incluso si creo que hay una clave obvia que se puede derivar de los datos de la tabla (por ejemplo, correo electrónico, nombre de usuario).
richeym
2

Los mecanismos de almacenamiento en caché entre la base de datos y el usuario perderán efectividad si cambian las claves principales.

Spoulson
fuente
2

Por qué no? ¿Porque quieres eliminar una columna?

El hecho de que los requisitos exijan que tres columnas sean únicas no significa que tenga que ser la clave principal. Puedes pensar que esa regla durará para siempre (¿Recuerdas durante esa reunión cuando el gerente del departamento de pinhead juró que eso nunca cambiaría? Ya sabes, la que acaba de ser despedida), pero no lo hará.

No me pagan por cada actualización en cascada que implemento y un bono si lo codifico yo mismo.

La computadora no requiere ningún significado para una clave; En mi humilde opinión, las claves son para computadoras, deja que la gente arruine el resto de los datos.

JeffO
fuente
1
"las claves son para computadoras, deja que la gente arruine el resto de los datos". +1, bien.
2

No es una mala práctica tener una clave cuyos valores pueden cambiar.

Las propiedades de una buena clave incluyen la estabilidad. La inmutabilidad es ideal pero no un requisito previo. Introducir una clave artificial en aras de la inmutabilidad es una mala práctica.

Tome el ejemplo del Número internacional estándar de libros (ISBN) . Es muy estable pero no inmutable: a veces los editores de libros cometen errores y ¡horror! - Se pueden producir números de ISBN duplicados. ¿Esto significa que el ISBN no debe aceptarse como una clave candidata en una base de datos computarizada? Por supuesto no. Una de las ventajas de ISBN es que tiene una fuente confiable que resolverá los problemas de todos los usuarios a nivel mundial.

Hay otras propiedades de una buena clave que tiene el ISBN que una clave entera de incremento automático sin sentido carecerá, por ejemplo, de familiaridad (todos en el comercio del libro conocen o están familiarizados con el ISBN), verificable (el ISBN está impreso en todos los libros modernos), puede ser validado con referencia al DBMS (ISBN es de ancho fijo e incluye una suma de verificación), etc.

un día cuando
fuente
3
ISBN tiene un ancho fijo, excepto cuando no lo es (ver ISBN-10 vs ISBN-13).
un CVn
Entonces, ¿cómo recomendaría manejar ISBN duplicados? En todos los RDBMS que conozco, tendrías que tener una restricción ÚNICA en el campo para usarlo como clave principal.
Comodín el
1

Todo lo que posiblemente sea inmutable debería serlo. Ayuda a garantizar la corrección y ayuda cuando desea que su aplicación sea multiproceso.

dash-tom-bang
fuente
1

Sí, una clave primaria debe ser inmutable, además de ser no nula y única. Sin embargo, todavía tengo que encontrar una base de datos que imponga la inmutabilidad de las claves primarias, por lo que probablemente pueda seguir adelante y cambiar sus valores si realmente lo desea.

Bob Jarvis - Restablece a Monica
fuente
0

Como algunos comentarios ya lo dijeron, una solución es usar una nueva clave primaria

Por ejemplo (siguiendo el ejemplo de @onedaywhen), digamos que existe la tabla Libros que almacena una lista de libros y que "usamos" para determinar el ISBN como clave principal. Sin embargo, algunos autores cometieron el error de escribir un ISBN incorrecto, por lo que solicitaron cambiar el ISBN, que implicaba las siguientes tareas:

  • crear un nuevo registro en la tabla Libros
  • señale todas las referencias del antiguo ISBN al nuevo ISBN. (*)
  • Y finalmente, elimine el registro anterior de la tabla Libros.

(*) esto podría ser trivial para encontrar todas las referencias para un modelo de base de datos que usa claves externas pero algunos modelos carecen de él.

Table Books
ISBN  is the primary key
NAME is a simple field.
etc.

Lo cambiamos como

Table Books
InternalBookId as the primary key
ISBN as a simple field or an indexed field.
NAME is a simple field.
etc.

Donde el nuevo InternalBookId podría incluso ser un valor autonumérico.

Los contras al respecto:

  • agrega un nuevo campo que usa más espacio / recurso.

  • podría requerir reescribir todo el modelo.

  • El nuevo modelo podría explicarse menos por sí mismo.

El PRO

  • Permite mutar la "clave primaria".
  • Permite incluso descartar o refactorizar la "clave principal", por ejemplo, cambiar Libros a ISBN-13 es tan simple como descartar la columna anterior y crear una nueva

Nueva mesa:

Table Books
InternalBookId as the primary key
ISBN13 is a new field.
NAME is a simple field.
etc.
magallanes
fuente