Guid vs INT - ¿Cuál es mejor como clave principal?

97

He estado leyendo sobre razones para usar o no Guidy int.

intEs más pequeño, más rápido, fácil de recordar, mantiene una secuencia cronológica. Y en cuanto a Guid, la única ventaja que encontré es que es única. ¿En qué caso a Guidsería mejor que inty por qué?

Por lo que he visto, intno tiene fallas excepto por el límite de número, que en muchos casos son irrelevantes.

¿Por qué exactamente fue Guidcreado? De hecho, creo que tiene un propósito que no sea servir como clave principal de una tabla simple. (¿Algún ejemplo de una aplicación real que use Guidpara algo?)

(Guid = UniqueIdentifier) ​​tipo en SQL Server

BrunoLM
fuente
1
En lugar de la clave primaria , creo que te refieres a una clave sustituta, es decir, una clave que no es la clave natural (esta última es la clave que usamos en el mundo real). Posiblemente te refieres al índice agrupado.
cuando el
También recuerde la diferencia entre CLAVE (Primaria) e ÍNDICE.
Allan S. Hansen
1
También discutido en SO: stackoverflow.com/questions/11033435/…
Jon of All Trades
2
" intno tiene fallas excepto por el límite de número, que en muchos casos son irrelevantes": en realidad, en este contexto de INT vs GUID, el límite superior de un signo de 32 bits INTes completamente irrelevante dado que el límite superior de un signo , 64 bits BIGINTestá más allá de casi todos los usos (aún más si comienza a numerar en el límite inferior; y lo mismo ocurre INT) y sigue siendo la mitad del tamaño de un GUID (8 bytes en lugar de 16) y secuencial.
Solomon Rutzky

Respuestas:

89

Esto se ha pedido en Stack Overflow aquí y aquí .

La publicación de Jeff explica mucho sobre los pros y los contras del uso de GUID.

GUID Pros

  • Único en cada tabla, cada base de datos y cada servidor
  • Permite combinar fácilmente registros de diferentes bases de datos
  • Permite una fácil distribución de bases de datos en múltiples servidores
  • Puede generar ID en cualquier lugar, en lugar de tener que hacer un viaje de ida y vuelta a la base de datos
  • La mayoría de los escenarios de replicación requieren columnas GUID de todos modos

Contras GUID

  • Es enormemente 4 veces más grande que el valor tradicional del índice de 4 bytes; Esto puede tener serias implicaciones de rendimiento y almacenamiento si no tiene cuidado
  • Incómodo de depurar ( where userid='{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}')
  • Los GUID generados deben ser parcialmente secuenciales para un mejor rendimiento (por ejemplo, newsequentialid()en SQL Server 2005+) y para permitir el uso de índices agrupados

Si está seguro del rendimiento y no planea replicar o fusionar registros, utilice inty configure el incremento automático ( semilla de identidad en SQL Server ).

CoderHawk
fuente
20
Otro inconveniente del enfoque GUID es que no puede usarlo como un identificador para su usuario final. ¿Realmente espera que sus usuarios le digan por teléfono que tienen un problema con la Orden "BAE7DF4-DDF-3RG-5TY3E3RF456AS10"? :)
Brann
3
Si no usa guías secuenciales, y su clave principal está agrupada (el valor predeterminado de SQL Server), todas sus inserciones de datos se dispersarán aleatoriamente en la tabla, lo que provocará una fragmentación masiva de sus datos. Eso supone que los datos normalmente se insertarían en algún tipo de orden, como el cronológico.
datagod
66
Las guías secuenciales son solo secuenciales hasta que se reinicia la instancia de SQL. Entonces, lo más probable es que el primer valor sea más bajo que el anterior debido a la forma en que se genera el valor raíz, causando todo tipo de problemas nuevamente.
mrdenny
20
@Brann Idealmente, en primer lugar, no se le darían sus valores de PK a los usuarios finales. Sé que es algo común hacerlo, y es algo que yo mismo he hecho en el pasado antes de aprender a no hacerlo. Pero como no debería hacerse, esa razón particular para preferir INT sobre GUID no es válida.
Solomon Rutzky
2
@ChadKuehn Elegir UNIQUEIDENTIFIERmás INTporque INTtiene un límite superior es un razonamiento bastante pobre ya que ser ilimitado, aunque es cierto, no es un beneficio práctico . Puede doblar fácilmente la capacidad efectiva de un INTcomenzándolo en el límite inferior (-2.14 mil millones) en lugar de en 1. O, si los 4.3 mil millones no son suficientes, comience con un valor de BIGINT8 bytes. en comparación con 16 para el GUID, y es secuencial.
Solomon Rutzky
18

