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.
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 –
memcached non è un motore di database: http://code.google.com/p/memcached/wiki/FAQ#How_can_I_use_memcached_as_a_database? –
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