2009-07-09 7 views
9

¿Cómo generan las personas números enteros autoincrementados para un usuario en particular en una aplicación típica de saas?Generación de números secuenciales en la aplicación de saas multiusuario

Por ejemplo, los números de factura de todas las facturas para un usuario particular deben autoincrementarse y comenzar desde 1. El campo id. De raíles no se puede usar en este caso, ya que se comparte entre todos los usuarios.

Por fuera de mi cabeza, podría contar todas las facturas que tiene un usuario, y luego agregar 1, pero ¿alguien sabe de alguna solución mejor?

Respuesta

4

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.

+0

No estoy permitiendo editar/borrar facturas, por lo que simplifica un poco todo (sin espacios). Pero no estoy preocupado por el rendimiento ahora. Gracias –

+0

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? –

+0

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

0

No estoy seguro si esta es la mejor solución, pero podría almacenar la última ID de factura en el Usuario y luego usarla para determinar la siguiente ID al crear una nueva Factura para ese Usuario. Pero esta solución simple puede tener problemas de integridad, tendrá que tener cuidado.

+0

¿Tiene un ID de factura atributo pertenece realmente en un objeto de usuario? ¡Es una solución pragmática, pero no una para los puristas! –

+0

Si existe un requisito de que los números de factura sean secuenciales para cada usuario, entonces "latestInvoiceNumberForThisUser" parece estar estrechamente asociado con el usuario. – djna

+0

Sí, bien argumentado. –

2

Puede introducir otra tabla asociada a su tabla de "usuarios" que rastrea el número de factura más reciente para un usuario. Sin embargo, la lectura de este valor dará lugar a una consulta en la base de datos, por lo que es mejor que obtenga un recuento de las facturas del usuario y agregue una, como sugirió. De cualquier forma, es un golpe de base de datos.

2

Si los números de factura son independientes para cada usuario/cliente, entonces parece que tener el campo "lastInvoice" en algún almacén persistente (por ejemplo, registro de base de datos) asociado con el usuario es bastante inevitable. Sin embargo, esto podría llevar a cierta disputa por el "último" número.

¿Realmente importa si enviamos las facturas de usuario 1, 2, 3 y 5, y nunca les enviamos la factura 4? Si puede relajar el requisito un poco.

Si el requisito es en realidad "cada número de factura debe ser único", entonces podemos ver todos los trucos normales de generación de identificaciones, y estos pueden ser bastante eficientes.

Asegurar que los números sean secuenciales se agrega a la complejidad, ¿se agrega al beneficio comercial?

+0

sí, porque es una aplicación de contabilidad, los números deben ser números enteros de incremento automático. Por lo tanto, debe ser bastante sólido también. –

0

¿Realmente desea generar los ID de factura en un formato incremental? ¿Esto no abriría agujeros de seguridad (donde, si un usuario puede adivinar la generación del número de factura, puede cambiarlo en la solicitud y puede conducir a la divulgación de información). Idealmente, generaría los números al azar (y mantendría un registro de los números usados). Esto también evita colisiones (Las posibilidades de colisión se reducen a medida que los números se asignan aleatoriamente en un rango).

+1

En algunos países, sus números aleatorios no son legales. Debe ser secuenciales para la inspección del gobierno. – Juanin

Cuestiones relacionadas