Si está sincronizando sus datos con una fuente externa, un GUID persistente puede ser mucho mejor. Un ejemplo rápido de dónde estamos usando un GUID es una herramienta que se envía al cliente para rastrear su red y hacer ciertas clases de autodescubrimiento, almacenar los registros encontrados y luego todos los registros del cliente se integran en una base de datos central De vuelta a nuestro lado. Si usáramos un número entero, tendríamos 7,398 "1" s, y sería mucho más difícil hacer un seguimiento de qué "1" era cuál.

TML
fuente
3
Los GUID son definitivamente buenos como identificadores externos, y mantendría un índice no agrupado de eso como la "clave externa". Todavía mantendría un int como la "clave interna", que es la base para el índice agrupado y las relaciones de clave externa. Si algo va a cruzar un límite arquitectónico (por ejemplo, comunicarse con otra aplicación), agradezco tener algo que no se pueda mezclar.
Greg
15

He utilizado un enfoque híbrido con éxito. Las tablas contienen AMBAS idcolumnas de enteros de clave primaria de incremento automático Y una guidcolumna. Se guidpuede usar según sea necesario para identificar globalmente de manera única la fila y idse puede usar para consultas, clasificación e identificación humana de la fila.

rmirabelle
fuente
3
¿Qué valor da el GUID si idya es suficiente para que los humanos identifiquen una fila?
Martin Smith
66
La identificación identifica la fila en esta tabla. El GUID (al menos en teoría) identifica esta fila en cualquier parte del universo conocido. En mi proyecto, los móviles Android tienen una copia estructuralmente idéntica de la tabla en una base de datos SQLite local. La fila y su GUID se generan en Android. Luego, cuando Android se sincroniza con la base de datos de back-end, su fila local se escribe en la tabla de back-end sin temor a entrar en conflicto con las filas creadas desde cualquier otro dispositivo móvil Android.
rmirabelle
2
@ MartinSmith He utilizado este enfoque yo mismo y funciona bastante bien. El GUID es solo una clave alternativa, con un índice No en clúster, y se pasa desde la aplicación, pero solo reside en la tabla primaria. Todas las tablas relacionadas están relacionadas a través de la INTPK. Me parece extraño que este enfoque no sea mucho más común dado que es lo mejor de ambos mundos. Parece que la mayoría de las personas simplemente prefieren resolver problemas en términos muy absolutistas, sin darse cuenta de que el PK no necesita ser un GUID para que la aplicación todavía use GUID para la unicidad y / o portabilidad global.
Solomon Rutzky
1
@rmirabelle Había pensado en este enfoque y estaba dudando, pero su respuesta me convenció. Básicamente, estoy en una situación en la que necesito tener un identificador único para un elemento de trabajo (que puede ingresar a través de la red desde cualquier lugar), pero no quiero hacer un viaje de ida y vuelta a la base de datos primero. Los GUID son una buena solución para esto, pero imagino que JOIN se volverá mucho más lento si no tengo una clave agrupada secuencial.
Pascua
1
@easuter Estoy de acuerdo con no agregar campos de identificación "por el simple hecho de hacerlo", como en las tablas de "puente" de muchos a muchos donde el PK debe ser un compuesto de los dos FK que están relacionados. Pero aquí no es una compensación, ya que el campo ID no es solo por el bien. Permitir que el sistema funcione de manera eficiente es bastante importante ;-). Y, diría que en su caso, dado que los GUID se generan externamente, no se garantiza que sean únicos, incluso si son pragmáticos. Pero la responsabilidad de la integridad de los datos es motivo suficiente para que GUID sea una clave alternativa y la ID sea PK en su caso :)
Solomon Rutzky
1

