Pregunta

Aquí vamos de nuevo, el viejo argumento todavía surge...

¿Será mejor que tengamos una clave comercial como clave principal o preferimos tener una identificación sustituta (es decir,una identidad de SQL Server) con una restricción única en el campo de clave comercial?

Por favor, proporcione ejemplos o pruebas que respalden su teoría.

¿Fue útil?

Solución

Ambos.Toma tu pastel y cometelo.

Recuerde que una clave primaria no tiene nada de especial, excepto que está etiquetada como tal.No es más que una restricción ÚNICA NOT NULL y una tabla puede tener más de una.

Si utiliza una clave sustituta, aún necesitará una clave comercial para garantizar la unicidad de acuerdo con las reglas comerciales.

Otros consejos

Sólo algunas razones para usar claves sustitutas:

  1. Estabilidad:Cambiar una clave debido a una necesidad comercial o natural afectará negativamente a las tablas relacionadas.Las claves sustitutas rara vez, o nunca, necesitan cambiarse porque no hay ningún significado vinculado al valor.

  2. Convención:Le permite tener una convención de nomenclatura de columnas de clave principal estandarizada en lugar de tener que pensar en cómo unir tablas con varios nombres para sus PK.

  3. Velocidad:Dependiendo del valor y tipo de PK, una clave sustituta de un número entero puede ser más pequeña y más rápida de indexar y buscar.

Parece que nadie ha dicho todavía nada en apoyo de las claves no sustitutas (dudo en decir "naturales").Así que aquí va...

A desventaja de claves sustitutas es que son sin sentido (citado como una ventaja por algunos, pero...).A veces, esto le obliga a unir muchas más tablas en su consulta de las que realmente deberían ser necesarias.Comparar:

select sum(t.hours)
from timesheets t
where t.dept_code = 'HR'
and t.status = 'VALID'
and t.project_code = 'MYPROJECT'
and t.task = 'BUILD';

contra:

select sum(t.hours)
from timesheets t
     join departents d on d.dept_id = t.dept_id
     join timesheet_statuses s on s.status_id = t.status_id
     join projects p on p.project_id = t.project_id
     join tasks k on k.task_id = t.task_id
where d.dept_code = 'HR'
and s.status = 'VALID'
and p.project_code = 'MYPROJECT'
and k.task_code = 'BUILD';

¿A menos que alguien piense seriamente que lo siguiente es una buena idea?:

select sum(t.hours)
from timesheets t
where t.dept_id = 34394
and t.status_id = 89    
and t.project_id = 1253
and t.task_id = 77;

"Pero" alguien dirá: "¿Qué sucede cuando cambia el código para myproject o válido o recursos humanos?" A lo que mi respuesta sería:"por que lo harias necesidad ¿Quieres cambiarlo?" Estas no son claves "naturales" en el sentido de que algún organismo externo vaya a legislar que de ahora en adelante 'VÁLIDO' debería recodificarse como 'BUENO'.Sólo un pequeño porcentaje de claves "naturales" realmente entran en esa categoría: el SSN y el código postal son los ejemplos habituales.Definitivamente usaría una clave numérica sin sentido para tablas como Persona, Dirección, pero no para todo, que por alguna razón la mayoría de la gente aquí parece defender.

Ver también: mi respuesta a otra pregunta

Las claves sustitutas (generalmente números enteros) tienen el valor agregado de hacer que las relaciones de sus tablas sean más rápidas y más económicas en almacenamiento y velocidad de actualización (mejor aún, las claves externas no necesitan actualizarse cuando se usan claves sustitutas, en contraste con los campos de claves comerciales). que cambian de vez en cuando).

La clave principal de una tabla debe usarse para identificar de forma única la fila, principalmente para fines de unión.Piense en una tabla de Personas:Los nombres pueden cambiar y no se garantiza que sean únicos.

