![]() |
El mejor método para generar IDs en tablas de movimiento
Saludos amigos,
En un entorno multiusuario, garantizar que las IDs (PKs) son únicas es parte fundamental de cualquier sistema bien estructurado. Actualmente, por ejemplo yo hago lo siguiente:
Función:
Consulta q_CalcIDNewPago:
sin embargo, no estoy seguro que sea la mejor forma de hacerlo. Cualquier aporte será bienvenido. Atte, Américo |
Estas duplicando, de forma mas ineficiente*, lo que hace una bd. Usa:
Lo que es dificil es garantizar que sea perfectamente incremental sin 'huecos' pero eso es otro asunto. * p.d: Y adicionalmente este codigo trae un bug incorporado! |
Campo autonumerico
Creo que la mejor forma de generar un id es con campo autonumerico o autoincrementable. Ahí simplemente el motor de bd genera el siguiente número sin necesidad de averiguar cual es el mayor número de un campo de tabla.
|
Cita:
|
En firebird existen los generadores.
Los generadores siempre devuelven números diferentes (garantizado por la base de datos). Los generadores siempre se incrementan, a pesar de que la transacción falle (Rollback). Yo suelo dejar que la base de datos lo genere y me lo devuelva. Con esta sentencia y el generador en el trigger:
Cuando por alguna razón no puedo utilizarlo de esta manera, pido un número al generador y luego lo utilizo en el insert
|
En tu caso, básicamente haces un SELECT MAX(ID).
Si justo al mismo tiempo dos usuarios piden el MAX(ID) les devolverá el mismo número. Luego al hacer el INSERT el primero logrará hacerlo y el segundo dará error porque estará insertando un duplicado. Particularmente esta forma de obtener un ID es muy ineficiente en Firebird. A pesar de tener índices por ese campo. Tiene que ver con la multi versión de registros. En otros motores no sabría decirte. |
Otro bug: Insertas 10 registros, el id va en 10. Ahora:
Borras el ultimo Borras todos Borras el primero etc. Un id debe ser global(en su contexto), único y *no repetible* |
Cita:
Como siempre muchas gracias a todos. Atte, Americo Torres |
Negarse a usar lo que el motor te da 'gratis' raramente tiene sentido. No solo es esfuerzo innecesario, es como introduces errores inesperados y limitas al motor a la hora de hacer optimizaciones.
P.D: Yo trabajo en parte construyendo un motor de base de datos desde cero(https://spacetimedb.com) y te puedo asegurar que cada componente se hace con mas detalle de lo que te puedes imaginar. Ahora estoy solamente generando el diseño básico de la autenticación y llevo 3 semanas, como 10 borradores y todo porque en un motor de base de datos hay que tener en cuenta un montón de casos extremos. Usar el soporte de autonumericos del motor es lo que se debe de hacer a menos que tengas una buena razón, que SOLAMENTE puede ser: * Necesitas un id universal, así que usas una UUID * Necesitas evitar `saltos` para el caso de facturas, que entonces es complicado de hacer correcto, porque no solo debes hacer la lógica correctamente sino que debes coordinar a todas tus app que usen un modo transaccional mas estricto `SERIALIZABLE` y eso que no estoy seguro como seria en sql server * Tienes una llave natural |
Saludos
Preguntándole a ChatGPT, me dió la siguiente funcion, la cual ya implementé:
Resultado: ![]() Funcion:
Quedo atento a sus comentarios. Atte |
Super interesante en los proyectos en que andas amigo.
Quisiera tener tu level. Saludos Cita:
|
La franja horaria es GMT +2. Ahora son las 18:08:23. |
Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi