¿Qué le parecen sus claves principales? [cerrado]


88

En una discusión bastante animada en mi equipo, me hicieron pensar en lo que a la mayoría de la gente le gusta como claves primarias. Tuvimos los siguientes grupos-

  1. Int / BigInt cuyos aumentos automáticos son claves primarias suficientemente buenas.
  2. Debe haber al menos 3 columnas que componen la clave principal.
  3. Id, GUID y los identificadores de fila legibles por humanos deben tratarse de manera diferente.

¿Cuál es el mejor enfoque para los PK? Sería fantástico si pudiera justificar su opinión. ¿Existe un enfoque mejor que el anterior?

EDITAR: ¿Alguien tiene una muestra / algoritmo simple para generar identificadores legibles por humanos para filas que se escalan bien?


1
Dado que esto es subjetivo, debería ser un wiki de la comunidad
John Sheehan

2
"¿Debería haber al menos 3 columnas que componen la clave principal"? ¿Qué significa esto? ¿Puede proporcionar una definición más detallada? ¿O es parte del n. ° 3?
S.Lott

@ S.Lott PK(NEWID(),NEWID(),NEWID());-)

@pst: ¿Por qué es esto un requisito? ¿Por qué debe haber tres columnas en un PK? ¿Por qué uno uno o cuatro?
S.Lott

Pude ver un PK de tres columnas como ... LocalID (Auto incremento int), GlobalID (GUID), ForeignId (clave externa como RolesType), etc. El LocalID + ForiegnId podría ser una combinación de clave compuesta. La guía se utiliza para otros sitios web / servicios. Personalmente, no haría esto, solo usaría Guid + ForiegnId.
Jerad

Respuestas:


77

Si va a realizar alguna sincronización entre bases de datos con aplicaciones conectadas ocasionalmente, entonces debería usar GUID para sus claves principales. Es una especie de molestia para la depuración, así que, aparte de ese caso, tiendo a ceñirme a los ints que autoincremento.

Los ints de autoincremento deben ser los predeterminados y no se debe justificar su uso.


3
No es necesario un GUID, simplemente cambie el paso a 10 o 20 o la cantidad de servidores con los que posiblemente necesite sincronizar en el futuro.
Robert C. Barth

44
Al menos el 90% del tiempo, no se necesita un GUID y desperdicia espacio.
Jonathan Leffler

8
En serio, creo que los GUID son exagerados. Nunca he tenido la necesidad de tener GUID como claves principales todavía.
Cyril Gupta

7
O, en lugar de desperdiciar espacio y arriesgarse a chocar con un GUID, cree una clave compuesta de la clave principal original y un identificador pequeño, donde el identificador pequeño es diferente para cada fuente de sincronización.
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

5
Una tienda para la que trabajé usaba GUID para todo, incluso cuando había identificadores públicos disponibles, como códigos ISO de país o idioma. E incluso cuando un booleano o CHAR(1)hubiera sido suficiente, como para sex. No hace falta decir que trabajar con él fue una pesadilla.
Lumi

56

No veo una respuesta que señale (lo que considero) el punto realmente fundamental, es decir, que una clave primaria es lo que garantiza que no obtendrá dos entradas en la tabla para la misma entidad del mundo real (como modelado en la base de datos). Esta observación ayuda a establecer qué opciones son buenas y malas para la clave primaria.

