¿Debería cada tabla tener una clave primaria sustituta / artificial de campo único?


33

Entiendo un beneficio de las claves sustitutas / artificiales en general: no cambian y eso puede ser muy conveniente. Esto es cierto si son de campo único o múltiple, siempre que sean 'artificiales'.

Sin embargo, a veces parece ser una cuestión de política tener un campo entero de incremento automático como clave principal de cada tabla. ¿Es esta siempre la mejor idea tener una clave de campo único y por qué (o por qué no)?

Para ser claros, esta pregunta no se trata de artificial versus natural, sino de si todas las claves artificiales deben ser de campo único


Respuestas:


28

Voy a decir que no, no siempre, pero la mayoría de las veces sí. .

Estas son algunas circunstancias en las que no necesita un sustituto o una clave artificial:

  • Tablas de intersección puras . Si no hay riesgo de que la intersección sea el objetivo de una clave externa y si hay poco o ningún riesgo de que la intersección atraiga atributos independientes (es decir, algo diferente de FK a las dos tablas primarias), puede salirse con la suya usando la combinación de FK como PK con bastante confianza.
  • Tablas de búsqueda con claves comerciales estáticas . Si tiene una
    tabla de búsqueda con una clave comercial única que se fija externamente a su
    negocio y que tiene cero posibilidades de cambiar para cualquier
    propósito práctico, entonces usar la clave comercial directamente puede simplificar las
    cosas. Un ejemplo podría ser una lista de
    códigos de estado o provincia o una lista de números estándar ANSI, etc.
  • Tablas que contienen datos consolidados de múltiples fuentes independientes . Si su sistema tiene muchas fuentes de datos que deben agruparse en una sola tabla, por ejemplo, en la oficina central, a veces necesita una clave compuesta que incluya el valor de la clave del sistema de origen y un código que indique cuál era el sistema de origen.

También hay algunas situaciones en las que la clave sustituta de números enteros crecientes monotónicamente fieles no es ideal. Puede tener claves que sean sustitutos alfanuméricos. Estos podrían incluir:

  • Situaciones en las que necesita fusionar datos de múltiples fuentes independientes. Para evitar colisiones de teclas, puede usar GUID en lugar de teclas de IDENTIDAD.
  • Situaciones en las que se ve obligado a utilizar representaciones de teclas no numéricas. Digamos que tienes una base de datos de matrículas. Su clave podría ser el valor alfanumérico en lugar de un número puro.
  • Situaciones en las que algunos requisitos externos lo obligan a aplicar compresión a su valor clave. En lugar de usar 10 dígitos para un int32, puede usar seis dígitos de base 36.

¿Por qué la mayoría de las veces sí? La respuesta más fundamental a esa pregunta es que es un verdadero infierno si alguna vez necesita modificar un valor de clave primaria en cualquier tabla. Dado que casi cualquier cosa que un usuario pueda ver o tocar está posiblemente sujeto a una actualización en algún momento, el uso de un valor de clave visible es un verdadero infierno. Usar una llave sustituta evitará que caigas en esta trampa.

Dicho esto, recuerde que hay espacio para YAGNI en la aplicación de este concepto. No necesita forzar tablas de códigos con claves de IDENTIDAD en cada rincón de su esquema, en caso de que alguien decida que el símbolo del género masculino en su tabla de empleados debe cambiar de M a X o algo tonto.


"El uso de una clave sustituta evitará que caigas en esta trampa". La pregunta no se trata de sustitutos frente a naturales, sino de sustitutos de campo único frente a múltiples.
Jack Douglas

Como ha reconocido en un comentario a su propia respuesta, estamos en un territorio de "acuerdo en desacuerdo" cuando se trata de lo que es prudente en el diseño de la base de datos. Dada su edición, no habría hecho la distinción entre claves sustitutas y naturales, por lo que mi segundo punto está fuera de tema. Mis otros puntos con respecto a cuándo uno podría diferir del enfoque clásico de identidad / secuencia siguen en pie.
Joel Brown

No cambié la pregunta como se puede ver en la historia, solo agregué énfasis donde pensé que ayudaría a los lectores descremados
Jack Douglas

12

No.

Diría que ciertamente hay casos en que las claves de campo único son inferiores a las claves compuestas, al menos para el propósito de claves externas . Eso no quiere decir que no debería tener una clave sustituta de un solo campo también si lo prefiere, pero personalmente prefiero que la clave que se usa con más frecuencia como destino de una clave externa se llame clave primaria

Intentaré ilustrar mi punto en los siguientes ejemplos, en los que:

  • brand es la marca del automóvil, por ejemplo, Ford, Toyota, etc.
  • dealer es un concesionario físico, vinculado a una marca (por ejemplo, un concesionario Ford que solo vende Ford)
  • model es el tipo de automóvil, por ejemplo, Ford Focus, Ford Fiesta, etc.
  • stock es el recuento actual de automóviles en la explanada de cada concesionario

