¿Cuáles son los inconvenientes de usar UUID o GUID como clave principal?


61

Me gustaría construir un sistema distribuido. Necesito almacenar datos en bases de datos y sería útil usar un UUID o un GUID como clave principal en algunas tablas. Supongo que es un inconveniente con este diseño ya que el UUID / GUID es bastante grande y son casi aleatorios. La alternativa es utilizar un INT o LONG de incremento automático.

¿Cuáles son los inconvenientes de usar UUID o GUID como clave principal para mis tablas?

Probablemente usaré Derby / JavaDB (en los clientes) y PostgreSQL (en el servidor) como DBMS.


¿Por qué sería útil? ¿En qué inconvenientes estás más enfocado? La respuesta a cada pregunta de DB tan vaga es "depende". ¿Puede darnos más detalles? ¿Estás más interesado en el rendimiento de lectura o escritura? ¿De qué nivel de distribución estamos hablando?
Brian Ballsun-Stanton

@Brian: UUID en sistemas distribuidos es útil ya que puede crear la clave primaria en los clientes y luego cargar los datos de forma asíncrona en el servidor. Estoy pensando principalmente en leer los inconvenientes de rendimiento. ¿Usar muchas uniones en UUID no es tan bueno? Por ejemplo, un cliente agrega un artículo (UUID, nombre, proveedor, creador) a un sistema de inventario, y luego la base de datos local se sincroniza con la base de datos central en el servidor.
Jonas

1
Creo que sin algunos comentarios más clarificadores sobre esto, a lo sumo será "depende". Sin esos, voy por VtC.
jcolebrand

Hay un artículo que habla sobre el efecto GUID versus no GUID en los índices agrupados en SQL Server que puede encontrar interesante a pesar de que está relacionado con un producto SQL diferente: x.co/Twpp
Jeff

Noté que Derby doc no enumera UUID como un tipo de datos. Es posible que desee considerar una alternativa como el Motor de base de datos H2 (una base de datos Java pura como Derby) que enumera un tipo de datos UUID . Por supuesto, Postgres tiene un excelente soporte para almacenar , indexar y generar valores UUID de manera eficiente .
Basil Bourque

Respuestas:


29

Depende de la función de generación y el tamaño de las tablas finales.

Los GUID están destinados a ser identificadores únicos a nivel mundial . Como se discutió en la documentación de Postgres 8.3, no existen metodologías que sean universalmente apropiadas para generar estos identificadores, pero postgreSQL se entrega con algunos candidatos más útiles.

Desde el alcance de su problema y la necesidad de escrituras fuera de línea , ha descartado claramente el uso de cualquier cosa que no sea un GUID, y por lo tanto no hay ventajas compensatorias de otros esquemas.

Desde un punto de vista funcional, la longitud de la clave generalmente no es un problema en ningún tipo de sistema moderno, dependiendo del número de lecturas y el tamaño de la tabla. Como metodología alternativa, los clientes fuera de línea podrían agrupar nuevos registros sin una clave primaria y simplemente insertarlos al volver a conectarlos. Como postgreSQL ofrece el tipo de datos "Serie", los clientes nunca necesitarán determinar la ID si pueden realizar una escritura simple en la base de datos.


3
Maldita sea que duermas, te has ido y dejas que Brian responda la pregunta. Sí, el requisito de "actualizaciones fuera de línea" cambió por completo todo el concepto allí.
jcolebrand

Muahahahaah! :: gira el bigote malvadamente ::
Brian Ballsun-Stanton

1
Incluso con escrituras fuera de línea, sería posible usar INT. Por ejemplo, usando dos columnas {Node_ID, Item_ID}donde cada nodo tiene un Node_ID, y un Item_IDque se incrementa automáticamente por nodo.
Jonas

@Jonas ~ Sí, eso es factible. Sin embargo, una de las razones por las que la mayoría de las personas incluso contemplan los GUID es la replicación de contenido separado a nivel mundial en otras bases de datos. Quiero decir que el término en sí es más bien QED allí.
jcolebrand