Piense en las empresas:Eres una empresa Merkin feliz que hace negocios con otras empresas en Merkia.Eres lo suficientemente inteligente como para no utilizar el nombre de la empresa como clave principal, por lo que utilizas la identificación única de la empresa del gobierno de Merkia en su totalidad de 10 caracteres alfanuméricos.Luego Merkia cambia los ID de la empresa porque pensó que sería una buena idea.Está bien, utiliza la función de actualizaciones en cascada de su motor de base de datos, para un cambio que no debería involucrarlo en primer lugar.Más tarde, su negocio se expande y ahora trabaja con una empresa en Freedonia.La identificación de la empresa de Freedonian tiene hasta 16 caracteres.Debe ampliar la clave principal de identificación de la empresa (también los campos de clave externa en Órdenes, Emisiones, Transferencias de dinero, etc.), agregando un campo País en la clave principal (también en las claves externas).¡Ay!Guerra civil en Freedonia, está dividida en tres países.El nombre del país de su asociado debe cambiarse por el nuevo;actualizaciones en cascada al rescate.Por cierto, ¿cuál es tu clave principal?(País, CompanyID) o (CompanyID, País)?Este último ayuda a las uniones, el primero evita otro índice (o quizás muchos, si desea que sus Órdenes también estén agrupadas por país).

Todo esto no es una prueba, sino una indicación de que una clave sustituta para identificar de forma única una fila para todos los usos, incluidas las operaciones de unión, es preferible a una clave comercial.

La clave sustituta NUNCA tendrá una razón para cambiar.No puedo decir lo mismo de las claves naturales.Apellidos, correos electrónicos, números de ISBN: todos pueden cambiar algún día.

Odio las claves sustitutas en general.Sólo deben utilizarse cuando no se dispone de una clave natural de calidad.Si lo piensas bien, es bastante absurdo pensar que agregar datos sin sentido a tu tabla podría mejorar las cosas.

Aquí están mis razones:

  1. Cuando se utilizan claves naturales, las tablas se agrupan en la forma en que se buscan con mayor frecuencia, lo que agiliza las consultas.

  2. Cuando utilice claves sustitutas, debe agregar índices únicos en las columnas de claves lógicas.Aún necesita evitar datos duplicados lógicos.Por ejemplo, no puede permitir dos organizaciones con el mismo nombre en su tabla de organizaciones aunque el pk sea una columna de identificación sustituta.

  3. Cuando se utilizan claves sustitutas como clave principal, queda mucho menos claro cuáles son las claves primarias naturales.Al desarrollar, desea saber qué conjunto de columnas hacen que la tabla sea única.

  4. En una a muchas cadenas de relaciones, los llaveros lógicos.Entonces, por ejemplo, las organizaciones tienen muchas cuentas y las cuentas tienen muchas facturas.Entonces, la clave lógica de la organización es OrgName.La clave lógica de Cuentas es OrgName, AccountID.La clave lógica de Factura es Nombre de organización, ID de cuenta, Número de factura.

    Cuando se utilizan claves sustitutas, las cadenas de claves se truncan al tener solo una clave externa para el padre inmediato.Por ejemplo, la tabla Factura no tiene una columna OrgName.Solo tiene una columna para AccountID.Si desea buscar facturas para una organización determinada, deberá unirse a las tablas Organización, Cuenta y Factura.Si utiliza claves lógicas, puede consultar la tabla de organización directamente.

  5. El almacenamiento de valores de clave sustitutas de tablas de búsqueda hace que las tablas se llenen con números enteros sin sentido.Para ver los datos, se deben crear vistas complejas que se unan a todas las tablas de búsqueda.Una tabla de búsqueda está destinada a contener un conjunto de valores aceptables para una columna.En su lugar, no debe codificarse almacenando una clave sustituta entera.No hay nada en las reglas de normalización que sugieran que deba almacenar un número entero sustituto en lugar del valor en sí.

  6. Tengo tres libros de bases de datos diferentes.Ninguno de ellos aparece usando claves sustitutas.

Quiero compartir mi experiencia con ustedes en esta guerra sin fin :D entre el dilema clave natural versus sustituto.Creo que ambos Las claves sustitutas (artificiales autogeneradas) y las claves naturales (compuestas por columnas con significado de dominio) tienen pros y contras.Entonces, dependiendo de tu situación, puede ser más relevante elegir un método u otro.

Como parece que mucha gente presenta las claves sustitutas como la solución casi perfecta y las claves naturales como la plaga, me centraré en los argumentos del otro punto de vista:

Desventajas de las claves sustitutas

Las claves sustitutas son:

  1. Fuente de problemas de rendimiento:
    • Por lo general, se implementan mediante columnas autoincrementadas, lo que significa:
      • Un viaje de ida y vuelta a la base de datos cada vez que desee obtener una nueva identificación (sé que esto se puede mejorar usando el almacenamiento en caché o algoritmos similares [seq]hilo, pero aún así esos métodos tienen sus propios inconvenientes).
      • Si algún día necesita mover sus datos de un esquema a otro (sucede con bastante regularidad al menos en mi empresa), es posible que encuentre problemas de colisión de ID.Y sí, sé que puedes usar UUID, ¡pero esos últimos requieren 32 dígitos hexadecimales!(Si le importa el tamaño de la base de datos, puede ser un problema).
      • Si está utilizando una secuencia para todas sus claves sustitutas, entonces, con seguridad, terminará teniendo competencia en su base de datos.
  2. Propenso a errores.Una secuencia tiene un límite max_value por lo que, como desarrollador, debes prestar atención a los siguientes puntos:
    • Debes realizar un ciclo de tu secuencia (cuando se alcanza el valor máximo, vuelve a 1,2,...).
    • Si está utilizando la secuencia como orden (a lo largo del tiempo) de sus datos, entonces debe manejar el caso de ciclo (la columna con Id. 1 puede ser más nueva que la fila con Id. valor máximo - 1).
    • Asegúrese de que su código (e incluso las interfaces de su cliente, lo cual no debería suceder, ya que se supone que es una identificación interna) admita enteros 32b/64b que utilizó para almacenar los valores de su secuencia.
  3. No garantizan datos no duplicados.Siempre puede tener 2 filas con los mismos valores de columna pero con un valor generado diferente.para mi esto es EL El problema de las claves sustitutas desde el punto de vista del diseño de bases de datos.
  4. Más en Wikipedia...

Mitos sobre las claves naturales

  1. Las claves compuestas son menos ineficientes que las claves sustitutas.¡No!Depende del motor de base de datos utilizado:
  2. Las claves naturales no existen en la vida real.¡Lo siento pero existen!En la industria de la aviación, por ejemplo, la siguiente tupla siempre será única con respecto a un determinado programado vuelo (aerolínea, fecha de salida, número de vuelo, sufijo operativo).De manera más general, cuando se garantiza que un conjunto de datos comerciales es único por un determinado estándar entonces este conjunto de datos es un [buen] candidato clave natural.
  3. Las claves naturales "contaminan el esquema" de las tablas secundarias.Para mí esto es más un sentimiento que un problema real.Tener una clave primaria de 4 columnas de 2 bytes cada una podría ser más eficiente que una sola columna de 11 bytes.Además, las 4 columnas se pueden usar para consultar la tabla secundaria directamente (usando las 4 columnas en una cláusula donde) sin unirse a la tabla principal.

Conclusión

Utilice claves naturales cuando sea relevante y utilice claves sustitutas cuando sea mejor utilizarlas.

¡Espero que esto haya ayudado a alguien!

Utilice siempre una clave que no tenga significado comercial.Es simplemente una buena práctica.

EDITAR:Estaba intentando encontrar un enlace en línea, pero no pude.Sin embargo en 'Patrones de arquitectura empresarial' [Fowler] tiene una buena explicación de por qué no deberías usar nada más que una clave sin otro significado que el de ser una clave.Todo se reduce al hecho de que debería tener un trabajo y sólo un trabajo.

Las claves sustitutas son bastante útiles si planea utilizar una herramienta ORM para manejar/generar sus clases de datos.Si bien puedes usar claves compuestas con algunos de los mapeadores más avanzados (lea:hibernate), agrega cierta complejidad a su código.

(Por supuesto, los puristas de las bases de datos argumentarán que incluso la noción de una clave sustituta es una abominación).

