sql vorteile Stellen Sie die Bestellung in einer relationalen Datenbank dar




relationale datenbank vorteile (8)

Ich habe eine Sammlung von Objekten in einer Datenbank. Bilder in einer Fotogalerie, Produkte in einem Katalog, Kapitel in einem Buch usw. Jedes Objekt wird als eine Reihe dargestellt. Ich möchte in der Lage sein, diese Bilder beliebig zu ordnen und diese Reihenfolge in der Datenbank zu speichern. Wenn ich die Objekte zeige, sind sie in der richtigen Reihenfolge.

Nehmen wir zum Beispiel an, ich schreibe ein Buch, und jedes Kapitel ist ein Objekt. Ich schreibe mein Buch und lege die Kapitel in folgender Reihenfolge:

Einführung, Zugänglichkeit, Form und Funktion, Fehler, Konsistenz, Schlussfolgerung, Index

Es geht an den Editor und kommt mit der folgenden vorgeschlagenen Reihenfolge zurück:

Einführung, Form, Funktion, Zugänglichkeit, Konsistenz, Fehler, Schlussfolgerung, Index

Wie kann ich diese Bestellung robust und effizient in der Datenbank speichern?

Ich hatte die folgenden Ideen, aber ich bin nicht begeistert von ihnen:

  1. Array. Jede Zeile hat eine Bestell-ID. Wenn die Bestellung geändert wird (über eine Entnahme gefolgt von einer Einfügung), werden die Bestell-IDs aktualisiert. Dies erleichtert die Suche, da es nur ORDER BY , aber es scheint einfach zu sein.

    // REMOVAL
    UPDATE ... SET orderingID=NULL WHERE orderingID=removedID
    UPDATE ... SET orderingID=orderingID-1 WHERE orderingID > removedID
    // INSERTION
    UPDATE ... SET orderingID=orderingID+1 WHERE orderingID > insertionID
    UPDATE ... SET orderID=insertionID WHERE ID=addedID

  2. Verknüpfte Liste Jede Zeile hat eine Spalte für die ID der nächsten Zeile in der Reihenfolge. Traversal scheint hier teuer zu sein, obwohl ich ORDER BY , an das ich nicht denke, irgendwie einsetzen kann.

  3. Platzierte Anordnung. Legen Sie die orderID (wie in # 1 verwendet) als groß fest, also ist das erste Objekt 100, das zweite ist 200 usw. Wenn eine Insertion stattfindet, legen Sie sie einfach auf (objectBefore + objectAfter)/2 . Natürlich müsste dies gelegentlich neu ausbalanciert werden, so dass Sie nicht zu nahe beieinander sind (selbst mit Floats würden Sie eventuell zu Rundungsfehlern kommen).

Keines von diesen scheint mir besonders elegant zu sein. Hat jemand einen besseren Weg, es zu tun?


Da ich mit Django hauptsächlich auf dieses Problem gestoßen bin, habe ich festgestellt, dass diese Lösung am effektivsten ist. Es scheint, dass es keinen "richtigen Weg" gibt, dies in einer relationalen Datenbank zu tun.


Ich hatte das gleiche Problem und habe wahrscheinlich mindestens eine Woche damit verbracht, mich mit der richtigen Datenmodellierung zu befassen, aber ich glaube, ich habe es endlich verstanden. Unter Verwendung des Array-Datentyps in PostgreSQL können Sie den Primärschlüssel jedes bestellten Artikels speichern und das Array entsprechend aktualisieren, indem Sie Änderungen oder Löschungen vornehmen, wenn sich Ihre Bestellung ändert. Wenn Sie auf eine einzelne Zeile verweisen, können Sie alle Ihre Objekte basierend auf der Reihenfolge in der Arrayspalte zuordnen.

Es ist immer noch ein bisschen abgehackt von einer Lösung, aber es wird wahrscheinlich besser als Option 1 funktionieren, da Option 1 erfordert, die Bestellnummer aller anderen Zeilen bei Bestelländerungen zu aktualisieren.


Wenn die Objekte nicht stark von anderen Tabellen getastet werden und die Listen kurz sind, ist es am einfachsten, alles in der Domäne zu löschen und nur die korrekte Liste neu einzufügen. Aber das ist nicht praktisch, wenn die Listen groß sind und Sie viele Einschränkungen haben, um das Löschen zu verlangsamen. Ich denke deine erste Methode ist wirklich die sauberste. Wenn Sie es in einer Transaktion ausführen, können Sie sicher sein, dass nichts Ungewöhnliches passiert, während Sie sich in der Mitte des Updates befinden, um die Bestellung zu vermasseln.


Ich habe das in meinem letzten Projekt gemacht, aber es war für einen Tisch, der nur gelegentlich speziell bestellt werden musste und nicht zu oft aufgerufen wurde. Ich denke, dass die Anordnung mit Abstand die beste Option wäre, da eine Umordnung im Durchschnitt am billigsten wäre, da nur eine Änderung an einem Wert und eine Abfrage an zwei vorgenommen wird.

Außerdem würde ich mir vorstellen, dass ORDER BY von Datenbankanbietern ziemlich stark optimiert würde, sodass die Nutzung dieser Funktion für die Leistung im Gegensatz zur Implementierung der verknüpften Liste vorteilhaft wäre.


Eine andere Alternative wäre (wenn Ihr RDBMS dies unterstützt), Spalten des Typs array zu verwenden. Während dies die Normalisierungsregeln bricht, kann es in Situationen wie dieser nützlich sein. Eine Datenbank, von der ich weiß, dass sie Arrays hat, ist PostgreSQL.


Verwenden Sie eine Gleitkommazahl, um die Position jedes Elements darzustellen:

Punkt 1 -> 0.0

Punkt 2 -> 1.0

Punkt 3 -> 2.0

Punkt 4 -> 3.0

Sie können jedes Element zwischen zwei anderen Elementen durch einfache Halbierung platzieren:

Punkt 1 -> 0.0

Punkt 4 -> 0,5

Punkt 2 -> 1.0

Punkt 3 -> 2.0

(Position 4 zwischen Position 1 und 2 verschoben).

Der Halbierungsprozess kann nahezu unbegrenzt fortgesetzt werden, da die Fließkommazahlen in einem Computersystem codiert sind.

Punkt 4 -> 0,5

Punkt 1 -> 0,75

Punkt 2 -> 1.0

Punkt 3 -> 2.0

(Bewegen Sie den Gegenstand 1 an die Position kurz nach Punkt 4)


Nur ein Gedanke, der die Option # 1 vs # 3 in Betracht zieht: verschiebt die Option mit dem beabstandeten Array (# 3) nur das Problem des normalen Arrays (# 1)? Egal welcher Algorithmus Sie wählen, entweder ist er kaputt, und Sie werden später mit # 3 Probleme bekommen, oder es funktioniert, und dann sollte # 1 genauso gut funktionieren.


Ich hatte dieses Problem auch. Ich stand unter starkem Zeitdruck (sind wir nicht alle) und ich ging mit Option # 1, und nur die Zeilen, die sich geändert haben.

Wenn Sie Artikel 1 mit Artikel 10 tauschen, führen Sie einfach zwei Aktualisierungen durch, um die Bestellnummern von Artikel 1 und Artikel 10 zu aktualisieren. Ich weiß, dass es algorithmisch einfach ist und es ist O (n) schlimmster Fall, aber der schlimmste Fall ist der Fall eine Gesamtpermutation der Liste. Wie oft wird das passieren? Das musst du beantworten.





django-models