Con respecto a las arquitecturas maestro / esclavo o clientes de conexión dispersa + arquitecturas del servidor principal, ¿podría ser factible utilizar un global_id (SERIAL) en el maestro y un global_id (BIGINT) + local_id (SERIAL) en los esclavos. Los esclavos hacen su trabajo local usando local_id y se comprometen cuando pueden con el maestro, el maestro recibe los datos y le otorga un global_id que devuelve al esclavo, el esclavo actualiza el campo global_id (para uso de referencia al hablar con el servidor u otro esclavos).
Mihai Stancu

22

Un consejo más: nunca use GUID como parte del índice agrupado. Los GUID no son secuenciales, por lo tanto, si forman parte del índice agrupado, cada vez que inserte un nuevo registro, la base de datos necesitará reorganizar todas sus páginas de memoria para encontrar el lugar correcto para la inserción, en caso de int (bigint) auto-increment, sería solo la última página.

Ahora, si observamos algunas realizaciones de db: 1.) MySQL: las claves principales están agrupadas, sin opción de cambiar el comportamiento; la recomendación es no usar GUID en absoluto aquí 2.) Postgres, MS-SQL: puede hacer GUID como clave primaria no agrupada y utilice otro campo como índice agrupado, por ejemplo, autoincrement int.


Lo que propone para Postgres también se puede hacer en MySQL, con una estructura ligeramente diferente: auto_increment PK (clave en clúster), GUID con índice único (sin clúster).
ypercubeᵀᴹ

Esto no siempre es cierto. Dependiendo del rendimiento del sistema de disco, sincronizar el acceso a esa última página podría ser su cuello de botella. blog.kejser.org/2011/10/05/…
mwilson

2
"A diferencia de Microsoft SQL Server, la agrupación en un índice en PostgreSQL no mantiene ese orden. Debe volver a aplicar el proceso CLUSTER para mantener el orden". ¿Cómo mejora CLUSTER ON el rendimiento del índice?
bartolo-otrit

Una versión más condensada de la información @ bartolo-otrit vinculada a: stackoverflow.com/a/4796685/1394393 . Esta respuesta realmente no me parece relevante, ya que esta pregunta es sobre PG y parece asumir similitudes con SQL Server y MySQL que no existen.
jpmc26

database would need to rearrange all its memory pages to find the right place for insertion=> No creo que sea el caso con Postgres, ya que la agrupación es opcional y las nuevas filas se almacenan sin ordenar.
Flavien

3

Depende.

En serio, con todo lo que has dado hasta ahora, esto es lo más lejos que puedes llegar.

¿Por qué sería útil usar UUID? ¿Por qué no usarás INTs? ¿Por qué no puedes simplemente indexar UUIDs más tarde? ¿Entiende lo que significa tener una lista ordenada con la clave de un UUID e insertar un UUID aleatorio (no secuencial) después de unos pocos millones de filas?

¿En qué plataforma se ejecutará esto? Cuantos discos Cuantos usuarios Cuantos registros


77
Como escribí en mi comentario, si uso UUID, los clientes pueden agregar filas a la base de datos sin una conexión con el servidor y luego sincronizarlas con el servidor. No puedo hacer eso si uso INTs para la clave primaria, porque varios clientes pueden usar la misma clave primaria para diferentes elementos en ese momento. Bueno, es inútil ordenar la lista en una columna UUID, sería más útil ordenarla en una columna de marca de tiempo. No, no sé qué significa insertar un UUID no secuencial aleatorio después de unos pocos millones de filas, por eso hago esta pregunta.
Jonas

La aplicación estará escrita en Java y los clientes pueden usar Windows, Mac o Linux. Los clientes utilizarán computadoras de escritorio comunes que generalmente tienen un disco. La cantidad de usuarios y registros depende de cuántos clientes obtengo, pero serán alrededor de 5000 por cliente y cliente.
Jonas

1
El comentario fuera de línea cambió todo. ¿Ves qué más detalles hace?
jcolebrand
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.