Por ejemplo, en una tabla de códigos y nombres de estados (EE. UU.), El nombre o el código podría ser la clave principal; constituyen dos claves candidatas diferentes, y una de ellas (normalmente la más corta, el código) se elige Clave primaria. En la teoría de las dependencias funcionales (y las dependencias de unión - 1NF a 5NF - son las claves candidatas las que son cruciales en lugar de una clave primaria.

Como contraejemplo, los nombres humanos generalmente son una mala elección para la clave primaria. Hay muchas personas que se conocen con el nombre de "John Smith" o algunos otros nombres similares; incluso teniendo en cuenta los segundos nombres (recuerde: no todo el mundo tiene uno, por ejemplo, yo no), hay muchas posibilidades de duplicación. En consecuencia, la gente no usa nombres como claves primarias. Inventan claves artificiales como el número de seguro social (SSN) o el número de empleado y las utilizan para designar a la persona.

Una clave primaria ideal es breve, única, memorable y natural. De estas características, la singularidad es obligatoria; el resto tiene que ser flexible dadas las limitaciones de los datos del mundo real.

Cuando se trata de determinar la clave principal de una tabla dada, por lo tanto, debe observar lo que representa esa tabla. ¿Qué conjunto o conjuntos de valores de columna de la tabla identifican de forma única cada fila de la tabla? Esas son las claves candidatas. Ahora, si cada clave candidata consta de 4 o 5 columnas, entonces puede decidir que son demasiado torpes para hacer una buena clave primaria (principalmente por razones de brevedad). En esas circunstancias, puede introducir una clave sustituta, un número generado artificialmente. Muy a menudo (pero no siempre) un simple entero de 32 bits es suficiente para la clave sustituta. Luego, designa esta clave sustituta como clave principal.

Sin embargo, aún debe asegurarse de que las otras claves candidatas (porque la clave sustituta también es una clave candidata, así como la clave primaria elegida) se mantengan como un identificador único, normalmente colocando una restricción única en esos conjuntos de columnas.

A veces, a las personas les resulta difícil identificar qué es lo que hace que una fila sea única, pero debería haber algo para hacer eso, porque la simple repetición de una información no la hace más verdadera. Y si no tiene cuidado y obtiene dos (o más) filas que pretenden almacenar la misma información, y luego necesita actualizar la información, existe el peligro (especialmente si usa cursores) de que actualice solo una fila en lugar de cada fila, por lo que las filas no están sincronizadas y nadie sabe qué fila contiene la información correcta.

Esta es una opinión bastante dura, en algunos aspectos.

No tengo ningún problema en particular con el uso de un GUID cuando se necesitan, pero tienden a ser grandes (como en 16-64 bytes) y se usan con demasiada frecuencia. Muy a menudo, bastaría con un valor de 4 bytes perfectamente correcto. El uso de un GUID donde un valor de 4 bytes sería suficiente desperdicia espacio en disco y ralentiza incluso el acceso indexado a los datos, ya que hay menos valores por página de índice, por lo que el índice será más profundo y se deben leer más páginas para llegar al información.


10
Con respecto a su muestra con nombres de estados de EE. UU., Preferiría una clave sustituta separada, simplemente porque los códigos son algo que está fuera de su control. Si cambian por cualquier motivo, surge un problema.
Dirk Vollmar

1
(continuación) Por ejemplo, Alemania reemplazó un sistema de código postal de 4 dígitos con un sistema de 5 dígitos en la década de 1990 después de la reunificación.
Dirk Vollmar

@divo: Soy un firme defensor de las claves artificiales / sustitutas, pero ni siquiera yo veo el cambio de código postal de 4 a 5 dígitos como un buen ejemplo. Los códigos postales no se utilizan generalmente como claves para nada. (¿Cuándo fue la última vez que tuvo que consultar una tabla PostalCode para averiguar algo sobre ese código? No, se usa casi exclusivamente como parte de una dirección sin que se haga referencia a ninguna otra tabla. Yo diría que su sugerencia está casi a la par con el uso de claves sustitutas para las direcciones mismas.)
ErikE

@Emtucifor: Sí, tal vez ZIP no sea un ejemplo muy práctico, pero mi punto fue que si parte de su clave sustituta está fuera de su control y cambia por cualquier motivo, está en problemas. Piense en alguien que crea un nuevo esquema de número de seguro social, un nuevo esquema de ISSN o, tal vez más realista, una empresa que decide crear un nuevo sistema de identificación de producto después de una fusión, asignando nuevos números de empleado a sus empleados para ajustar su crecimiento, etc. Estos son todos son solo ejemplos de ficción, pero, como muestra mi ejemplo anterior con el ZIP, a veces un sistema bien establecido puede cambiar.
Dirk Vollmar

2
Tu primer punto es correcto. Hay un nombre para esta restricción. Se llama "integridad de la entidad". La IE requiere que cada entidad tenga una identidad única. Las claves primarias a menudo cumplen con este requisito, excepto cuando se usa el número automático. Con la numeración automática, puede obtener dos filas que son idénticas, excepto por la numeración automática. Esto suele violar la integridad de la entidad.
Walter Mitty

26

Este es solo un problema religioso porque la gente busca una respuesta correcta universal. El hecho de que tanto su equipo como este hilo de SO muestren tanto desacuerdo debería ser una pista de que existen buenas razones para utilizar todas las soluciones que describe, en diferentes circunstancias.

  • Las claves sustitutas son útiles cuando ningún otro atributo o conjunto de atributos en la tabla es adecuado para identificar filas de forma única.
  • Se prefieren las claves naturales, cuando sea posible, para que la tabla sea más legible por humanos. Las claves naturales también permiten que la clave externa en una tabla dependiente contenga un valor real en lugar de una identificación sustituta. Por ejemplo, cuando necesite almacenar state(CA, TX, NY), también podría usar una char(2)clave natural en lugar de una int.
  • Utilice claves primarias compuestas cuando corresponda. No agregue una idclave sustituta " " innecesariamente cuando existe una clave compuesta perfectamente buena (esto es especialmente cierto en tablas de muchos a muchos). Un mandato para una clave de tres columnas en cada tabla es una absoluta tontería.
  • Los GUID son una solución cuando necesita preservar la singularidad en varios sitios. También son útiles si necesita que los valores de la clave principal sean únicos, pero no ordenados ni consecutivos.
  • INT vs.BIGINT: no es común que una tabla requiera un rango de 64 bits para las claves primarias, pero con la creciente disponibilidad de hardware de 64 bits, no debería ser una carga y brinda más seguridad de que no se desbordará. INT es, por supuesto, más pequeño, por lo que si el espacio es escaso, puede ofrecer una ligera ventaja.

8
No estoy de acuerdo tanto como una persona pueda hacerlo. Las claves naturales son horribles. ¿Qué pasa si uno quiere cambiar los datos? Oh, no puedes. Escribir uniones en claves naturales compuestas es un fastidio. Llevar esa clave compuesta a todas sus tablas relacionadas es un desperdicio.
Robert C. Barth

2
@Robert: leer acerca de "ACTUALIZAR CASCADA". Pero entiendo lo que está diciendo y estoy de acuerdo en que es mejor usar una clave sustituta la mayor parte del tiempo, porque los atributos están sujetos a cambios y no son únicos.
Bill Karwin

2
Las claves primarias deben ser inmutables. Las actualizaciones en cascada son solo un truco feo para una mala decisión de diseño en este caso. NUNCA se prefieren las claves naturales. Lo mismo ocurre con las claves compuestas, que se propagan como una plaga. Cualquiera con más de 3 meses de experiencia en el desarrollo de bases de datos lo sabría.
FDCastel

7
@FD: No estoy de acuerdo con su declaración inequívoca, y he estado desarrollando con bases de datos SQL desde 1992. Pero ciertamente es cierto que las claves sustitutas son las que mejor pueden permanecer inmutables.
Bill Karwin

20

Me gusta el blog The Database Programmer como fuente para este tipo de información.

3 columnas para una clave primaria? Yo diría que las columnas deberían tener restricciones únicas apropiadas según lo exijan las reglas de negocio, pero aún tendría una clave sustituta separada. Las claves compuestas significan que la lógica empresarial entra en la clave. Si la lógica cambia, todo tu esquema se arruina.


2
Cambiaron su enlace, aquí está el marcador actualizado: database-programmer.blogspot.com/2008/09/…
Bryan Rehbein

Acabo de heredar un proyecto como este. Y lo primero que querían hacer hizo estallar el esquema. Llaves sustitutas FTW. Lógica empresarial en su DB FTL.
Jason


11

Un poco fuera de tema, pero me siento obligado a intervenir con ...

Si su clave principal es un GUID, no lo convierta en un índice agrupado . Dado que los GUID no son secuenciales, los datos se reorganizarán en el disco durante casi todas las inserciones. (¡Qué asco!) Si usa GUID como claves primarias, deberían ser índices no agrupados.


1
Muy buen punto: es necesario distinguir entre el concepto LÓGICO de una clave primaria (podría ser válido para usar un GUID para eso, especialmente si se trata de replicación), y el concepto FÍSICO de la clave de agrupamiento, que NUNCA debería ser un GUID ya que conduce a una fragmentación excesiva del índice
marc_s

3
De hecho, esto no es exacto. Los datos se insertarán en orden, lo que, dada la naturaleza aleatoria del GUID, podría terminar en cualquier lugar de la tabla. En la remota posibilidad de que no haya espacio, se producirá una división de página, pero ciertamente no se "reorganizará en el disco durante cada inserción" ni siquiera cerca.
Ralph Shillington

@Ralph, tienes razón, no en TODAS las inserciones, pero lo suficiente como para causar un impacto de rendimiento de 20 veces. sql-server-performance.com/articles/per/…
Portman

La función newsequentialid () de SQL Server resuelve el problema de fragmentación del índice con GUID (aunque 24 bytes sigue siendo un poco excesivo si no necesita absolutamente la unicidad global). Consulte msdn.microsoft.com/en-us/library/ms189786.aspx.
ErikE

10

Siempre voy con la llave sustituta. Una clave sustituta (generalmente una columna de identidad, autoincremento o GUID) es aquella en la que la clave no está presente en los datos en sí. Una clave natural, por otro lado, es aquella que, por sí sola, identifica de forma única la fila. Por lo que puedo decir en la vida, casi no hay claves naturales reales . Ni siquiera cosas como SSN en los Estados Unidos es una clave natural. Las claves primarias compuestas son un desastre a la espera de suceder. No puede editar ninguno de esos datos (que es el mayor inconveniente de cualquier clave natural, compuesta o no), pero lo peor es que con una clave compuesta, ahora tiene que perpetuar esos datos clave en cada tabla relacionada. Qué desperdicio gigante.

Ahora, para la selección de la clave sustituta, me quedo con las columnas de identidad (trabajo principalmente en MS SQL Server). Los GUID son demasiado grandes y Microsoft recomienda no usarlos como PK. Si tiene varios servidores, todo lo que necesita hacer es hacer el incremento de 10 o 20 o lo que crea que es el número máximo de servidores que necesitará sincronizar / expandir, y solo aumentar la semilla para cada tabla en cada servidor subsiguiente y nunca tendrá una colisión de datos.

Por supuesto, debido al incremento, hago que la columna de identidad sea un BigInt (también conocido como long [64 bits]).

Haciendo un poco de matemáticas, incluso si hace el incremento de 100, todavía puede tener 92,233,720,368,547,758 (> 92 cuatrillones) filas en su tabla.


9

Creo que el uso de la palabra "Primaria" en la frase Clave "Primaria" es, en un sentido real, engañoso.

Primero, use la definición de que una "clave" es un atributo o conjunto de atributos que deben ser únicos dentro de la tabla,

Entonces, tener cualquier clave sirve para varios propósitos que a menudo son incompatibles entre sí.

  1. Para usar como condiciones de unión a uno o varios registros en tablas secundarias que tienen una relación con esta tabla principal. (Definición explícita o implícita de una clave externa en esas tablas secundarias)
  2. (relacionado) Garantizar que los registros secundarios deben tener un registro principal en la pestaña principal; e (La tabla secundaria FK debe existir como clave en la tabla principal)
  3. Para aumentar el rendimiento de las consultas que necesitan ubicar rápidamente un registro / fila específico en la tabla.

  4. Para garantizar la coherencia de los datos evitando que se inserten en la tabla filas duplicadas que representan la misma entidad lógica. (Esto a menudo se denomina clave "natural" y debe constar de atributos de tabla (entidad) que son relativamente invariantes).

Claramente, cualquier clave no significativa, no natural (como un GUID o un entero generado automáticamente es totalmente incapaz de satisfacer # 4.

Pero a menudo, con muchas (la mayoría) de las tablas, una clave totalmente natural que puede proporcionar el n. ° 4 a menudo constará de múltiples atributos y será excesivamente amplia, o tan amplia que usarla para los propósitos n. ° 1, n. ° 2 o n. ° 3 causará inaceptables Consecuencias de rendimiento c.

La respuesta es simple. Utilice ambos. Use una clave integral de generación automática simple para todas las combinaciones y FK en otras tablas secundarias, pero asegúrese de que cada tabla que requiera consistencia de datos (muy pocas tablas no lo hagan) tenga una clave única natural alternativa que evitará inserciones de filas de datos inconsistentes. .. Además, si siempre tiene ambos, entonces todas las objeciones contra el uso de una clave natural (¿y si cambia? Tengo que cambiar cada lugar al que se hace referencia como FK) se vuelven discutibles, ya que no la está usando para eso. .. Solo lo está usando en la única tabla donde es un PK, para evitar datos duplicados inconsistentes ...

En cuanto a los GUID, tenga mucho cuidado al usarlos, ya que el uso de guids en un índice puede dañar la fragmentación del índice. Los algoritmos más comunes que se utilizan para crearlos colocan la parte "aleatoria" del guid en las posiciones de bits más significativas ... Esto aumenta el requisito de desfragmentación / reindexación de índice regular a medida que se agregan nuevas filas.


La función newsequentialid () de SQL Server resuelve el problema de fragmentación de índices de los GUID (aunque 24 bytes sigue siendo un poco excesivo si no necesita absolutamente la unicidad global). Consulte msdn.microsoft.com/en-us/library/ms189786.aspx.
ErikE

Ups, quise decir 16 bytes.
ErikE

8

Una cosa que nunca debe hacer es usar una llave inteligente. Esa es una clave donde la información sobre el registro se codifica en la clave misma, y ​​eventualmente lo morderá.

Trabajé en un lugar, donde la clave principal era el ID de cuenta, que era una combinación de letras y números. No recuerdo ningún dato específico, pero, por ejemplo, aquellas cuentas que eran de cierto tipo, estarían en el rango de 600, y de otro tipo, comenzaban con 400. Eso fue genial, hasta que ese cliente decidió pedir tanto tipos de trabajo. O cambiaron el tipo de trabajo que hacían.

En otro lugar, se utilizó la ubicación en el árbol como clave principal para los registros. Entonces habría registros como el siguiente.

Cat1.subcatA.record1
Cat1.subcatA.record2
Cat1.subcatB.record1
Cat2.subcatA.record1

Por supuesto, lo primero que querían los clientes era una forma de mover los elementos del árbol. Todo el conjunto de software murió antes de que eso sucediera.

Por favor, por favor, por favor, si está escribiendo un código que alguna vez tengo que mantener, ¡no use una llave inteligente!


Estoy totalmente de acuerdo. Smartkeys = tonto.
Robert C. Barth

2
Sin embargo, esto no significa que las teclas naturales sean tontas. Pero buen punto.

4

Soy fanático del incremento automático como clave principal. Sé en el fondo de mi corazón que esto es una evasión, pero hace que sea muy fácil ordenar los datos según el momento en que se agregaron (ORDER BY ID DESC, primera instancia).

3 columnas suena terriblemente duro de analizar humanamente.

Y esa es la compensación: cuánta capacidad relacional necesita, versus hacer que ESTA TABLA AQUÍ sea comprensible para un humano que la interroga (versus el procedimiento almacenado o la interfaz programática).

el auto incremento es para nosotros los humanos. :-(


4

Generalmente depende.

Personalmente, me gustan los ints de autoincremento.

Pero, una cosa que puedo decirle es que nunca confíe en los datos de otras fuentes como clave. Lo juro, cada vez que lo he hecho vuelve a morderme. Bueno, ¡nunca más!


3

Debe haber al menos 3 columnas que componen la clave principal.

No entiendo esto.

¿Estás hablando de una "clave natural", por ejemplo, "nombre y fecha de nacimiento"? Una clave natural puede ser ideal si existe, pero la mayoría de los candidatos para una clave natural no son únicos (varias personas con el mismo nombre) o no son constantes (alguien puede cambiar su nombre).

Int / BigInt cuyos aumentos automáticos son claves primarias suficientemente buenas.

Prefiero a Guid. Un problema potencial con el autoincremento es que el valor (por ejemplo, "ID de pedido") es asignado por la instancia de la base de datos (por ejemplo, por la "base de datos de ventas") ... que no funcionará por completo (en su lugar, empezará a necesitar claves compuestas) si siempre necesita fusionar datos creados por más de una instancia de base de datos (por ejemplo, de varias oficinas de ventas, cada una con su propia base de datos).


Las claves primarias deben ser únicas, pero no es necesario que sean constantes. Por lo tanto, las claves externas declaradas con "ON UPDATE CASCADE". Pero suponer que las claves primarias son constantes ayuda a simplificar muchas aplicaciones. Este es uno de los beneficios de las claves sustitutas.
Bill Karwin

3

RE GUID's

Tenga cuidado si esto va a ser una base de datos realmente, REALMENTE REALMENTE grande, mucha carga y acceso rápido.

En mi último trabajo, donde teníamos bases de datos de 100 a 500 millones de registros, nuestros chicos de bases de datos se opusieron firmemente a los GUID y a favor de un número decimal del tamaño adecuado. Consideraron que (bajo Oracle) la diferencia de tamaño en el almacenamiento interno para una cadena Guid - vs- un valor decimal haría una diferencia muy notable en las búsquedas. (Teclas más grandes = árboles más profundos para atravesar)

La naturaleza aleatoria de los GUID también reduce significativamente el factor de relleno de las páginas de índice, lo que aumenta drásticamente el desgarro y la E / S del disco.


¿"Reduce el factor de llenado"? No estoy seguro de lo que eso podría significar. El factor de relleno es un trato único, definido como el porcentaje de espacio libre solicitado en el nivel de hoja del índice en el momento en que se crea el índice. Los valores GUID por su distribución de naturaleza aleatoria a lo largo del ancho del nivel de hoja en inserciones en ese espacio libre que proporcionó el factor de relleno.
Ralph Shillington

1
¿Desde cuándo un GUID es una cadena? Los GUID deben almacenarse internamente como 16 bytes por cualquier DBMS respetable. ¡Almacenar 32 bytes en la representación hexadecimal sería inadmisible! (o 36 con guiones, o 38 con llaves)
ErikE

2

Columnas de incremento automático. Puedo hacer que mi código funcione sin problemas con SQL Server u Oracle, uno usando identidad y el otro usando secuencias a través de mi DAL, y no podría estar más feliz. Estoy de acuerdo, los GUID a veces son necesarios si está realizando una replicación o enviando datos para recibirlos más tarde después del procesamiento.


2

Siempre he usado una clave sustituta, un número entero que aumenta automáticamente y se llama 'id'. Puedo ver muchas razones para hacer esto incluso cuando otra opción es obvia:

  • Consistencia
  • Independiente de los datos (únicos, no destruidos por cambios de formato)
  • Legible por humanos

... y no hay ninguna razón sensata para no:

  • ¿Ambigüedad en las combinaciones? - Las tablas de alias es una mejor práctica, en mi humilde opinión
  • ¿Tablas óptimas? - Eliminar un byte por entrada es una optimización prematura, en mi humilde opinión
  • ¿Decisión por mesa? - Ya no es consistente
  • ¿Problemas de escala? - ¿Eh? ¿Por qué?
  • ¿Estructura de datos jerárquica? - Eso es desnormalizar, otro tema de religión. Basta decir que soy fan en algunas circunstancias en teoría, pero nunca en la práctica :)

razones sensatas en contra de las que no he pensado o encontrado todavía son siempre bienvenidas ...


1

Este es un clásico "depende". No hay una respuesta correcta para cada proyecto. Me gustan cosas diferentes para situaciones diferentes. Depende de si estoy usando un ORM y de lo que admite. Depende de la arquitectura general (distribuida o no, etc.). Simplemente elija uno que crea que funcionará y continúe discutiendo sobre tabulaciones y espacios.


Todavía desea saber CÓMO depende; solo con la conciencia de estos se puede llegar a confiar en uno mismo para elegir ...
Nicholas Leonard

1

Tiendo a usar la opción # 1 o # 3 dependiendo del tamaño, la cantidad de personas que se conectan y si se trata de una situación de servidor de base de datos múltiple o no.

La opción # 2 no tiene mucho sentido para mí. Si alguno de los tres no es suficiente para identificar un registro único, entonces es posible (sin pasar por maquinaciones adicionales) que dos tengan dos registros que aparezcan con los mismos valores en las tres columnas. Si desea hacer cumplir la singularidad en cualquier combinación de los tres, simplemente agregue un índice para ellos.


1

Solo he usado un int de incremento automático o un GUID. El 99% de las veces utilizo el incremento automático int. Es solo lo que me enseñaron a usar cuando aprendí por primera vez sobre bases de datos y nunca me he encontrado con una razón para no usarlas (aunque conozco las razones por las que un GUID sería mejor).

Me gustan los ints de incremento automático porque ayuda con la legibilidad. Por ejemplo, puedo decir "eche un vistazo al registro 129383" y es bastante fácil para alguien entrar y encontrarlo. Con un GUID eso es casi imposible de hacer.


2
¿Por qué dices eso? Parece que mucha gente usa un número entero de incremento automático. No puede ser tan malo si funciona y funciona bien para lo que necesita.
dtc

1

Más allá de una respuesta de definición básica, lo que constituye una buena clave primaria se deja en gran parte a la religión y los argumentos de la sala de descanso. Si tiene algo que es, y siempre, se asignará de forma única a una fila individual, entonces funcionará bien como clave principal. Más allá de ese punto, hay otras consideraciones:

  • ¿La definición de clave primaria no es demasiado compleja? ¿Evita introducir una complejidad innecesaria en aras de seguir una "mejor práctica"?
  • ¿Existe una clave primaria mejor posible que requiera menos gastos generales para que la base de datos la maneje (es decir, INTEGER frente a VARCHAR, etc.)?
  • ¿Estoy ABSOLUTAMENTE seguro de que la unicidad y la invariabilidad de la definición de mi clave principal no cambiarán?

Este último es probablemente lo que atrae a la mayoría de las personas a usar cosas como GUID o columnas de números enteros que se incrementan automáticamente, porque confiar en cosas como direcciones, números de teléfono, nombres / apellidos, etc., simplemente no lo corte. La única invariante sobre las personas en las que puedo pensar son los números de seguro social, pero ni siquiera estoy 100% seguro de que esos sigan siendo únicos para siempre.

Con suerte, esto ayuda a agregar algo de claridad ...


Hay algunos casos históricos en los que los SSN no son únicos.
Bill Karwin

1

La forma en que me acerco a las claves primarias (y creo que es la mejor) es evitar tener un enfoque "predeterminado". Esto significa que en lugar de simplemente dar una palmada a un entero que se incrementa automáticamente y llamarlo un día, miro el problema y digo "¿hay una columna o grupo de columnas que siempre será unqiue y no cambiará?" Si la respuesta es sí, entonces adopto ese enfoque.


¿Eso significa que 'evitas incrementar automáticamente los enteros siempre que puedas'? Tenía entendido que los expertos de la industria pensaban que el mejor rendimiento en bases de datos a gran escala proviene de PK de una sola columna incrementales, indexados y con firma mínima.
Hardryv

1
Siempre pensé que los expertos usaban la mejor herramienta para el trabajo
Andrew G. Johnson

1

Casi siempre enteros.

Tienen otras buenas razones además de ser más pequeñas / más rápidas de procesar. ¿Cuál preferiría escribir: "404040" o "3463b5a2-a02b-4fd4-aa0f-1d3c0450026c"?


Este último puede ser un número entero, con guiones agregados y en base 16. Pero sí, 404040 es más rápido de procesar que el GUID largo. Por otra parte, 0 es incluso más rápido de procesar porque no requiere un solo bit de datos.
extraño

1

Solo un poco relevante, pero una cosa que comencé a hacer recientemente cuando tengo pequeñas tablas de clasificación (esencialmente aquellas que representan ENUM en el código) es que haré que la clave principal sea char (3) o char (4). Luego hago que esas claves primarias sean representativas del valor de búsqueda.

Por ejemplo, tengo un sistema de cotización para nuestros agentes de ventas internos. Tenemos "Categorías de costos" a las que a cada artículo de línea de cotización se le asigna una de ... Así que tengo una tabla de búsqueda de tipos llamada 'tCostCategories', donde la clave principal es 'MTL', 'SVC', 'TRV', 'TAX', 'ODC'. Otras columnas en la tabla de búsqueda almacenan más detalles, como los significados en inglés normales de los códigos, "Material", "Servicio", "Viajes", "Impuestos", "Otros costos directos", etc.

Esto es realmente bueno porque no usa más espacio que un int, y cuando está mirando los datos de origen, no tiene que vincular la tabla de búsqueda para saber cuál es el valor. Por ejemplo, una fila de cotización podría verse así:

1 Número de pieza $ 40 MTL
2 Otro Número de pieza $ 29.99 SVC
3 Número de pieza 2 $ 150 TRV

Es mucho más fácil que usar un int para representar las categorías y luego vincular 1, 2, 3 en todas las líneas: tiene los datos justo frente a usted y el rendimiento no parece afectado en absoluto (no es que yo ' realmente he probado.)

En cuanto a la verdadera pregunta ... me gustan los identificadores únicos RowGUID. No estoy al 100% en esto, pero ¿no todas las filas tienen RowGuid internos de todos modos? Si es así, usar RowGuid en realidad tomaría menos espacio que los ints (o cualquier otra cosa). Todo lo que sé es que si es lo suficientemente bueno para que M $ lo use en GreatPlains, entonces es lo suficientemente bueno para mí. (¿Debería agacharme?)


1

Oh, una razón más por la que uso GUID: uso una estructura de datos jerárquica. Es decir, tengo una tabla 'Compañía' y una tabla 'Proveedor' para las que coinciden las claves primarias. Pero también tengo una tabla 'Fabricante' que también 'hereda' de la Compañía. Los campos que son comunes a proveedores y fabricantes no aparecen en esas tablas, aparecen en Compañía. En esta configuración, el uso de int es mucho más doloroso que Guids. Como mínimo, no puede usar claves primarias de identidad.


1
Sí, puede, simplemente no hace que las tablas de subtipos tengan la propiedad de identidad, sino que obtienen inserciones explícitas del valor de la tabla de supertipo. Consulte stackoverflow.com/questions/2112882/…
ErikE

1

Me gustan las claves naturales, siempre que puedo confiar en ellas. Estoy dispuesto a pagar un pequeño precio por rendimiento para utilizar claves que tengan sentido para los expertos en la materia.

Para las tablas que describen entidades, debe haber una clave natural simple que identifique instancias individuales de la misma manera que lo hacen las personas de la materia. Si el tema no tiene identificadores confiables para una de las entidades, entonces recurriré a una clave sustituta.

Para las tablas que describen relaciones, utilizo una clave compuesta, donde cada componente hace referencia a una entidad que participa en la relación y, por lo tanto, a una fila en una tabla de entidad. Nuevamente, el impacto en el rendimiento por usar una clave compuesta es generalmente mínimo.

Como han señalado otros, el término "clave primaria" es un poco engañoso. En el modelo de datos relacionales, el término que se utiliza es "claves candidatas". Podría haber varias claves candidatas para una sola tabla. Lógicamente, cada uno es tan bueno como el otro. Elegir uno de ellos como "principal" y hacer todas las referencias a través de esa clave es simplemente una elección que el diseñador puede hacer.


Por favor, describa algunos ejemplos de claves naturales confiables.
ErikE

1
"confiable" no es una propiedad de una clave en sí misma. Más bien, tiene que ver con la clave en el contexto de las personas que proporcionan los datos. Si está escribiendo una aplicación para venderla a alguien que realmente administrará los datos, debe adivinar qué claves serán confiables para el cliente o no. Dada la variedad de clientes, es casi seguro que adivinará mal para una fracción de su clientela.
Walter Mitty

Habiendo dicho lo anterior, aquí hay un ejemplo de una clave en la que confiamos hace mucho tiempo. Teníamos una base de datos sobre cursos. Incluía libros de texto y otros materiales del curso sobre cursos, cursos que se ofrecen programados, instructores que estaban calificados para impartir cursos, requisitos previos del curso, matrícula, etc. Cuando el desarrollo del curso creó un curso nuevo, una de las primeras cosas que hicieron fue asignar un código de curso. Ellos eran responsables de asegurarse de que los códigos de los cursos fueran únicos y de que los cursos nunca cambiaran su código, una vez asignados. Formaba parte de los datos que nos dieron.
Walter Mitty

Otro buen ejemplo de clave natural confiable es VIN (Número de identificación del vehículo). Durante los últimos años, cada vehículo vendido como nuevo tiene un VIN adjunto. Se puede confiar en que son únicos e inmutables.
Walter Mitty

1

Guids.period.

En el caso de que necesite escalar horizontalmente o necesite asignar la clave principal por medios alternativos, serán sus amigos. Puede agregar índices para todo lo demás.


actualizar para aclarar mi declaración.

He trabajado en muchos tipos diferentes de sitios. Desde pequeños acuerdos de un solo servidor hasta grandes respaldados con múltiples bases de datos y servidores web. Ciertamente, ha habido aplicaciones que hubieran estado bien con el incremento automático de ints como claves primarias. Sin embargo, esos no se ajustan al modelo de cómo hago las cosas.

Cuando usa un GUID, puede generar el ID en cualquier lugar. Puede ser generado por un servidor remoto, su aplicación web, dentro de la propia base de datos o incluso dentro de varias bases de datos en una situación de varios maestros.

Por otro lado, un INT autoincrementado solo se puede generar de forma segura dentro de la base de datos primaria. Nuevamente, esto podría estar bien si tiene una aplicación que estará íntimamente ligada a ese servidor de base de datos de respaldo y el escalado horizontal no es algo que le preocupe.

Claro, el uso de GUID significa que debe tener procesos de reindexación nocturnos. Sin embargo, si está utilizando algo que no sea un INT incrementado automáticamente, debe hacerlo de todos modos. Diablos, incluso con un INT como principal, es probable que tenga otros índices que necesiten regenerarse para lidiar con la fragmentación. Por lo tanto, el uso de GUID no agrega exactamente otro problema porque esas tareas deben realizarse independientemente.

Si echas un vistazo a las aplicaciones más grandes, notarás algo importante: todas usan GUID codificadas en Base64 como claves. La razón de esto es simple, el uso de GUID le permite escalar horizontalmente fácilmente, mientras que puede haber muchos obstáculos que superar al intentar escalar INT.

Nuestra última aplicación pasa por un período de inserciones pesadas que dura aproximadamente un mes. Después de eso, más del 90% de las consultas se seleccionan para informar. Para aumentar la capacidad, puedo activar servidores de base de datos adicionales durante este gran período de inserción; y luego fusionarlos fácilmente en una sola base de datos para generar informes. Intentar hacer eso con INT sería una pesadilla absoluta.

Francamente, cada vez que agrupa una base de datos o configura la replicación, el servidor de base de datos exigirá que tenga GUID en la mesa de todos modos. Por lo tanto, si cree que su sistema podría necesitar crecer, elija el que sea bueno.


¿Alguna vez examinó el factor de relleno de sus índices? La naturaleza aleatoria de los GUID los hace queso suizo, lo que reduce drásticamente su eficacia.
stephbu

2
"Guids.period": Eso está muy mal. Los GUID deben usarse cuando sea apropiado. Como señaló el otro comentarista, podría facilitar la vida como programador, pero afecta el tamaño general y el rendimiento de la base de datos.
Mitch Wheat

Al final del día, puedo escalar mis aplicaciones en múltiples servidores de bases de datos sin problemas. Pero supongo que ustedes trabajan en sitios pequeños.
NotMe

3
GUID puede estar bien para la clave primaria lógica, pero NUNCA NUNCA use una columna GUID como su clave de CLUSTERING; se ahogará en la fragmentación del índice que conducirá a un POBRE rendimiento .....
marc_s

Ciertamente no proclamaría "Guids.period". sobre este tema, de hecho, incluso en una industria tan llena de 'mejores prácticas', ese tipo de declaración lo pone en un terreno inestable por defecto (particularmente con esa declaración). Cualquier cosa tan dolorosa de tratar como un GUID necesita una justificación estricta y, como dice JL, creo que la mayoría de nosotros lo consideraría un último recurso. Es como si publicaras sin leer el resto del hilo.
Hardryv

0

Este es un tema complejo, te hayas dado cuenta o no. Podría incluirse en la sección de estas preguntas frecuentes de StackOverflow.

¿Qué tipo de preguntas no debería hacer aquí?

Evite hacer preguntas subjetivas, argumentativas o que requieran una discusión extensa. ¡Este es un lugar para preguntas que pueden responderse!

Esto se ha debatido durante años y seguirá debatiéndose durante años. Los únicos indicios de consenso que he visto es que las respuestas son algo predecibles dependiendo de si le estás preguntando a un tipo de OO (¡los GUID son el único camino a seguir!), Un modelador de datos (¡las claves naturales son el único camino a seguir!), o un DBA orientado al rendimiento (¡los INT son el único camino a seguir!).


No dejaré que la discusión se prolongue mucho. Solo tenía curiosidad por ver el consenso general.
Perpetualcoder

1
¡Yo digo que haga las preguntas que desee! De lo contrario, esta comunidad se volverá estática y sobrecontrolada como parece que se ha vuelto wikipedia. Me parece que algunas veces necesitas dejar que la gente pregunte lo que sea que decida preguntar. ¡Confíe en ellos y ellos podrían llegar a confiar en sí mismos!
Nicholas Leonard
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.