Saltar al contenido

PostgreSQL usando UUID vs Text como primario key

Esta reseña fue evaluado por nuestros especialistas para asegurar la exactitud de nuestra esta división.

Solución:

Cuando se trate de números UUID, guárdelos como tipo de datos uuid. Siempre. Simplemente no hay una buena razón para siquiera considerar text como alternativa La entrada y salida se realiza a través de la representación de texto de forma predeterminada de todos modos. El elenco es muy barato.

el tipo de datos text requiere más espacio en RAM y en disco, es más lento de procesar y más propenso a errores. La respuesta de @khampson proporciona la mayor parte de la razón. Curiosamente, no parece llegar a la misma conclusión.

Todo esto ha sido preguntado y respondido y discutido antes. Preguntas relacionadas sobre dba.SE con una explicación detallada:

  • ¿La búsqueda de índice sería notablemente más rápida con char vs varchar cuando todos los valores son 36 caracteres?
  • ¿Cuál es el tipo de datos óptimo para un campo MD5?

bigint?

Tal vez no necesite UUID (GUID) en absoluto. Considerar bigint en lugar de. Solo ocupa 8 bytes y es más rápido en todos los aspectos. Su rango a menudo se subestima:

-9223372036854775808 to +9223372036854775807

Eso es 9.2 millones de millones de millones numeros positivos OIA, nueve quintillones doscientos veintitrés mil trescientos setenta y dos billones treinta y seis mil millones.

Si quema 1 millón de ID por segundo (que es un número increíblemente alto), puede seguir haciéndolo por 292471 años. Y luego otros 292471 años para números negativos. “Decenas o centenas de millones” es ni siquiera cerca.

UUID es realmente solo para sistemas distribuidos y otros casos especiales.

Como mencionó @Kevin, la única forma de estar seguro con sus datos exactos sería comparar y contrastar ambos métodos, pero por lo que ha descrito, no veo por qué esto sería diferente de cualquier otro caso en el que un string era el primario key en una tabla o parte de un índice único.

Lo que se puede decir por adelantado es que sus índices probablemente serán más grandes, ya que tienen que almacenar más string valores, y en teoría las comparaciones para el índice tomarán un poco más de tiempo, pero no recomendaría una optimización prematura si hacerlo fuera doloroso.

En mi experiencia, he visto un rendimiento muy bueno en un índice único usando md5sums en una tabla con miles de millones de filas. Descubrí que tienden a ser otros factores sobre una consulta los que tienden a generar problemas de rendimiento. Por ejemplo, cuando termina necesitando consultar sobre una franja muy grande de la tabla, digamos cientos de miles de filas, una exploración secuencial termina siendo la mejor opción, así que eso es lo que elige el planificador de consultas, y puede llevar mucho más tiempo. .

Hay otras estrategias de mitigación para ese tipo de situación, como fragmentar la consulta y luego UNIONing los resultados (por ejemplo, una simulación manual del tipo de cosa que se haría en Colmena o Impala en el Hadoop esfera).

Re: su preocupación sobre la indexación de texto, aunque estoy seguro de que hay algunos casos en los que un conjunto de datos produce un key distribución tal que funciona terriblemente, los GUID, al igual que md5sums, sha1, etc., deberían indexarse ​​bastante bien en general y no requerir escaneos secuenciales (a menos que, como mencioné anteriormente, consulte una gran parte de la tabla).

Uno de los grandes factores sobre el rendimiento de un índice es cuántos valores únicos hay. Por esa razón, no es probable que un índice booleano en una tabla con una gran cantidad de filas ayude, ya que básicamente terminará teniendo una gran cantidad de colisiones de filas para cualquiera de los valores (true, falsey potencialmente NULL) en el índice. Un índice GUID, por otro lado, es probable que tenga una gran cantidad de valores sin colisión (definitivamente en teoría, ya que son GUID).

Editar en respuesta al comentario de OP:

Entonces, ¿está diciendo que un GUID de UUID es lo mismo que un GUID de texto en lo que respecta a la indexación? Toda nuestra estructura de tabla usa campos de texto con un guid-like string, pero no estoy seguro de que Postgre lo reconozca como Guid. solo un string eso pasa a ser único.

No es literalmente lo mismo, no. Sin embargo, estoy diciendo que deberían tener un rendimiento muy similar para este caso en particular, y no veo por qué vale la pena optimizar desde el principio, especialmente dado que usted dice que hacerlo sería una tarea muy complicada.

Siempre puede cambiar las cosas más tarde si, en su entorno específico, tiene problemas de rendimiento. Sin embargo, como mencioné anteriormente, creo que si llega a ese escenario, hay otras cosas que probablemente producirían un mejor rendimiento que cambiar los tipos de datos PK.

Un UUID es un tipo de datos de 128 bits (es decir, 16 bytes), mientras que el texto tiene 1 o 4 bytes de sobrecarga más la longitud real del string. Para un GUID, eso significaría un mínimo de 33 bytes, pero podría variar significativamente dependiendo de la codificación utilizada.

Entonces, con eso en mente, ciertamente los índices de UUID basados ​​en texto serán más grandes ya que los valores son más grandes, y comparar dos cadenas con dos valores numéricos es, en teoría, menos eficiente, pero no es algo que probablemente marque una gran diferencia en este caso, al menos no los casos habituales.

No optimizaría por adelantado cuando hacerlo sería un costo significativo y es probable que nunca se necesite. Ese puente se puede cruzar si llega ese momento (aunque primero buscaría otras optimizaciones de consulta, como mencioné anteriormente).

En cuanto a si postgres conoce el string es un GUID, definitivamente no lo hace por defecto. En lo que se refiere, es solo un único string. Pero eso debería estar bien para la mayoría de los casos, por ejemplo, filas coincidentes y demás. Si necesita algún comportamiento que requiera específicamente un GUID (por ejemplo, algunas comparaciones no basadas en la igualdad donde una comparación de GUID puede diferir de una comparación puramente léxica), entonces siempre puede emitir el string a un UUID, y postgres tratará el valor como tal durante esa consulta.

por ejemplo, para una columna de texto footu puedes hacer foo::uuid para echarlo a un uuid.

También hay un módulo disponible para generar uuids, uuid-ossp.

Aquí tienes las reseñas y valoraciones

Recuerda que puedes dar recomendación a esta reseña si te fue de ayuda.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *