Excelente enfoque. En mi empresa actual estamos trabajando con un enfoque dual. Tenemos Ids autoincrementales como primary key y UUIDs para comunicacion entre sistemas
La mejor opción es lo que dices de los dos pero hay varias precisiones. En algunos motores el UUID se almacena como un texto pero en la mayoria se almacena como un espacio binario de 16 bytes, o 128 bits. Y acá es donde el tamaño importa. Si cada caracter es ASCII, pesa 7 bits, y la representacion puede ser de 32 a 36 caracteres, tendias en total 32 * 7 bits (aunque por lo general se suelen utilizar mínimo 8bits -1 byte- por caracter), que es casi el doble de 128. Por otra parte, aunque la indexación es importante, no es lo mismo organizar texto que organizar números y esto es algo que la base de datos tendrá que hacer de forma autónoma o de vez en cuando obligarla a hacerlo en el mantenimiento de los mismos. Entiendo la parte de seguridad pero, como bien señala la solucion es que, una cosa puede ser lo que tengas en tu DB, otra lo que muestras en tu APP y otra muy distinta lo expones a los Consumers de esa APP. Pero hay algo muy importante que no se mencionó y es la fragmentación de las tablas y los índices. Y eso es un problema muy chungo que casi nadie le pone atención. Por eso es que puede ayudar mucho si la llave es secuencial. En SQL Server, tu puedes obtener incluso un UUID 'secuencial' para evitar el problema de la fragmentación pero eso es otro tema. Lo importante es ser consciente de esto que menciono y de que no es lo mismo organizar un índice a organizar el cluster de una tabla o una tabla sin cluster, y no es lo mismo tampoco leer y escribir en esos objetos. El tema se resume a que la identidad no necesariamente se da por la llave primaria, sino que puede darse por un índice único. Es decir, la llave primaria puede ser solo para organizar tus registros físicamente (si utilizas un cluster) garantizando la eficiencia a la hora de escribir y buscar registros. Pero, la identidad de ella puede ser otra cosa, algo más universal y largo, como un UUID. De hecho, siempre me he planteado el hecho que, no somos conscientes que la identidad de un registro sólo busca simplificar y reducir la densidad de la información de una tabla, es por eso que, no es la misma densidad de una tabla paramétrica a una transaccional, y esta densidad tambien se puede comparar entre tablas de igual categoría. Si pensamos en conjuntos: Profesiones < Personas, Pais < Ciudad < Lugares, Por este motivo tambien se piensa en numeros enteros. La información contenida en un conjunto, independiente de su información, se puede reducir a un espacio de 2^N donde N es el numero de bits. De este modo tenemos 256, 65536.. valores distintos. Y uno puede escoger el espacio en el que va a ubicar el conjunto de registros. Tu identidad es tu ADN (conjunto universal), pero en tu pais, pueden simplificarte dandote un número de identificación de ciudadano (subconjunto), pero si eres contribuyente te simplifican aún más (subconjunto del subconjunto), y así y así, te van catalogando en varios subconjuntos anidados haciendo que, identificarte inquivocamente en un conjunto sea más fácil. Basicamente en eso consisten las tablas de las DB relacionales. Se trata de identificar un registro en el conjunto (tabla) que corresponde. Incluso, yo en algun momento he discutido sobre la necesidad de tener autonuméricos negativos y comprender que el 0 no es ausencia de valor como se conciben en ORMs tipo EntityFramework. Y en cuanto a los UUID, entre más aleatorios sean, en realidad es mucho mejor, pero claro, deberán ser indexados y dichos índices tener mantenimiento constante para evitar la fragmentación.
Este es un tema a tomar con mucho cuidado, el UUID puede ser la solución ideal en términos de portabilidad y seguridad, sin embargo, el términos de rendimiento en aplicaciones grandes, considera que incrementas sustancialmente el consumo de disco, por ende se aumenta la grabación y lectura de disco y el consumo de memoria de procesamiento, solo usaria UUID para temas de auditoria y para compartir información entre compañías.
una solucion alternativa que realize fue agregar un campo ExternalId que el cliente envia en la creacion, y para los get lo busco con el ExternaId, pero para las consultas con join trabajo con el id numerico.
@NetMentor Te he conocido hace poco y estoy muy contento porque tienes muy buen contenido. Te queria plantear una pregunta sobre los identiticadores. Yo por norma general, en las aplicaciones en las que he trabajado, normalmente es el backend el que se encarga de generarar los identificadores en la Creacion de una entidad (ya sea la bbdd por autoincremental o guid desde codigo). Que opinion te merece que sea el cliente (frontal) el que sea responsable de generar su propio identificador? Muchas gracias
Piedes hacer un vídeo explicando los beneficios de usar el id compuesto. He visto ids con formato uuid::order::item siguiendo tu ejemplo, pero no veo el caso de uso
Yo creo que el uso de UUID sólo es realmente necesario cuando se vayan a utilizar bases de datos distribuidas y evitar que colisionen las PK. Usar IDs por defensive programming es, en mi opinión, sobre ingeniería.
Me da intriga como descubrieron que el alumno podía ver todas las notas, me imagino que alguien se enteró y le llegó a la empresa, si no por logs es casi imposible salvo que se la vean venir (que no era el caso)
No me hace gracia el tema del UUID porque rompe la naturaleza de la base de datos, ya que hay que crearlo desde el código. Si tienes que importar datos a la base de datos, tendrías que crear primero todos los UUIDs por separado.
Blog : www.netmentor.es/entrada/primary-key-uuid-vs-autoid
Twitter twitter.com/NetMentorTw
Excelente enfoque. En mi empresa actual estamos trabajando con un enfoque dual. Tenemos Ids autoincrementales como primary key y UUIDs para comunicacion entre sistemas
La mejor opción es lo que dices de los dos pero hay varias precisiones.
En algunos motores el UUID se almacena como un texto pero en la mayoria se almacena como un espacio binario de 16 bytes, o 128 bits.
Y acá es donde el tamaño importa. Si cada caracter es ASCII, pesa 7 bits, y la representacion puede ser de 32 a 36 caracteres, tendias en total 32 * 7 bits (aunque por lo general se suelen utilizar mínimo 8bits -1 byte- por caracter), que es casi el doble de 128.
Por otra parte, aunque la indexación es importante, no es lo mismo organizar texto que organizar números y esto es algo que la base de datos tendrá que hacer de forma autónoma o de vez en cuando obligarla a hacerlo en el mantenimiento de los mismos.
Entiendo la parte de seguridad pero, como bien señala la solucion es que, una cosa puede ser lo que tengas en tu DB, otra lo que muestras en tu APP y otra muy distinta lo expones a los Consumers de esa APP. Pero hay algo muy importante que no se mencionó y es la fragmentación de las tablas y los índices. Y eso es un problema muy chungo que casi nadie le pone atención. Por eso es que puede ayudar mucho si la llave es secuencial.
En SQL Server, tu puedes obtener incluso un UUID 'secuencial' para evitar el problema de la fragmentación pero eso es otro tema. Lo importante es ser consciente de esto que menciono y de que no es lo mismo organizar un índice a organizar el cluster de una tabla o una tabla sin cluster, y no es lo mismo tampoco leer y escribir en esos objetos.
El tema se resume a que la identidad no necesariamente se da por la llave primaria, sino que puede darse por un índice único. Es decir, la llave primaria puede ser solo para organizar tus registros físicamente (si utilizas un cluster) garantizando la eficiencia a la hora de escribir y buscar registros. Pero, la identidad de ella puede ser otra cosa, algo más universal y largo, como un UUID.
De hecho, siempre me he planteado el hecho que, no somos conscientes que la identidad de un registro sólo busca simplificar y reducir la densidad de la información de una tabla, es por eso que, no es la misma densidad de una tabla paramétrica a una transaccional, y esta densidad tambien se puede comparar entre tablas de igual categoría.
Si pensamos en conjuntos: Profesiones < Personas, Pais < Ciudad < Lugares,
Por este motivo tambien se piensa en numeros enteros. La información contenida en un conjunto, independiente de su información, se puede reducir a un espacio de 2^N donde N es el numero de bits. De este modo tenemos 256, 65536.. valores distintos. Y uno puede escoger el espacio en el que va a ubicar el conjunto de registros.
Tu identidad es tu ADN (conjunto universal), pero en tu pais, pueden simplificarte dandote un número de identificación de ciudadano (subconjunto), pero si eres contribuyente te simplifican aún más (subconjunto del subconjunto), y así y así, te van catalogando en varios subconjuntos anidados haciendo que, identificarte inquivocamente en un conjunto sea más fácil. Basicamente en eso consisten las tablas de las DB relacionales. Se trata de identificar un registro en el conjunto (tabla) que corresponde.
Incluso, yo en algun momento he discutido sobre la necesidad de tener autonuméricos negativos y comprender que el 0 no es ausencia de valor como se conciben en ORMs tipo EntityFramework. Y en cuanto a los UUID, entre más aleatorios sean, en realidad es mucho mejor, pero claro, deberán ser indexados y dichos índices tener mantenimiento constante para evitar la fragmentación.
Este es un tema a tomar con mucho cuidado, el UUID puede ser la solución ideal en términos de portabilidad y seguridad, sin embargo, el términos de rendimiento en aplicaciones grandes, considera que incrementas sustancialmente el consumo de disco, por ende se aumenta la grabación y lectura de disco y el consumo de memoria de procesamiento, solo usaria UUID para temas de auditoria y para compartir información entre compañías.
hace un rato no te veia por cuestiones del trabajo pero cada video es una joya. Gracias por compartir tu conocimiento!
Me ha gustado mucho el vídeo. Da igual cuantos años lleve en esto, siempre se puedfe aprender perspectivas diferentes.
Tu contenido siempre es de calidad, te felicito y agradezco que lo compartas. Saludos desde Colombia.
yo uso combinados ids autonumeri cos y uuid para no exponer valores y lo sqids esta interesante para ofuscar valores 😮 gracias por el tip
En SQL Server tiene el tipo de datos uniqueidentifier crea un NEWID desde el mismo motor de base.
una solucion alternativa que realize fue agregar un campo ExternalId que el cliente envia en la creacion, y para los get lo busco con el ExternaId, pero para las consultas con join trabajo con el id numerico.
eso puede ser una solución cuando tu cliente son clientes externos o servicios, pero si el cliente es la UI pues no lo es 😅
@NetMentor Te he conocido hace poco y estoy muy contento porque tienes muy buen contenido.
Te queria plantear una pregunta sobre los identiticadores.
Yo por norma general, en las aplicaciones en las que he trabajado, normalmente es el backend el que se encarga de generarar los identificadores en la Creacion de una entidad (ya sea la bbdd por autoincremental o guid desde codigo).
Que opinion te merece que sea el cliente (frontal) el que sea responsable de generar su propio identificador?
Muchas gracias
mala idea, la generación de IDs tiene que ser responsabilidad del Back.
Que bueno! Muy interesante el tema ! Saludos profe
Pues los UUID en cuestión de seguridad son más eficientes y los SQUID me convencieron completamente para implementarlos en Backend.
Muy bueno el video, excelente
Piedes hacer un vídeo explicando los beneficios de usar el id compuesto. He visto ids con formato uuid::order::item siguiendo tu ejemplo, pero no veo el caso de uso
ninguno mas alla de que sea mas legible al ojo humano.
Ecelente :)
Yo creo que el uso de UUID sólo es realmente necesario cuando se vayan a utilizar bases de datos distribuidas y evitar que colisionen las PK. Usar IDs por defensive programming es, en mi opinión, sobre ingeniería.
una webapi monolito con cliente wpf desktop , tambien se deberia ofuscar?
yo considero que si
Me da intriga como descubrieron que el alumno podía ver todas las notas, me imagino que alguien se enteró y le llegó a la empresa, si no por logs es casi imposible salvo que se la vean venir (que no era el caso)
uno de los colegios llamo diciendo que un alumno nos habia hackeado
UUID es el ROWID de los '90
Otra alternativa seria usando el algoritmo HiLo no?
No me hace gracia el tema del UUID porque rompe la naturaleza de la base de datos, ya que hay que crearlo desde el código.
Si tienes que importar datos a la base de datos, tendrías que crear primero todos los UUIDs por separado.
IDs ofuscados y a otra cosa jeje
Hoy en día casi todas las bbdd tienen una función para generar uuid. Yo por ejemplo utilizo sqlserver newid() y esto genera un uniqueidentifier