2011-01-10 24 views
18

Estoy viendo los pros y los contras de estos tres métodos principales para obtener claves principales para las filas de la base de datos.¿Cómo elegir entre UUID, claves autoincrement/sequence y tablas de secuencia para claves primarias de base de datos?

Suponiendo que estoy usando una base de datos que admita más de uno de estos métodos, ¿existe una heurística simple para determinar cuál es la mejor opción para mí?

¿Cómo pueden tenerse en cuenta las consideraciones tales como maestros distribuidos/múltiples, requisitos de rendimiento, uso de ORM, seguridad y pruebas?

¿Hay algún inconveniente inesperado que pueda surgir?

+0

¿qué tipo de proveedor de idioma/orm usas? –

+0

Java. Ya sea Hibernate o Eclipselink. Aunque realmente estoy buscando más puntos genéricos en cuanto a sus ventajas y desventajas. – Tim

+0

El idioma o el método de acceso no deberían tener ninguna relación con la clave principal. La clave primaria identificará uniqulymente el objeto, entidad, persona, etc. Si la clave principal es amplia, navrchar (25) para mí, entonces use un subsitio entero como columna de identidad. pensar en los datos que se almacenarán y modelar el almacenamiento de los datos para proporcionar la mejor OLAP, velocidad de transacción o velocidad de informes que se necesita. –

Respuesta

22

UUID

A menos que estos se generan "en el aumento de secuencia monótona" que pueden herir drásticamente índices/fragmentos. El soporte para la generación de UUID varía según el sistema. Aunque se puede utilizar, no usaría un UUID como mi primario agrupado index/PK en la mayoría de los casos. Si es necesario, probablemente lo convertiría en una columna secundaria, tal vez indizada, tal vez no.

Algunas personas argumentan que los UUID se pueden usar para generar/fusionar registros de forma segura desde un número arbitrario de sistemas. Mientras que un UUID (dependiendo del método) generalmente tiene una probabilidad astronómicamente pequeña de colisión, es posible, al menos con alguna entrada externa o muy mala suerte :) - generar colisiones. Creo que solo se debe transmitir un PK verdadero entre los sistemas, lo que, en mi opinión, no es (o no debería ser) un U1200 generado por la base de datos en la mayoría de los casos.

claves incremento automático/secuencias y tablas de secuencia

Esto realmente depende de lo que la base de datos soporta bien. Algunas bases de datos admiten secuencias que son más flexibles que un simple "auto-incremento". Esto puede o no ser deseable (o puede ser la única forma de este tipo de tarea, incluso). Las tablas de secuencias generalmente son más flexibles aún, pero si se necesita este tipo de "flexibilidad", me sentiría tentado a volver y visitar el patrón de diseño, especialmente si implica el uso de desencadenantes. Aunque me desagradan "limitar los ORM", eso también puede hacer una diferencia al elegir el autoincremento "simple" o el tipo de secuencia/soporte de base de datos.

Independientemente del método utilizado, cuando se utiliza claves primarias sustitutas, la verdadera clave primaria debe ser identificado y codificado en el esquema todavía.

Además, defiendo que "la seguridad se compromete al exponer una PK de secuencia automática" es el resultado de exponer incorrectamente una propiedad de base de datos interna. Si bien es una forma muy sencilla de manejar el funcionamiento de CRUD, creo que hay una distinción entre las claves internas y las claves expuestas (por ejemplo, número de cliente bonito).

Sólo mis dos centavos.

Editar, respuestas adicionales a Tim:

creo que la verdadera cuestión vs PK generado es un muy buen uno y tengo que considerar también. Me gustaría UUID en general a los puntos que hagas. Mi duda era en tamaño vs. int/largo. No estaba al tanto de posibles desoptimizaciones de indexación, lo cual es mucho más importante para mí.

