Newsgroup: it.comp.software.database
Titolo: [MySQL] Campi auto_increment e "buchi"

Ho una tabella con un campo "ID" integer auto incrementante come chiave 
primaria. Supponiamo che dopo vari INSERT e DELETE si sia creata una 
situazione del genere:
ID      CAMPO1
--------------
1       ...
2       ...
8       ...
20      ...
Al prossimo inserimento l'ID assumerà naturalmente il valore 21, nonostante ci 
siano molti altri valori disponibili più bassi... Non c'è un modo in MySQL per 
fargli assumere il più piccolo valore disponibile (in questo caso 3) ?
Altrimenti c'è il rischio dopo un po' di tempo che si lavora con la tabella di 
veder crescere a dismisura l'indice, se ci sono molti INSERT e DELETE...
Grazie per i suggerimenti !! :)
-- 
Lorenzo

 veder crescere a dismisura l'indice, se ci sono molti INSERT e DELETE...
il valore di un integer signed va da -
2147483648
 a 
2147483647
.
Per quello unsigned va da 0 a 4294967295.
Ce ne vogliono di inserimenti per esaurirli tutti.

 Ce ne vogliono di inserimenti per esaurirli tutti.
Certo, ovviamente non č un problema cosě immediato. Perň nel mio caso si 
tratta di un'applicazione web di "news", gli articoli sono inseriti dagli 
utenti, che possono anche cancellarli, e comunque hanno una scadenza oltre la 
quale vengono eliminati comunque, insomma, č un db molto "dinamico". Non 
volevo avere questo problema, seppur remoto, e quindi volevo eliminare la 
causa alla radice.
Eliminando l'opzione auto_increment, e quindi fornendo gli id 
dall'applicazione, quale sarebbe una query efficiente per trovare il piů basso 
valore libero ?
Oppure un'altra soluzione che mi era venuta a mente, era quella di trasformare 
la colonna id in char(32), e di creare cosě i valori (lavoro in PHP):
$id=md5(rand());
Qual'č secondo te la soluzione migliore (=veloce), tenendo conto che ci 
saranno molte query del tipo: SELECT * from tabella WHERE id=... ?
La ricerca in campi char č molto piů lenta di quella in campi integer ?
Grazie ancora...:)
-- 
Lorenzo

 Saluti.
Grazie di tutti i chiarimenti !! :)
-- 
Lorenzo

auto_increment... fra 10 anni si vedrà...:)
E poi ti basta fare un po' di pulizia.
Per esempio, supponiamo di avere una tabella PRIMARIA con id auto_inc, e
una tabella SECONDARIA che utilizza quegli id.
Passo 1:
	CREATE TABLE xlate
	{
		old_id	integer not null,
		new_id	integer not null primary key auto_increment
		--	serial	-- Questo per PostgreSQL
	};
Passo 2:
	INSERT INTO xlate SELECT id FROM PRIMARIA;
Passo 3: (a sistema locked)
	Modo A
	SELECT * INTO PRIMARIA_COPY FROM PRIMARIA;
	DROP TABLE PRIMARIA;
	UPDATE PRIMARIA_COPY SET id = new_id FROM xlate
		WHERE id = old_id;
	CREATE TABLE PRIMARIA { ... };
	INSERT INTO PRIMARIA SELECT * FROM PRIMARIA_COPY;
	CREATE [UNIQUE] INDEX ...;
	Modo B
	UPDATE PRIMARIA SET id = new_id FROM xlate
		WHERE id = old_id;
 
Passo 4:
	UPDATE SECONDARIA SET id = new_id FROM xlate
		WHERE id = old_id;
C'e' poi un modo belluino che richiede dei locks piu' brevi:
	max = SELECT MAX(new_id) FROM xlate
		WHERE old_id = new_id;
	CURR = SELECT * FROM xlate WHERE new_id > max;
	WITH CURR DO
		-- Lock primaria
		UPDATE PRIMARIA SET id = CURR.new_id
			WHERE id = CURR.old_id;
		-- release primaria
		-- Lock secondaria
		UPDATE SECONDARIA SET id = CURR.new_id
			WHERE id = CURR.old_id;
		-- release secondaria
		-- UPDATE TERZIARIA ...
		-- 
		END
	END
Dato che new_id e' sempre <= old_id, non c'e' pericolo di collisioni.
Il modo belluino, usato piu' volte in PHP magari solo per dieci rec a
botta, effettua un "coalescing", ovvero sposta tutti i buchini dentro
alla tabella verso il fondo, creando una enorme bolla o bucone. Si ha
riallineamento completo quando il bucone arriva in fondo... e finche'
questo non succede, PRIMARIA continua ad avere un "last_id" enorme.
In effetti, se e' auto_increment, lo avra' SEMPRE. Percio', il metodo
belluino (cosi' come il metodo B) funziona solo se ID e' inserito con
una subselect o in altro modo che lo faccia equivalere sempre a
	MAX(id)+1
Leonardo
-- 
".signature": bad command or file name

 E poi ti basta fare un po' di pulizia.
[CUT]
Molto interessante, ho appena salvato il tuo post per qualsiasi evenienza 
futura. Grazie 1000 !! :)
-- 
Lorenzo

 
Mi associo 
Angelo

 
Saggia idea Lorenzo.
Ciao