solución típica para cualquier base de datos de relación podría ser una tabla como
user_invoice_numbers (user_id int primary key clustered, last_id int)
y un procedimiento almacenado o una consulta SQL como
update user_invoice_numbers set last_id = last_id + 1 where user_id = @user_id
select last_id from user_invoice_numbers where user_id = @user_id
Se trabajará para los usuarios (si cada usuario tiene unos pocos operaciones simultáneas), pero no funcionará para las empresas (por ejemplo, cuando necesite empresas_números_encuesta) porque las transacciones de diferentes usuarios dentro de la misma empresa pueden bloquearse entre sí y habrá un cuello de botella de rendimiento en esta tabla.
El requisito funcional más importante que debe verificar es , ya sea que su sistema tenga huecos en la numeración de facturas o no. Cuando utiliza auto_increment estándar, permite huecos, porque en la mayoría de la base de datos que conozco, cuando retrotrae la transacción, el número incrementado no se revertirá. Teniendo esto en cuenta, puede mejorar el rendimiento utilizando una de las siguientes pautas
1) Excluya el procedimiento que utiliza para obtener nuevos números de las transacciones de larga ejecución. Supongamos que insertar en el procedimiento de factura es una transacción de larga ejecución con lógica de servidor compleja. En este caso, primero adquiere una nueva identificación, y luego, en una transacción separada, inserta una nueva factura. Si la última transacción se revierte, el número automático no disminuirá.Pero user_invoice_numbers no estará bloqueado durante mucho tiempo, por lo que muchos usuarios simultáneos podrían insertar facturas al mismo tiempo
2) No utilice una base de datos transaccional tradicional para almacenar los datos con la última identificación para cada usuario. Cuando necesita mantener una lista simple de claves y valores, existen muchos motores de base de datos pequeños pero rápidos que pueden hacer eso por usted. List of Key/Value databases. Probablemente memcached es el más popular. En el pasado, vi los proyectos donde simples almacenamientos de claves/valores se implementaban usando el Registro de Windows o incluso un sistema de archivos. Había un directorio donde cada nombre de archivo era la clave y dentro de cada archivo estaba la última identificación. Y esta solución aproximada era aún mejor que usar la tabla SQL, ya que los bloqueos se emitían y se liberaban muy rápidamente y no estaban involucrados en el alcance de la transacción.
Bueno, si mi propuesta para la optimización parece ser demasiado complicada para su proyecto, olvídese de esto ahora, hasta que realmente se encuentre con problemas de rendimiento. En la mayoría de los proyectos, el método simple con una tabla adicional funcionará bastante rápido.
No estoy permitiendo editar/borrar facturas, por lo que simplifica un poco todo (sin espacios). Pero no estoy preocupado por el rendimiento ahora. Gracias –
memcached no es un motor de base de datos: http://code.google.com/p/memcached/wiki/FAQ#How_can_I_use_memcached_as_a_database? –
Si utiliza alguna tecnología que pueda generar lagunas (como se desprende de esta respuesta, el autoincremento lo hará), puede reducir la contención al permitir la obtención previa de trozos de la secuencia. En el peor de los casos, pierdes el pedazo sin usar. – djna