Soy fanático del uso de uids como claves sustitutas cuando sea adecuado.La mayor ventaja con ellos es que conoces la clave de antemano, p.puede crear una instancia de una clase con el ID ya configurado y garantizado como único, mientras que con, por ejemplo, una clave entera necesitará establecer un valor predeterminado de 0 o -1 y actualizarlo a un valor apropiado cuando guarde/actualice.

Sin embargo, los UID tienen penalizaciones en términos de velocidad de búsqueda y unión, por lo que depende de la aplicación en cuestión si son deseables.

En mi opinión, usar una clave sustituta es mejor, ya que no hay ninguna posibilidad de que cambie.Casi cualquier cosa que se me ocurra y que pueda utilizar como clave natural podría cambiar (descargo de responsabilidad:no siempre es cierto, pero es común).

Un ejemplo podría ser una base de datos de coches: a primera vista se podría pensar que la matrícula podría utilizarse como llave.Pero estos podrían cambiarse, por lo que sería una mala idea.Realmente no querrías descubrir eso. después al lanzar la aplicación, cuando alguien se acerca a ti y quiere saber por qué no puede cambiar su matrícula por una nueva y brillante personalizada.

Utilice siempre una sola columna, clave sustituta si es posible.Esto hace que las uniones, así como las inserciones, actualizaciones y eliminaciones sean mucho más limpias porque usted solo es responsable de rastrear una única información para mantener el registro.

Luego, según sea necesario, apile las claves de su negocio como restricciones o índices únicos.Esto mantendrá intacta la integridad de sus datos.

La lógica empresarial/las claves naturales pueden cambiar, pero la clave física de una tabla NUNCA debería cambiar.

En un escenario de almacén de datos, creo que es mejor seguir la ruta de la clave sustituta.Dos razones:

  • Usted es independiente del sistema de origen y los cambios allí, como un cambio de tipo de datos, no le afectarán.
  • Su DW necesitará menos espacio físico ya que solo utilizará tipos de datos enteros para sus claves sustitutas.Además, sus índices funcionarán mejor.

Las claves sustitutas pueden resultar útiles cuando la información empresarial puede cambiar o ser idéntica.Después de todo, los nombres comerciales no tienen por qué ser únicos en todo el país.Suponga que trabaja con dos empresas llamadas Smith Electronics, una en Kansas y otra en Michigan.Puedes distinguirlos por dirección, pero eso cambiará.Incluso el Estado puede cambiar;¿Qué pasa si Smith Electronics de Kansas City, Kansas se muda al otro lado del río a Kansas City, Missouri?No existe una forma obvia de mantener estas empresas diferenciadas con información de clave natural, por lo que una clave sustituta es muy útil.

Piense en la clave sustituta como un número ISBN.Por lo general, identifica un libro por título y autor.Sin embargo, tengo dos libros titulados "Pearl Harbor" de H.PAG.Willmott, y definitivamente son libros diferentes, no sólo ediciones diferentes.En un caso como ese, podría referirme a la apariencia de los libros, o al anterior versus al posterior, pero es mejor que tenga el ISBN al que recurrir.

Como recordatorio, no es una buena práctica colocar índices agrupados en claves sustitutas aleatorias, es decir,GUID que leen XY8D7-DFD8S, ya que SQL Server no tiene la capacidad de ordenar físicamente estos datos.En su lugar, debería colocar índices únicos en estos datos, aunque también puede ser beneficioso simplemente ejecutar el generador de perfiles SQL para las operaciones de la tabla principal y luego colocar esos datos en el Asesor de optimización del motor de base de datos.

Ver hilo @ http://social.msdn.microsoft.com/Forums/en-us/sqlgetstarted/thread/27bd9c77-ec31-44f1-ab7f-bd2cb13129be

Caso 1: Tu mesa es una tabla de búsqueda con menos de 50 tipos (insertos)

Usar claves comerciales/naturales.Por ejemplo:

Table: JOB with 50 inserts
CODE (primary key)       NAME               DESCRIPTION
PRG                      PROGRAMMER         A programmer is writing code
MNG                      MANAGER            A manager is doing whatever
CLN                      CLEANER            A cleaner cleans
...............
joined with
Table: PEOPLE with 100000 inserts

foreign key JOBCODE in table PEOPLE
looks at
primary key CODE in table JOB

