2009-07-09 13 views
9

In che modo le persone generano numeri interi autoincrementali per un particolare utente in una tipica applicazione saas?Generazione di numeri sequenziali in un'applicazione saas multiutente

Ad esempio, i numeri di fattura per tutte le fatture per un particolare utente devono essere auto_incrementing e iniziare da 1. Il campo ID rotaie non può essere utilizzato in questo caso, poiché è condiviso tra tutti gli utenti.

In cima alla mia testa, potevo contare tutte le fatture ricevute da un utente, quindi aggiungere 1, ma qualcuno sa di una soluzione migliore?

risposta

4

soluzione tipica per qualsiasi database relazione potrebbe essere una tabella come

user_invoice_numbers (user_id int primary key clustered, last_id int) 

e una stored procedure o una query SQL come

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 

Essa opererà per gli utenti (se ogni utente ha pochi simultaneamente eseguendo transazioni) ma non funzionerà per le aziende (ad esempio quando hai bisogno di companies_invoice_numbers) perché le transazioni da diversi utenti all'interno della stessa azienda potrebbero bloccarsi a vicenda e ci sarà un collo di bottiglia nelle prestazioni in questa tabella.

Il requisito funzionale più importante da verificare è se al sistema è consentito avere lacune nella numerazione della fattura o non. Quando si utilizza auto_increment standard, si consente di lasciare spazi vuoti, poiché nella maggior parte dei database che conosco, quando si esegue il rollback della transazione, il numero incrementato non verrà ripristinato. Tenendo presente ciò, è possibile migliorare le prestazioni utilizzando una delle seguenti linee guida

1) Escludere la procedura che si utilizza per ottenere nuovi numeri dalle transazioni a esecuzione prolungata. Supponiamo che l'inserimento nella fattura sia una transazione di lunga durata con logica lato server complessa. In questo caso, si acquisisce innanzitutto un nuovo ID e quindi, in una transazione separata, inserire una nuova fattura. Se l'ultima transazione verrà ripristinata, il numero automatico non diminuirà.Ma user_invoice_numbers non sarà bloccato per molto tempo, quindi molti utenti simultanei potrebbero inserire fatture allo stesso tempo

2) Non utilizzare un database transazionale tradizionale per memorizzare i dati con l'ultimo ID per ciascun utente. Quando è necessario mantenere un semplice elenco di chiavi e valori ci sono molti piccoli ma veloci motori di database che possono farlo funzionare per voi. List of Key/Value databases. Probabilmente memcached è il più popolare. In passato, ho visto i progetti in cui semplici archivi di chiavi/valori sono stati implementati utilizzando il registro di Windows o persino un file system. C'era una directory in cui ogni nome di file era la chiave e all'interno di ogni file c'era l'ultimo id. E questa soluzione approssimativa era ancora migliore dell'utilizzo della tabella SQL, perché i blocchi venivano emessi e rilasciati molto rapidamente e non erano coinvolti nell'ambito della transazione.

Bene, se la mia proposta per l'ottimizzazione sembra essere eccessivamente complicata per il progetto, dimenticatene ora, finché non incontrerete effettivamente problemi di prestazioni. Nella maggior parte dei progetti, il metodo semplice con una tabella aggiuntiva funzionerà abbastanza velocemente.

+0

Non autorizzo la modifica/eliminazione delle fatture, in modo da semplificare un po 'tutto (senza interruzioni). Ma non sono preoccupato per le prestazioni ora. Grazie –

+0

memcached non è un motore di database: http://code.google.com/p/memcached/wiki/FAQ#How_can_I_use_memcached_as_a_database? –

+0

Se si utilizza una tecnologia che potrebbe causare spazi vuoti (come risulterà da questa risposta automatica), è possibile ridurre la contesa consentendo il pre-acquisizione di blocchi dalla sequenza. Nel peggiore dei casi si perde il pezzo inutilizzato. – djna

0

Non sicuro se questa è la soluzione migliore, ma è possibile memorizzare l'ultimo ID fattura sull'Utente e quindi utilizzarlo per determinare l'ID successivo quando si crea una nuova Fattura per quell'Utente. Ma questa semplice soluzione potrebbe avere problemi di integrità, sarà necessario fare attenzione.

+0

Esiste un ID fattura attributo in realtà appartengono a un oggetto d'uso? È una soluzione pragmatica ma non per i puristi! –

+0

Se è necessario che i numeri di fattura siano sequenziali per ciascun utente, "latestInvoiceNumberForThisUser" sembra essere strettamente associato all'utente. – djna

+0

Sì, ben argomentato. –

2

È possibile introdurre un'altra tabella associata alla tabella "utenti" che tiene traccia del numero di fattura più recente per un utente. Tuttavia, la lettura di questo valore comporterà una query del database, quindi potresti anche ottenere un conteggio delle fatture dell'utente e aggiungerne uno, come suggerito. Ad ogni modo, è un successo di database.

2

Se i numeri di fattura sono indipendenti per ciascun utente/cliente, sembra che il campo "lastInvoice" in alcuni archivi persistenti (ad esempio il record DB) associato all'utente sia piuttosto inevitabile. Tuttavia questo potrebbe portare ad alcune contese per il "più recente" numero.

È davvero importante se inviamo fatture utente 1, 2, 3 e 5 e non le inviamo mai la fattura 4? Se riesci a rilassare un po 'il requisito.

Se il requisito è in realtà "ogni numero di fattura deve essere univoco", possiamo osservare tutti i normali trucchi generati dall'ID e questi possono essere abbastanza efficienti.

Accertarsi che i numeri siano sequenziali si aggiunga alla complessità, si aggiunge ai vantaggi aziendali?

+0

sì, perché è un'applicazione di contabilità, i numeri devono essere numeri interi autoincrementanti. Quindi, deve essere abbastanza solido. –

0

Vuoi davvero generare gli ID fattura in un formato incrementale? Ciò non aprirebbe lacune di sicurezza (dove, se un utente può indovinare la generazione del numero di fattura, può cambiarlo nella richiesta e può portare alla divulgazione di informazioni). Preferirei generare i numeri in modo casuale (e tenere traccia dei numeri usati). Questo previene anche le collisioni (le probabilità di collisione sono ridotte in quanto i numeri sono assegnati casualmente su un intervallo).

+1

In alcuni paesi i numeri casuali non legali. Deve essere sequenziale per l'ispezione del Gov. – Juanin

Problemi correlati