Si creamos una clave sustituta de campo único para dealery de la modelsiguiente manera:

create table brand( brand_id integer primary key );

create table dealer( dealer_id integer primary key, 
                     brand_id integer references brand )

create table model( model_id integer primary key, 
                    brand_id integer references brand )

create table stock( model_id integer references model, 
                    dealer_id integer references dealer, 
                    quantity integer,
                      primary key(model_id, dealer_id) )

entonces es posible insertar una fila stockque vincule un Ford dealercon un modelo "Toyota". Agregar brand_id references branda stocksolo empeora el problema. Por otro lado, si mantenemos la clave externa como parte de la clave primaria de la siguiente manera:

create table brand( brand_id integer primary key );

create table dealer( brand_id integer references brand, 
                     dealer_id integer, 
                       primary key(brand_id, dealer_id) )

create table model( brand_id integer references brand, 
                    model_id integer, 
                      primary key(brand_id, model_id) )

create table stock( brand_id integer, 
                    model_id integer, 
                    dealer_id integer, 
                    quantity integer,
                      primary key(brand_id, model_id, dealer_id),
                      foreign key(brand_id, model_id) references model,
                      foreign key(brand_id, dealer_id) references dealer )

ahora la regla de que los concesionarios "Ford" solo pueden almacenar autos "Ford" se aplica naturalmente por el modelo.

Tenga en cuenta que en el ejemplo de 'claves compuestas', dealer_idpuede o no ser único, de acuerdo con las preferencias. No necesita ser único (es decir, una clave alternativa), pero se pierde muy poco al hacerlo (tal vez un poco de espacio de almacenamiento) y puede ser muy útil, por lo que esa es la forma en que generalmente lo configuro, por ejemplo:

create table dealer( brand_id integer references brand, 
                     dealer_id serial unique, 
                       primary key(brand_id, dealer_id) )

3
Teniendo en cuenta las condiciones habituales sobre los ejemplos que no necesariamente son perfectos desde todos los ángulos, diría que este tipo de diseño es particularmente frágil. Si bien hay algo satisfactorio en encontrar una manera de usar DRI para hacer cumplir las reglas comerciales, también le quita parte de su capacidad para responder a los cambios. Si Toyota compra Ford, o incluso si un concesionario Ford decide vender un Toyota usado, sus reglas comerciales basadas en DRI le darán un dolor de cabeza de mantenimiento.
Joel Brown

1
Entonces "sus reglas de negocio pueden cambiar". Eso es cierto para cualquier regla de negocios y siempre será potencialmente difícil volver a modelar. Por lo general, me dicen cuáles son las reglas de negocio, no las decido por mí mismo.
Jack Douglas

1
¿Estás diciendo que DRI no debería usarse para hacer cumplir las reglas comerciales? ¿No es eso lo único que hace DRI? - incluso las claves foráneas simples son reglas comerciales aplicadas por DRI.
Jack Douglas

44
Por supuesto, DRI hace cumplir las reglas comerciales. Debe decidir qué reglas se aplicarán en el código y cuáles en su esquema. Los cambios de esquema son casi siempre más difíciles que los cambios de código. Hay dos tipos de reglas comerciales que pueden entrar en su modelo de datos. Uno pertenece allí y el otro no. La naturaleza fundamental de los datos que es importante para su negocio no cambia mucho. Las formas específicas en las que opera con esos datos son mucho más volátiles . Una regla como que los automóviles tienen un fabricante pertenece al modelo de datos. Una regla como los concesionarios nunca venderán dos marcas de automóviles no lo hace.
Joel Brown

44
"Los cambios de esquema son casi siempre más difíciles que los cambios de código". En mi opinión, lo contrario es cierto. En realidad, estoy en desacuerdo con prácticamente todo lo que acabas de decir, pero dudo que tenga sentido discutir el lanzamiento contigo, así que lo dejaré así.
Jack Douglas

12

"depende"

Sí: los campos IDENTIDAD / AUTONÚMERO sustituto son válidos cuando la clave natural es amplia y no numérica. Nota: esto supone la combinación de "PK" e índice agrupado que ocurre de manera predeterminada en SQL Server y Sybase, etc.

No: muchas / muchas tablas cuando las 2 claves principales son suficientes. O cuando la clave natural es corta y de longitud fija, por ejemplo, código de moneda

Por supuesto, un ORM de muerte cerebral (léase: (n) Hibernate) puede superar estas reglas ...

Editar: leer la pregunta nuevamente

Una tabla muchos / muchos con 2 claves principales sustitutas tendrá una PK de varias columnas.
Sin embargo, no necesita otra columna sustituta.

Si una tabla tiene una clave sustituta (IDENTIDAD, etc.), entonces no necesita ser una columna múltiple.

Puede tener una súper clave que incluya el sustituto, pero esto sería para imponer otras reglas (por ejemplo, subtipos )

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.