Caso 2: Tu mesa es una mesa con miles de inserciones

Usar claves sustitutas/de incremento automático.Por ejemplo:

Table: ASSIGNMENT with 1000000 inserts
joined with
Table: PEOPLE with 100000 inserts

foreign key PEOPLEID in table ASSIGNMENT
looks at
primary key ID in table PEOPLE (autoincrement)

En el primer caso:

  • Puede seleccionar todos los programadores en la tabla PERSONAS sin usar la combinación con la tabla TRABAJO, pero solo con:"SELECCIONAR * DE LAS PERSONAS DONDE CÓDIGO DE TRABAJO = 'PRG'"

En el segundo caso:

  • Las consultas de su base de datos son más rápidas porque su clave principal es un número entero
  • No necesita preocuparse por encontrar la siguiente clave única porque la propia base de datos le proporciona el siguiente incremento automático.

Este es uno de esos casos en los que una clave sustituta prácticamente siempre tiene sentido.Hay casos en los que elige lo que es mejor para la base de datos o lo que es mejor para su modelo de objetos, pero en ambos casos, usar una clave o GUID sin sentido es una mejor idea.Hace que la indexación sea más fácil y rápida, y es una identidad para su objeto que no cambia.

Caballo para cursos.Para expresar mi parcialidad;Primero soy desarrollador, por lo que lo que más me preocupa es brindarles a los usuarios una aplicación que funcione.

He trabajado en sistemas con claves naturales y tuve que dedicar mucho tiempo a asegurarme de que los cambios de valor se extendieran.

He trabajado en sistemas solo con claves sustitutas y el único inconveniente ha sido la falta de datos desnormalizados para la partición.

A la mayoría de los desarrolladores tradicionales de PL/SQL con los que he trabajado no les gustaban las claves sustitutas debido al número de tablas por unión, pero nuestras bases de datos de prueba y producción nunca sudaron;las uniones adicionales no afectaron el rendimiento de la aplicación.Con dialectos de bases de datos que no admiten cláusulas como "X unión interna Y en X.a = Y.b", o desarrolladores que no usan esa sintaxis, las uniones adicionales para claves sustitutas hacen que las consultas sean más difíciles de leer y más largas de escribir y controlar:ver la publicación de @Tony Andrews.Pero si usa un ORM o cualquier otro marco de generación de SQL, no lo notará.La mecanografía también lo mitiga.

Quizás no sea completamente relevante para este tema, pero me duele la cabeza lidiar con las claves sustitutas.Los análisis preentregados de Oracle crean SK generados automáticamente en todas sus tablas de dimensiones en el almacén y también los almacena en función de los hechos.Por lo tanto, cada vez que es necesario recargar (las dimensiones) a medida que se agregan nuevas columnas o deben completarse para todos los elementos de la dimensión, las SK asignadas durante la actualización hacen que las SK no estén sincronizadas con los valores originales almacenados en el hecho, lo que obliga a una recarga completa de todas las tablas de hechos que se unen a él.Preferiría que incluso si el SK fuera un número sin sentido, hubiera alguna manera de que no pudiera cambiarse para los registros originales/antiguos.Como muchos saben, lo listo para usar rara vez satisface las necesidades de una organización y tenemos que personalizarlo constantemente.Ahora tenemos 3 años de datos en nuestro almacén y las recargas completas de los sistemas Oracle Financial son muy grandes.Entonces, en mi caso, no se generan a partir de la entrada de datos, sino que se agregan en un almacén para ayudar a generar informes sobre el rendimiento.Lo entiendo, pero lo nuestro cambia y es una pesadilla.

En el caso de una base de datos puntual, es mejor tener una combinación de claves sustitutas y naturales.p.ej.necesita realizar un seguimiento de la información de un miembro de un club.Algunos atributos de un miembro nunca cambian.por ejemplo, fecha de nacimiento, pero el nombre puede cambiar.Así que cree una tabla de miembros con una clave sustituta member_id y tenga una columna para DOB.Cree otra tabla llamada nombre de persona y tenga columnas para member_id, member_fname, member_lname, date_updated.En esta tabla la clave natural sería member_id + date_updated.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top