Aufüllen eines Indexes nach Delete



  • Hallo!

    Ich habe eine Tabelle aus der ich einen Eintrag rauslösche. Danach möchte ich die Lücke aufüllen, also die Indices (Unique) nach dem rausgelöschtem Eintrag um eins verringern

    Beispiel:

    Anfang: 1, 2, 3, 4, 5, 6
    Rauslöschen von Eintrag 3: 1, 2, 4, 5, 6
    Neue Indices : 1, 2, 3, 4, 5

    Muss ich das mit n-UPDATES machen? (In meinem Fall wären es bis zu 100 pro gelöschtem Eintrag)

    UPDATE Tabelle SET Index = 3 WHERE Index = 4
    UPDATE Tabelle SET Index = 4 WHERE Index = 5
    UPDATE Tabelle SET Index = 5 WHERE Index = 6
    usw...



  • Ich nehme an die Reihenfolge soll erhalten bleiben? Falls nicht, dann sagen, dann gibt's ne noch viel einfachere (und vor allem performantere) Möglichkeit.

    Falls ja... das müsste meiner Meinung nach funktionieren:

    UPDATE blub SET id = id - 1 WHERE id > {ID des Loches}
    

    Alternativ kannst du den gesamten Index neu aufbauen. Verschiedene Möglichkeiten wie man das machen kann kannst du z.B. hier finden: http://stackoverflow.com/questions/13648898/sql-update-with-row-number



  • Hi! Dein Vorschlag funktioniert soweit und das werde ich wohl auch verwenden. Aus neugier: Wenn die Reihenfolge nicht erhalten bleiben muss, wie hättest du es dann gelöst?
    Ich hätte dann sowas wie

    UPDATE Tabelle SET id = loch_id WHERE id = letzte_id
    

    gemacht. Wobei dann noch die Frage bleibt wie man schnell an letzte_id rankommt.



  • Hallo nochmal!

    Hatte gedacht, dass

    UPDATE blub SET id = id - 1 WHERE id > {ID des Loches}
    

    funktioniert (hat es am Anfang auch). Aber es klappt nur, wenn die Reihenfolge in der die Einträge gefunden werden richtig ist. D.h. wenn ich 3 lösche und dann beim UPDATE 5 finde bevor ich 4 auf 3 geändert habe, dann funktioniert das ganze nicht mehr, weil MySQL dann versucht 5 auf 4 zu ändern 4 aber unique ist und noch nicht auf 3 geändert wurde. Das ganze endet dann mit Execute failed: (1062) Duplicate entry '4' for key 'ID'.

    Hilfe...



  • Oh, doof.
    Du kannst es aber natürlich in zwei Schritten machen:

    UPDATE blub SET id = id + 10000     WHERE id >  {ID des Loches};
    UPDATE blub SET id = id - 10000 - 1 WHERE id >= 10000;
    


  • Hab es jetzt so implementiert, Danke!

    Anmerkungen dazu:
    1. Das ">=" im zweiten update ist ein ">", da die zu aktualisierende ids immer > 0 sind.
    2. Die maximale Anzahl der verwendbaren ids wird halbiert (but who cares anyway).



  • hustbaer schrieb:

    Oh, doof.
    Du kannst es aber natürlich in zwei Schritten machen:

    UPDATE blub SET id = id + 10000     WHERE id >  {ID des Loches};
    UPDATE blub SET id = id - 10000 - 1 WHERE id >= 10000;
    

    Das funktioniert wahrscheinlich, aber ist nicht so leserlich und ich finde es unelegant.

    Wie wäre es damit? http://www.xaprb.com/blog/2006/06/16/how-to-avoid-unique-index-violations-on-updates-in-mysql/

    Zitat:

    http://www.xaprb.com/blog/2006/06/16/how-to-avoid-unique-index-violations-on-updates-in-mysql/ schrieb:

    The solution is to update the rows in a different order. MySQL allows an ORDER BY clause on UPDATE statements:

    update t set i = i + 1 order by i desc;



  • Ja, das ist besser! 👍


Log in to reply