Durchlaufende, eindeutige ID



  • Ich brauche in einer Tabelle in jedem Datensatz eine ID, die von 1 an durchläuft und zwar automatisch. Wenn ein Datensatz aus der Mitte gelöscht wird, sollen die darunter aufrücken, so dass quasi keine Lücken entstehen.
    Wie lässt sich so etwas realisieren?



  • Ich emfpehle dringenst ein bißchen Literatur zum Thema Datenbankdesign!

    Grüße,

    Joe_M.



  • Das geht nicht. Es gibt zwar autoinc. Typen aber diese verwendet man normalerweise für den Primärschlüssel.
    Da ist aber nicht mit aufrücken der nachvollgenden.

    Ich gebe dir mal eine Hack aber sowas macht man nicht:
    Du löscht den Datensatz anhand der ID. Dann machst du ein
    UPDATE auf die ID und setzt alle ID - 1 die großer sind als die gelöschte.

    DELETE FROM XY where id = 5;
    UPDATE XY SET id = id -1 WHERE id > 5



  • Nun da Unix-Tom die Katze schon aus dem Sack gelassen hat... 😉

    Zum einen bezweifle ich, dass das mit AutoInc-Feldern funktioniert (habe ich aber nicht getestet), zum anderen fehlt der Hinweis darauf, dass natürlich auch in allen abhängigen Tabellen, in denen diese ID verwendet wird, diese ebenfalls geändert werden muss. Das ist auch der Grund, warum man so etwas nicht macht. Ein kleiner Denkfehler, oder ein einziges fehlgeschlagenes Update und schon ist die DB unbrauchbar, da die Daten inkonsistent sind.
    Selbst wenn es keine abhängigen Tabellen gibt, ist diese Vorgehehesweise denkbar ungünstig, wenn mehrere Anwender auf die Tabelle zugreifen. Was passiert, wenn Du in gerade die IDs änderst, und jemand einen neuen Datensatz einfügt? Oder ebenfalls einen Datensatz löscht? Oder einfach nur einen geänderten Datensatz speichert, der auf seinem Client noch die ID 8 hat, aber durch Deine Routine nun die ID 7 hat. Der falsche Datensatz wird aktualisiert. Das kann auch passieren, wenn nur ein User auf die DB zugreift, aber mehrere Select-Ergebnisse verwendet.
    Mach Dir doch lieber ein zusätzliches Feld, in dem Du die laufende Nummer speicherst. Das kann zwar auch schief gehen, aber es beeinträchtigt nicht die Funktionalität der Datenbank. Wenn Du einfach nur ein fortlaufende Nummerierung haben willst, gibt es vielleicht bei Deinen Zugriffskomponenten eine Möglichkeit 'berechnete Felder' zu verwenden, oder die RowNumber, sofern die Datenbank das unterstüzt.

    Gerade als Anfänger macht man bei dem Design von Datenbanken schnell einen 'dummen' Fehler, die sich an irgendeinem Punkt fürchterlich rächen kann und das gesamte Konzept über den Haufen werfen kann... Also nochmal die Empfehlung Dir entsprechende Literatur zu Gemüte zu führen.



  • Vor allem wofür brauchst du die durchgehende Nummer? Wenn du eh alle Datensätze
    ausliest, kannst du sie auch im Client ergänzen. Und ansonsten halt eine eigene
    Spalte. Aber erzähl doch mal, was du überhaupt machen willst. Vielleicht gibt es
    ja doch einen ganz anderen, einfacheren Ansatz...



  • @Joe_M.

    Bei MySQL funktioniert das.
    Wenn einer alles ID`s updatet und ein andere will auslesen dann ist das kein Problem weil MySQL die Tabelle bei jedem INSERT/UPDATE/REPLACE sperrt.

    Man macht es aber trotzdem nicht.



  • @Unix-Tom: ja, das wird wohl jedes DBMS so machen (sollte zumindest 😉 )
    Aber dennoch reicht schon eine ReadDirty Query eines zweiten Users, der die Daten vor dem Löschen abgefragt hat und schon werden dessan Aktionen auf die alte ID angewendet... (sofern ID der Primary Key ist)

    Auf jeden FAll ist (meiner Meinung nach) das Risiko, das etwas schief geht, sehr hoch. Und insbesondere bei Datenbanken versuche ich die 'Restrisiken' zu minimieren.

    Allerdings fällt mir gerade auf, dass er nirgendwo geschrieben hat, dass es der Primary Key ist... Nun es wurden genügend Denkanstöße gegeben - ich hoffe er macht was draus.

    Grüße Joe_M.



  • ok,ok sinn der Sache wäre eigentlich nur geziehlt Datensätze auszulesen! Also 23 bis 33 oder 5 bis 8 odernur 15. Geht das irgendwie?



  • Jein. Du kannst deine Datensätze auslesen wie du sie brauchst.
    Nach bestimmten kriterien.

    z.B. Where ID > 3 AND ID < 7. (Geht auch etwas anders)
    Damit bekommst du alle Datensätze zwischen 4 und 6.

    Wisst du Resultsets limitieren dann bei MySQL mit LIMIT 3, 5

    Erste Zahl ist bei welchem Datensatz im Resultset begonnen wird und die 2te wieviele Datensätze im Resultset sein sollen.
    Dis gillt aber nur für MySQL und ist IMHO eine Spracherweiterung.


Anmelden zum Antworten