yo no realmente preocuparse por el tamaño - si un UUID es mejor, entonces es mejor. Si no es así, entonces no lo es. En el esquema general , los 12bytes extra sobre un int probablemente no harán mucha diferencia. SQL Server 2005+ admite la función de generación de UUID newsequentialid para evitar la fragmentación asociada con la generación de UUID normal. La página lo discute un poco. Estoy seguro de que otras bases de datos tienen soluciones similares.

Y por "codificado en el esquema", quiere usted decir más que añadir una restricción de unicidad?

Sí. La clave primaria no tiene que ser la única restricción [única]. Simplemente usando un sustituto PK no significa que el modelo de base de datos debe estar comprometida :-) índices adicionales también se puede utilizar para cubrir, etc.

Y por "distinción entre", ¿estás diciendo que primaria sustituta las llaves nunca se escapan?

La redacción en mi publicación inicial fue un poco difícil. No es "nunca" tanto como "si lo hacen y es importante, entonces ese es otro problema". A menudo, las personas se quejan de la inseguridad a través de números imaginables, p. si su pedido es 23, entonces es probable que haya un pedido 22 y 24, etc. Si esta es su "protección" y/o puede filtrar información confidencial, entonces el sistema ya está dañado. (La separación de identificadores internos y externos no soluciona de forma inherente este problema y aún se requiere autenticación/autorización. Sin embargo, es un problema planteado contra el uso de "identificadores secuenciales": me parece que codificar un nonce en URL distribuidas maneja este para mi uso -case bastante bien)

Más de lo que realmente quería conseguir a través:. el hecho de que el id sustituta PK 8942 pasa a ser no significa que es el fin 8942. es decir, según la "algunos campos son internos solo para db "diseño, el número de orden" puede no estar relacionado en absoluto en la superficie (pero es totalmente compatible con el modelo DB), como "# 2010-42c" o lo que tenga sentido para los requisitos del negocio. Es este número externo que debería estar expuesto en la mayoría de los casos.

Siento que a veces la clave generada es realmente la clave primaria de cierto como otros campos son mutables (por ejemplo. Usuario puede cambiar de correo electrónico y nombre de usuario).

Este puede ser el caso dentro de una base de datos y no voy a discutir esta declaración. Sin embargo, una vez más sosteniendo que los PK sustitutos son internos en la base de datos, solo asegúrese de exportar e importar tuplas que puedan identificarse correctamente. Si el nombre de usuario/correo electrónico puede cambiar, entonces esto bien podría incluir un UUID asignado en la creación de la cuenta, y podría ser el propio PK sustitutivo.

Por supuesto, como con todo, permanezca abierto y ajuste el modelo al problema, no el problema para el modelo :-) Para un servicio como Twitter, por ejemplo, usan su propio esquema de generación de números. Ver Twitter's new ID generation. A diferencia de [algunos] generación UUID, el enfoque de twitter (suponiendo que todos los servidores estén configurados correctamente) garantiza que ninguna de las máquinas/procesos distribuidos generará una ID duplicada, requiere solo 64 bits y mantiene un orden aproximado (los bits más significativos tienen marca de tiempo). (El número de registros generados por Twitter puede no estar de ninguna manera relacionado con los requisitos locales ;-)

Happy coding.

+0

Creo que la pregunta de PK generada frente a la verdadera es muy buena y debo considerarla también. Me gustaría UUID en general a los puntos que hagas. Mi duda era en tamaño vs. int/largo. No estaba al tanto de posibles desoptimizaciones de indexación, lo cual es mucho más importante para mí. Y por "codificado en el esquema", ¿quiere decir algo más que agregar una restricción de exclusividad? Y por "distinción entre", ¿estás diciendo que las claves primarias sustitutas nunca se filtran? Siento que a veces la clave generada es realmente la verdadera clave primaria ya que otros campos son mutables (por ejemplo, el usuario puede cambiar el correo electrónico y el nombre de usuario). – Tim

+0

@Tim Edits para usted. Disfrutar. –

+0

[_Más ideas sobre UUIDs_] (https://mariadb.com/kb/en/guiduuid-performance/) –

Cuestiones relacionadas