serial primary database database-design sequence uuid auto-increment

database - primary - ¿Cómo elegir entre los UUID, las claves de autoincremento/secuencia y las tablas de secuencia para las claves primarias de la base de datos?



uuid vs id (1)

UUIDs

A menos que estos se generen "en una secuencia monotónica creciente", pueden dañar drásticamente / fragmentar los índices. El soporte para la generación de UUID varía según el sistema. Mientras sea utilizable, no usaría un UUID como mi índice / PK en clúster principal en la mayoría de los casos. De ser necesario, probablemente lo convertiría en una columna secundaria, quizás indexada, tal vez no.

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

Autoincremento / secuencia de claves 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 "incremento automático". Esto puede o no ser deseable (o puede ser la única manera de este tipo de tarea, simplemente, incluso). Las tablas de secuencias son generalmente más flexibles aún, pero si se necesita este tipo de "flexibilidad", me sentiría tentado a regresar y visitar el patrón de diseño, especialmente si involucra el uso de activadores. Si bien no me gusta "limitar los ORM", eso también puede marcar la diferencia en la elección de los incrementos automáticos "más simples" o los tipos de secuencia / compatibilidad con bases de datos.

Independientemente del método utilizado, cuando se usan claves primarias sustitutas , la clave primaria verdadera aún debe identificarse y codificarse en el esquema.

Además, sostengo que "los compromisos de seguridad a través de la exposición de una PK de secuencia automática" son el resultado de la exposición incorrecta de una propiedad de la base de datos interna . Aunque es una forma muy simple de manejar la operación CRUD, creo que hay una distinción entre las teclas internas y las claves expuestas (por ejemplo, un número de cliente bonito).

Sólo mis dos centavos.

Editar , respuestas adicionales a Tim:

Creo que la pregunta de PK generada contra verdadera es muy buena y también debo tener en cuenta. Me gustaría UUIDs en general a los puntos que haces. Mi duda fue en tamaño vs. int / long. No estaba al tanto de posibles des-optimizaciones de indexación, lo que es una preocupación mucho más grande para mí.

Realmente no me preocuparía por el tamaño; si un UUID es el mejor, entonces es el mejor. Si no lo es, entonces no lo es. En el esquema general, los 12 bytes adicionales sobre un int probablemente no supondrán una gran diferencia. SQL Server 2005+ admite la newsequentialid 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 decir más que agregar una restricción de singularidad?

Sí. La clave principal no tiene que ser la única restricción [única]. El solo uso de un PK sustituto no significa que el modelo de base de datos deba verse comprometido :-) También se pueden usar índices adicionales para cubrir, etc.

Y por "distinción entre", ¿estás diciendo que las claves primarias sustitutas nunca se filtran?

La redacción en mi post inicial fue un poco difícil. No es "nunca" tanto como "si lo hacen y importa , ese es otro problema". A menudo, las personas se quejan de inseguridad a través de números adivinables: por ejemplo, si su pedido es 23, 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 tiene fallas. (La separación de los identificadores internos y externos no soluciona de manera inherente este problema y la autenticación / autorización sigue siendo necesaria. Sin embargo, es un problema planteado en comparación con el uso de "identificadores secuenciales". bastante bien.)

Más de lo que realmente quería transmitir : el hecho de que la ID de PK sustituta sea 8942 no significa que sea el orden 8942. Es decir, mantener "algunos campos son internos solo para db", el número del pedido " "podría no tener ninguna relación en la superficie (pero se admite completamente en el modelo DB), como" # 2010-42c "o lo que tenga sentido para los requisitos del negocio. Es este número externo el que debería estar expuesto en la mayoría de los casos.

Creo que a veces la clave generada es realmente la verdadera clave principal, ya que otros campos son mutables (por ejemplo, el usuario puede cambiar el correo electrónico y el nombre de usuario).

Este puede ser el caso dentro de una base de datos y no discutiré esta afirmación. Sin embargo, una vez más, manteniendo que las PK sustitutas son internas a la base de datos, solo asegúrese de exportar / importar tuplas que puedan estar bien identificadas. Si el nombre de usuario / correo electrónico puede cambiar, esto podría incluir un UUID asignado en el momento de la creación de la cuenta, y muy bien podría ser el propio PK sustituto.

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

Feliz codificacion

Estoy viendo los pros y los contras de estos tres métodos principales de crear claves primarias para las filas de la base de datos.

Entonces, asumiendo que estoy usando una base de datos que admite más de uno de estos métodos, ¿hay una heurística simple para determinar cuál sería la mejor opción para mí?

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

¿Algún inconveniente inesperado que uno pueda encontrar?