|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Member
Iscritto dal: Nov 2005
Città: Torino
Messaggi: 289
|
[SQL] riordinare id
Col passare del tempo i valori degli id hanno raggiunto quote elevate (da 10000 in poi, mentre i record sono poco più di un centinaio).
E' possibile far sì che ad un successivo inserimento l'id assuma il valore più basso disponibile?
__________________
Toshiba Satellite A100-926: Intel Core 2 Duo T7200, 2 GB ram ddr2, ATI MOBILITY RADEON X1600 512 MB Hypermemory (256 MB+256 MB) |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Certo, e' possibile.
Ma se poi con l'introduzione di 10000 nuovi record dovessi raggiungere di nuovo uno dei 100 ID che ora e' presente (e suppongo anche poi), cosa vorresti che capitasse?
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
|
|
|
|
|
#3 | |
|
Member
Iscritto dal: Nov 2005
Città: Torino
Messaggi: 289
|
Quote:
In pratica ho bisogno che la prossima riga che inserisco avrà id=1, quando poi troverà un id che è già occupato (presupponiamo id=90) dovrà saltarlo (e quindi assumere id=91 se è libero).
__________________
Toshiba Satellite A100-926: Intel Core 2 Duo T7200, 2 GB ram ddr2, ATI MOBILITY RADEON X1600 512 MB Hypermemory (256 MB+256 MB) |
|
|
|
|
|
|
#4 | |
|
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Quote:
La cosa che vorresti fare non si puo' fare automaticamente. Dovresti costruire una funzione apposita. Ma il supportare un database di tale funzione non e' banale. Occorre affrontare problemi di concorrenza e di lock, che sono gia' risolti dalle identity di SqlServer e Access, dalle Sequence di Oracle, e in generale da tutti i contatori presenti nei database piu' diffusi. Ergo, ti consiglio di tenere gli ID alti, che tanto il database non soffre.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
|
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: May 2005
Città: Napoli - Fuorigrotta
Messaggi: 471
|
Per curiosità, che tipo di db usi? Potresti risolvere con una semplice stored procedure.
__________________
Acquisti sul mercatino: grabrihc, LucaXbox360, Yarsha,micanto1,American horizo,Fnac,schumyFast,STECCO,Ezechiele25,17 Vendite sul mercatino: musodatopo,alexbands,mspr,anto.wajo |
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Ciao, Quale algoritmo proporresti nella stored procedure?
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. Ultima modifica di gugoXX : 27-02-2008 alle 09:25. |
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: May 2005
Città: Napoli - Fuorigrotta
Messaggi: 471
|
Dipende, se sai che questo problema non si presenterà più, potresti scrivere una query ad hoc, metti il caso l'id iniziale che hai adesso è 10000, potresti fare una cosa del genere nella procedura "genera_id":
SELECT max(id)+1 INTO massimovalore FROM tabella WHERE id<10000 In questo modo ottieni il massimo valore al di sotto dei 10000: se massimovalore vale 10000 allora il massimovalore deve diventare SELECT max(id)+1 INTO massimovalore FROM tabella Se il tuo engine DB supporta le query multiple (eseguite in modalità atomica) potresti fare una cosa del tipo INSERT INTO tabella(id,altricampi) VALUES ((SELECT genera_id),'altri campi') Quindi il tuo problema e' scrivere la procedura. Altra situazione invece si presenta se gli ID vanno e vengono: quì la cosa si fà più complicata. Il mio suggerimento è di crearti una tabella "ID_CANCELLATI" ed ogni volta che cancelli un record dal DB inserisci l'ID relativo in questa tabella; poi quando devi creare un nuovo record puoi prima andare a vedere se la tabella ID_CANCELLATI è vuota; in qual caso prenderesti il valore max(id) altrimenti il primo valore da ID_CANCELLATI.
__________________
Acquisti sul mercatino: grabrihc, LucaXbox360, Yarsha,micanto1,American horizo,Fnac,schumyFast,STECCO,Ezechiele25,17 Vendite sul mercatino: musodatopo,alexbands,mspr,anto.wajo |
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Non mi sembra che le soluzioni siano resistenti al multiprocesso.
Mi spiego, cosa succede se 2 processi aprono contemporaneamente una transazione e cercano di inserire entrambi un record in quella tabella, e poi chiudono (commit) la transazione?
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: May 2005
Città: Napoli - Fuorigrotta
Messaggi: 471
|
Dipende dall'engine DB, come ho già detto.
Ad esempio, in PostgreSQL le query singole rispettano le proprietà acide delle transazioni: quindi se una query chiama una stored procedure che a sua volta ne chiama altre 100 il tutto sarà eseguito come una transazione. In pratica, è come se facesse "BEGIN TRANSACTION; QUERY; COMMIT WORK;". Quindi, se all'interno della query chiami una SP (come "SELECT genera_id") allora quella query sarà eseguita come transazione.
__________________
Acquisti sul mercatino: grabrihc, LucaXbox360, Yarsha,micanto1,American horizo,Fnac,schumyFast,STECCO,Ezechiele25,17 Vendite sul mercatino: musodatopo,alexbands,mspr,anto.wajo |
|
|
|
|
|
#10 | |
|
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Quote:
Ma quello che proponevo di testare e': - Ho due processi, ciascuno dei quali apre esplicitamente una transazione - Entrambi giungono contemporaneamente ( prima che l'altro abbia effettuato il commit) al punto di dover inserire un record nella tabella - Il secondo dei due processi non puo' vedere che l'altro ha gia' inserito un record, e che quindi il proprio MAX dovrebbe essere diverso da quanto calcolato. - Cosa succede? In SQL Server ed in Oracle se si usa tale metodo viene generato un LOCK di tutta la tabella. (Cosa che con le identity e le sequence invece non succede) Quando si generano LOCK su tutta la tabella e' molto facile degenerare in DEADLOCK senza neppure che ce ne si accorga. Gestire in modo robusto questi casi non e' cosi' semplice.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. Ultima modifica di gugoXX : 27-02-2008 alle 11:39. |
|
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: May 2005
Città: Napoli - Fuorigrotta
Messaggi: 471
|
Beh si. Ti dirò che non ricordo esattamente come funziona il metodo con il quale vengono gestite le transazioni, mi ricordo di averlo studiato nell'esame di sistemi informativi, ma se non erro ogni volta che una query scrive su un record o lo elimina, siccome il sistema è in grado di riportare indietro lo stato di altre transazioni, dovrebbe annullare quelle che hanno letto lo stesso valore ma che non sono ancora terminate.
Detto ciò poi dipende dal problema che stiamo risolvendo: non sappiamo se l'applicazione è multiutente o meno! L'utente che ha aperto il thread non mi sembra l'abbia scritto...
__________________
Acquisti sul mercatino: grabrihc, LucaXbox360, Yarsha,micanto1,American horizo,Fnac,schumyFast,STECCO,Ezechiele25,17 Vendite sul mercatino: musodatopo,alexbands,mspr,anto.wajo |
|
|
|
|
|
#12 |
|
Member
Iscritto dal: Nov 2005
Città: Torino
Messaggi: 289
|
Oggi ero alle prese con altri problemi e non ho potuto provare le vostre soluzioni.
Appena potrò farò le dovute considerazioni. Grazie per l'aiuto
__________________
Toshiba Satellite A100-926: Intel Core 2 Duo T7200, 2 GB ram ddr2, ATI MOBILITY RADEON X1600 512 MB Hypermemory (256 MB+256 MB) |
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Sull'argomento transazioni et similia vi consiglio di leggere questo http://www.firebirdsql.org/doc/white..._vs_oracle.pdf documento, che è MOLTO interessante ed esaustivo.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 02:42.




