Algunas de las mejores prácticas aún mencionan que debe usar un tipo de datos que se adapte con la menor memoria posible a todo el conjunto de valores que va a usar. Por ejemplo, si lo está utilizando para almacenar el número de empleadores en una pequeña empresa y es poco probable que llegue a 100, entonces nadie sugeriría usar un valor bigint mientras int (incluso smallint) lo haría.

Por supuesto, el inconveniente de esto es como "¡Di no a la escalabilidad!"


Además, sé que esto no está totalmente relacionado, pero hay otro factor con respecto a esto. Cuando no es excesivo, generalmente trato de recomendar el uso de una clave primaria no autogenerada, si tiene sentido. Por ejemplo, si está guardando la información del conductor, no se moleste en crear una nueva columna autogenerada para "ID", solo use el número de licencia.

Sé que esto suena muy obvio, pero veo que se olvida con bastante frecuencia.

Para el contexto: esta parte de la respuesta se abordó desde un enfoque teórico de datos, donde desea que su PK sea el único identificador de datos para un registro. La mayoría de las veces los creamos cuando ya existen, de ahí la respuesta anterior.

Sin embargo, es muy raro que pueda tener un control estricto sobre estos puntos de datos y, como tal, es posible que deba hacer correcciones o ajustes. No puedes hacer eso con las claves principales (bueno, puedes, pero puede ser un dolor).

Gracias @VahiD por las aclaraciones.

Alfa
fuente
no se recomienda usar claves primarias significativas, considere el siguiente escenario, alguien ingresó un número de licencia incorrecto y ha utilizado esta identificación en 3-4 tablas como clave externa, ¿cómo soluciona este error? simplemente editar el número de licencia no podría ser suficiente en este caso.
VahiD
1
Divertido: leí tu comentario y pensé "sí, por supuesto", luego volví a leer mi respuesta y pensé "¿dije eso"? Es curioso cómo cambian las cosas en un par de años. Probablemente venía de un contexto más teórico, pero a menos que tenga un control estricto sobre él (rara vez) no proporciona muchos beneficios. Actualizaré la respuesta.
Alfa
voto a favor para el desarrollo en los años :)
VahiD
1

El uso de ID de incremento automático puede filtrar información sobre su actividad comercial. Si tiene una tienda y la utiliza order_idpara identificar públicamente una compra, cualquiera puede averiguar su número de ventas mensuales por simple aritmética.

golopot
fuente
0

Otra cosa con cómo se generan los GUID. mrdenny señaló correctamente que incluso si se usa newsequentialid (), reiniciar las instancias hace que los nuevos valores comiencen con los "agujeros" que quedaron en el procesamiento anterior. Otra cosa que afecta a los GUID "secuenciales" es la tarjeta de red. Si no recuerdo mal, el UID de la NIC se usa como parte del algoritmo GUID. Si se reemplaza una NIC, no hay garantía de que el UID sea un valor más alto para mantener el aspecto secuencial de las cosas. Tampoco estoy seguro de cómo las NIC múltiples pueden afectar la asignación de valores usando el algoritmo.

Solo un pensamiento y espero estar recordando correctamente. ¡Que tengas un gran día!

bobo8734
fuente
2
Bienvenido a Administradores de bases de datos, bobo8734. ¿Podría encontrar algunas fuentes para estos comentarios? Si no está seguro de ellos, tal vez sea mejor que le sirvan como comentario (cuando tenga el representante) que una respuesta independiente.
LowlyDBA
-6

Usa ambos

Use int / Bigint para la clave principal, ya que es fácil de mantener y usar como relaciones de clave externa.

Pero vincule una columna al GUID para que cada fila también tenga una columna única

Abdul Hannan Ijaz
fuente
2
Explicar su razonamiento detrás de esta sugerencia no dañaría a nadie, estoy seguro.
Andriy M
GUID tiene 36 caracteres de largo será difícil de leer en caso de que esté buscando un caso específico ..
Abdul Hannan Ijaz
1
Está bien, pero eso realmente no explica por qué el OP debe usar ambos inty guid, como sugiere en su respuesta. Y además, no estaba hablando de explicarme tu sugerencia solo a mí, mi punto era que tal vez quieras actualizar tu respuesta . Por cierto, ¿eres consciente de que otro respondedor ya ha sugerido lo mismo (más o menos) que tú ?
Andriy M
Sí, quise decir lo mismo ... genial BTW :)
Abdul Hannan Ijaz