mmofacts.com

Immer die niedrigste Nummer suchen.

gepostet vor 18 Jahre, 11 Monate von Klaus
Jeder kennt das auto_increment Problem:
1 Daten
2 Daten
-- gelöscht --
4 Daten
...

beim einfügen eines neuen Datensatzes würde ich diese Lücke gern schließen können. Es muss also die kleinste freie Zahl gesucht werden, damit meine User nicht mit riesigen Zahlen hantieren müssen.
Gibt es da einen schnellen Weg für?


Und noch eine Frage: Wie hieß die PHP-Funktion um mehrere Queries abzuarbeiten? Und ist das schneller als wenn die Queries einzeln hintereinander kommen?
gepostet vor 18 Jahre, 11 Monate von Tweety
Hm, warum verlässt du dich nicht auf die Auto-Increment-Funktion der Datenbank? Das sollte schneller gehen als jedesmal nach einer freien Nummer zu suchen. Und die paar Bits mehr für größere Integerzahlen sollten doch wohl drin sein?
Außerdem kannst du so falsche Verknüpfungen zwischen Tabellen schlechter finden - denn dann können ja neue Datensätze die Nr. der alten haben, und somit könnten Verknüpfungen auf Datensätze zeigen, mit denen sie eigentlich gar nix zu tun haben...
gepostet vor 18 Jahre, 11 Monate von Klaus
das ist nur was für die User. "Fahrzeug Nummer 42" z.B.
Besser als wenn ich die richtige ID 52234 nehme, das kann sich ja niemand merken. :lol:
gepostet vor 18 Jahre, 11 Monate von Tweety
Ach so, eine "richtige" ID hast du zusätzlich? dann hab ich das falsch verstanden.

Du könntest dann die entsprechenden Datensätze mit "SELECT * FROM table WHERE .... ORDER BY sichtbare_ID ASC" ermitteln und dann in einem Durchgang durch die Ergebnisse jeweils gucken, ob der Abstand zwischen zwei Datensätzen größer als 1 ist, also z. B.
if($zeile["sichtbare_ID"]-$vorigezeile["sichtbare_ID"]>1) {

$gefundene_luecken_ID = $vorigezeile["sichtbare_ID"] + 1;
}

Sobald du so eine Lücken-ID findest, kannst du abbrechen und die gefundene ID weiterverwenden. Ist jetzt spontan das, was mir dazu einfiele. Kann sein, dass es auch optimaler geht...

Aber wie gesagt - du solltest dann drauf achten, dass nirgends anders Daten rumschwirren, die irgendwann evtl. auf einen Datensatz gezeigt haben, der gelöscht und durch einen anderen ersetzt wurde - solche Fehler lassen sich dann meist nur schwer wiederfinden... ich sprech aus Erfahrung *g*
gepostet vor 18 Jahre, 11 Monate von Krisch
Man könnte es auch direkt in MySQL machen, aber da bei Inserts keine Joins erlaubt sind bringt das nur einen sehr kleinen Vorteil.
So ungefähr:
Select * From fahrzeuge As f1
Left Join fahrzeuge As f2 ON f1.id + 1 = f2.id
Where f2.id Is Not Null;
gepostet vor 18 Jahre, 11 Monate von Kampfhoernchen
Naja, das ganze halt als Subquery (wenn MySQL5 zur Verfügung steht)
gepostet vor 18 Jahre, 11 Monate von KoMtuR
wenn mysql 5 verfügbar ist dann lieber per stored procedure:

(dies ist der code, wenn man mit der konsolenanwendung arbeitet)
 

delimiter //
create function `datenbank`.`getFirst` () returns int
begin
declare zaehler int;
declare currentid int;
declare done int default 0;
declare cur CURSOR FOR SELECT id FROM `tabelle` ORDER BY `id` ASC;
declare CONTINUE HANDLER FOR SQLSTATE '02000' set done = 1;
set zaehler = 1;

open cur;

while NOT done do
fetch cur into currentid;
if(not done) then
if(currentid
zaehler) then
return zaehler;
end if;
set zaehler = zaehler + 1;
end if;
end while;
return zaehler;
end //
delimiter ;


Dann geht die Einfügeoperation so:

Insert into tabelle (`id`,....) VALUES (tabelle.getFirst(), ....);


Viel spass dabei.

PS.: Ich weiß nicht, inwieweit dies langsam ist. Also einfach mal ausprobieren. Geht sicherlich noch einfacher

Edit: Ah mom es gibt ne leichtere Variante, indem man Cursor verwendet. Der Code kommt dann gleich

Edit2: Dies sollte nun vielleicht etwas schneller gehen
gepostet vor 18 Jahre, 11 Monate von Klaus
Vielen Dank für die verschiedenen Lösungen.

Meine andere Frage steht noch:


Und noch eine Frage: Wie hieß die PHP-Funktion um mehrere Queries abzuarbeiten? Und ist das schneller als wenn die Queries einzeln hintereinander kommen?
gepostet vor 18 Jahre, 11 Monate von KoMtuR
Die Funktion heißt multi_query und kommt aus der Bibliothek mysqli. Ich hatte mal so ein paar Tests gemacht und da war ein multiquery um einiges schneller. Für insert/update-Operationen nimmste aber die prepared Statements von mysqli, weil diese bei großen Daten

a) den Datenaustausch zwischen Server und php-Skript verkleinern

b) dadurch Mysql-Injections verhindert werden

Auf diese Diskussion antworten