sql - tipos - ¿Cuáles son los motivos*no*para usar un GUID para una clave principal?
tipos de restricciones en base de datos (8)
Aún implementas la clave natural de cada mesa, ¿no? - Las claves GUID por sí solas obviamente no evitarán la duplicación de datos, la redundancia y la consiguiente pérdida de integridad de los datos.
Suponiendo que usted haga cumplir otras claves, entonces agregar GUIDs a cada tabla sin excepción probablemente solo agregue complejidad y sobrecarga innecesarias. En realidad, no hace que sea más fácil fusionar datos en diferentes tablas porque de todos modos tiene que modificar / quitar la duplicación de la otra clave (s) de la tabla. Sugiero que evalúe el uso de un sustituto GUID caso por caso. Tener una regla general para cada tabla no es necesario ni útil porque cada tabla modela una cosa diferente después de todo.
Cada vez que diseño una base de datos, empiezo automáticamente con una clave principal GUID de generación automática para cada una de mis tablas (excepto las tablas de búsqueda)
Sé que nunca perderé el sueño por duplicar claves, fusionar tablas, etc. Para mí, tiene sentido filosóficamente que un registro determinado sea único en todos los dominios, y que esa singularidad se represente de manera consistente de una tabla a otra. .
Me doy cuenta de que nunca será la mejor opción, pero dejando de lado el rendimiento, me gustaría saber si hay argumentos filosóficos contra esta práctica.
En base a las respuestas, permítanme aclarar:
Estoy hablando de usar constantemente una clave sustituta GUID como clave principal, independientemente de si y cómo se diseñan claves naturales o secuenciales en una tabla. Estas son mis suposiciones:
- La integridad de los datos basada en claves naturales se puede diseñar para, pero no se supone.
- La función de una tecla principal es la integridad referencial, independientemente del rendimiento, la secuencia o los datos.
Agregando a ewwwn:
Pros
- Hace casi imposible que los desarrolladores expongan "accidentalmente" la clave sustituta a los usuarios (a diferencia de los enteros donde ocurre casi todo el tiempo).
- Facilita la fusión de bases de datos de varios órdenes de magnitud más simple que el manejo de columnas de identidad.
Contras
- Más gordo. El problema real de que sea más gordo es que consume más espacio por página y más espacio en los índices haciéndolos más lentos. El espacio de almacenamiento adicional de Guids es francamente irrelevante en el mundo de hoy.
- Debe tener cuidado sobre cómo se crean los nuevos valores. Los valores verdaderamente aleatorios no tienen un buen índice. Se ve obligado a utilizar un GUI COMB o alguna variante que agregue un elemento secuencial a la GUID.
Jeff Atwood habla de esto en gran detalle:
http://www.codinghorror.com/blog/2007/03/primary-keys-ids-versus-guids.html
Pros Guid:
Único en cada mesa, cada base de datos, cada servidor
Permite una fácil fusión de registros de diferentes bases de datos
Permite una fácil distribución de bases de datos en múltiples servidores
Puede generar identificadores 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
Contraste Guid:
Es una friolera 4 veces más grande que el valor del índice tradicional de 4 bytes; esto puede tener graves implicaciones de rendimiento y almacenamiento si no tiene cuidado
Es complicado depurar (donde userid = ''{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}'')
Los GUID generados deben ser parcialmente secuenciales para un mejor rendimiento (p. Ej., Newsequentialid () en SQL 2005) y para permitir el uso de índices agrupados
Los GUID pueden parecer una opción natural para su clave principal, y si realmente debe hacerlo, probablemente podría argumentar que debe usarla para la PRIMARY KEY de la tabla.
Lo que recomiendo encarecidamente que no haga es usar la columna GUID como la clave de clúster , que SQL Server realiza de manera predeterminada, a menos que específicamente le diga que no lo haga. La razón principal de esto es el rendimiento, que vendrá y lo morderá en el camino ... (lo hará, créame, solo es cuestión de tiempo), además de un desperdicio de recursos (espacio en disco y memoria RAM en su Servidor SQL máquina) que realmente no es necesario.
Realmente necesitas separar dos cuestiones:
1) la clave primaria es una construcción lógica: una de las claves candidatas que identifica de forma única y confiable cada fila en su tabla. Esto puede ser cualquier cosa, en realidad, una INT, un GUID, una cadena, elija lo que tenga más sentido para su escenario.
2) la clave del clúster (la columna o columnas que definen el "índice agrupado" en la tabla): esta es una cuestión relacionada con el almacenamiento físico , y aquí, un tipo de datos pequeño, estable y en constante aumento es su mejor opción - INT o BIGINT como su opción predeterminada.
De forma predeterminada, la clave principal en una tabla de SQL Server también se usa como la clave de clúster, ¡pero eso no tiene por qué ser así! Personalmente, he visto aumentos de rendimiento masivos al dividir la Clave primaria / en clúster basada en GUID anterior en dos claves separadas: la clave primaria (lógica) en el GUID y la clave de agrupación (ordenamiento) en una IDENTIDAD INT separada (1, 1) columna.
Como Kimberly Tripp , la reina de la indexación, y otros han declarado muchas veces, un GUID ya que la clave de clúster no es óptima, ya que debido a su aleatoriedad generará una fragmentación masiva de páginas e índices y, en general, un mal rendimiento.
Sí, lo sé, hay newsequentialid()
en SQL Server 2005 en adelante, pero incluso eso no es verdaderamente secuencial y, por lo tanto, también adolece de los mismos problemas que el GUID, pero un poco menos prominente.
Luego hay otro problema que considerar: la clave de agrupamiento en una tabla se agregará a todas y cada una de las entradas de todos y cada uno de los índices no agrupados en su tabla, por lo que realmente desea asegurarse de que sea lo más pequeña posible. Normalmente, una INT con más de 2 mil millones de filas debería ser suficiente para la gran mayoría de las tablas, y en comparación con un GUID como clave de agrupamiento, puede ahorrarse cientos de megabytes de almacenamiento en el disco y en la memoria del servidor.
Cálculo rápido: utilizando INT frente a GUID como clave principal y de agrupación en clúster:
- Tabla base con 1''000''000 filas (3.8 MB vs. 15.26 MB)
- 6 índices no agrupados (22.89 MB vs. 91.55 MB)
TOTAL: 25 MB vs. 106 MB - ¡y eso es solo en una sola mesa!
Algo más para pensar, material excelente de Kimberly Tripp: ¡léelo, léelo de nuevo, digerirlo! Es el evangelio de indexación de SQL Server, realmente.
- GUID como clave principal y / o clave agrupada
- El debate sobre el índice agrupado continúa
- ¡Clave de agrupamiento cada vez mayor: el debate sobre el índice agrupado .......... otra vez!
Bagazo
Me pregunto por qué no hay un tipo estándar de "miniGUID". Parecería que realizar un hash decente en un GUID debería arrojar un número de 64 bits que tendría una probabilidad trivial de duplicación en cualquier universo que no tenga un billón o más de cosas en él. Como el universo en el que se utilizan la mayoría de los identificadores GUID / miniGUID nunca crecerá más allá de un millón de cosas, mucho menos de mil millones, creo que un miniGuid de 8 bytes más pequeño sería muy útil.
Eso no implicaría, por supuesto, que deba usarse como un índice agrupado; eso impediría en gran medida el rendimiento. No obstante, un miniGUID de 8 bytes solo desperdiciará un tercio del espacio de un GUID completo (en comparación con un índice de 4 bytes).
Puedo ver que los identificadores de la aplicación o de la empresa son únicos y se representan de manera consistente en todos sus dominios (es decir, porque pueden abarcar más de una base de datos), pero un GUID es excesivo para estos fines. Supongo que son populares porque están disponibles de forma inmediata y el diseño y la implementación de una ''clave empresarial'' requiere tiempo y esfuerzo. La regla al diseñar un identificador artificial es hacerlo lo más simple posible pero no más simple. IDENTITY
es demasiado simple, un GUID no es lo suficientemente simple.
Las entidades que existen fuera de la aplicación / empresa generalmente tienen sus propios identificadores (por ejemplo, un automóvil tiene un VIN, un libro tiene un ISBN, etc.) mantenido por una fuente confiable externa y en tales casos el GUID no agrega nada. Así que supongo que el argumento filosófico en contra del que estoy hablando aquí es que usar un identificador artificial en cada tabla es innecesario.
Respuesta simple: no es relacional.
El registro (según lo definido por el GUID) puede ser único, pero no se puede decir que ninguno de los atributos asociados ocurra de forma exclusiva con ese registro.
Usar un GUID (o cualquier clave puramente sustituta) no es más relacional que declarar un archivo plano como relacional, sobre la base de que cada registro se puede identificar por su número de fila.
Una razón potencialmente importante, pero a menudo no se piensa, es si es posible que deba proporcionar compatibilidad con una base de datos Oracle en el futuro.
Como Oracle no tiene un tipo de datos de columna uniqueid, puede llevar a una pesadilla cuando tiene dos tipos de datos diferentes para la misma clave primaria en dos bases de datos diferentes, especialmente cuando se trata de un ORM.