MySQL niedrigste "freie" ID

d-braun

Erfahrenes Mitglied
Hi,

folgende Problemstellung:

Ich hab eine Lagerverwaltungssoftware welche Daten in einer MySQL-Tabelle einträgt.
Wie kann ich des realisieren dass die niedrigste "freie" ID benutzt wird und nicht die nächst höhere?

Beispiel:
ID Beschreibung
1 Artikel1
2 Artikel2
3 Artikel3

Wenn ich nun "Artikel2" mit der ID "2" lösche und danach einen neuen Artikel hinzufüge bekommt dieser die ID "4".
Wie kann ich nach der nächsten "freien" ID suchen damit neue Einträge nicht fortlaufend eingetragen werden sondern der Bestand quasi "aufgefüllt" wird?

Das einzige was mir gerade einfällt ist folgendes:
MaxID ermitteln, ID für ID (also 1 bis MaxID) durchgehen und prüfen ob diese ID existeirt, wenn die ID nicht existiert Artikel mit dieser ID anlegen, falls ID existiert weitersuchen.

Das ganze würde aber bei einer Menge im 5-stelligen Bereich ein relativ großes Rechenaufkommen haben was ich mir eigentlich nicht leisten kann da die Software auf uralten Systemen in Afrika laufen muss.

Hat jemand ne andere Lösung?

MFG
d-braun
 
Hi,

also ich hab hier mal nen Ansatz allerdings funktioniert das nicht.
PHP:
                if(!mysql_query($query))
                {
                  $foundid = "1";
                  $setid = $count;
                }
Das geht scheinbar nicht.
Aber wieso? Gibts da nicht noch ne elegantere Lösung?

Hier der komplette Code:
PHP:
            $getmaxid = mysql_query("SELECT MAX(id) as maxid FROM glaeser");
            $maxid = mysql_fetch_row($getmaxid);
            $maxid = $maxid[0];

            $count = 1;
            $foundid = 0;
            while(($count <= $maxid))
            {
              if ($foundid == "0")
              {
                $query = "SELECT id FROM glaeser WHERE `id` = $count";
                if(!mysql_query($query))
                {
                  $foundid = "1";
                  $setid = $count;
                }
              }
              $count++;
            }

            if ($foundid == "0")
            {
              $getmaxid = mysql_query("SELECT MAX(id) as maxid FROM glaeser");
              $maxid = mysql_fetch_row($getmaxid);
              $maxid = $maxid[0];
              $setid = $maxid + 1;
            }
 
Ich würde folgendermassen vorgehen:

1. mittels "SELECT id FROM glaeser ORDER BY id" alle id's in ein Array abspeichern.
2. mittels Schleifenindex auf das Array zugreifen und pruefen, ob der Schleifenindex( Achtung, ev. +1) mit der id aus dem Array uebereinstimmt. Falls nicht, hast du eine Luecke gefunden und kannst die schleife abbrechen.

Sorry, kann leider kein PHP, daher weiss ich nicht, ob PHP einen Abbruch der Schleife erlaubt.
 
Hallo,

auch wenn ich den Sinn dahinter nicht ganz verstehe… folgende Abfrage sollte dir die kleinste, noch nicht belegte ID zurückgeben:
Code:
SELECT t1.id + 1
FROM tabelle t1
LEFT JOIN tabelle t2 ON (t2.id = t1.id + 1)
WHERE t2.id IS NULL
ORDER BY t1.id ASC
LIMIT 1
Allerdings sollte man hierbei natürlich aufpassen, dass keine Race Condition entsteht.

Grüße,
Matthias
 
Hallo,

bezüglich der Ermittlung wurden hier ja schon einige Vorschläge gemacht, den einen oder andern würde ich auch unterschreiben :)
Allerdings halte ich die Strategie eine bereits vergebene ID nach Löschen des Datensatzes erneut zu vergeben für fragwürdig. Das komplette ERD entzieht sich meiner Kenntnis, aber was ist mit FK´s? Ja, ich weis, dass Records nur dann gelöscht werden können, wenn sie nicht mehr referenziert sind, aber oft findet sich in einer DB ein FK als (sinnvolle) redundante Information, die keiner Referenz unterliegt. Das könnte Probs mit sich bringen, indem durch die Wiederverwendung falsche Daten angezeigt würden. Im Falle der Nichtwiederverwendung (was ein Wort...) hast Du ne leere Ergebnismenge, die man sicherlich schneller findet als falsche Daten...

Gruß

M.
 
Ich hab das ganze jetzt wiefolgt gelöst:
PHP:
            $getmaxid = mysql_query("SELECT MAX(id) as maxid FROM glaeser");
            $maxid = mysql_fetch_row($getmaxid);
            $maxid = $maxid[0];

            $count = 1;
            $foundid = 0;
            while(($count <= $maxid))
            {
              if ($foundid == "0")
              {
                if ( mysql_num_rows( mysql_query( "SELECT id FROM glaeser WHERE id='$count'" ) ) == 0 )
                {
                  $foundid = "1";
		  $setid = $count;
                }
              }
              $count++;
            }

            if ($foundid == "0")
            {
              $getmaxid = mysql_query("SELECT MAX(id) as maxid FROM glaeser");
              $maxid = mysql_fetch_row($getmaxid);
              $maxid = $maxid[0];
              $setid = $maxid + 1;
            }

Geht sicherlich noch eleganter etc. aber für meine Zwecke sollte das ausreichen.
 

Neue Beiträge

Zurück