Ich dränge meinen Kopf gegen etwas und ich frage mich, ob jemand erfahrener wäre, der mir helfen könnte.
Mein Ziel ist es, einen Kommentarthread zu erstellen, der ein System der Kommentierung berücksichtigt.
Zuerst werde ich erklären, wo ich gerade bin.
Angenommen, wir haben einen Kommentar-Thread zu einem Artikel, der wie im folgenden Beispiel aussieht. Die Zahl in Klammern ist die ID dieses Kommentars. IDs werden automatisch von der Datenbank zugewiesen und chronologisch mit jedem weiteren geposteten Kommentar erhöht. Die Anzahl der Striche vor dem Kommentartext spiegelt die Kommentartiefe wider.
%Vor%Mein erstes Problem bestand darin, diese Daten so zu speichern, dass sie in der richtigen Reihenfolge zurückgegeben werden können. Wenn Sie einfach ein Tiefenfeld und eine Reihenfolge nach Tiefe speichern, werden zuerst alle Kommentare der obersten Ebene und dann die Kommentare der zweiten Ebene usw. zurückgegeben. Das ist nicht richtig, wir müssen die Kommentare mit der vollständigen, noch intakten Herkunft zurückgeben.
Eine Möglichkeit, dies zu erreichen, besteht darin, die vollständige Abstammung für jeden Kommentar zu speichern.
%Vor%Das Hinzufügen eines weiteren Kommentarsatzes ist so einfach wie das Abrufen der Abstammung aus dem Kommentar, auf den Sie antworten, und das Anhängen seiner ID an die neue Elternschaft. Zum Beispiel, wenn ich auf Kommentar 10 antworten würde, würde ich seine Abstammung nehmen (03-05-08-) und seine ID anhängen (10-). Die Datenbank würde dies automatisch als 11. Kommentar erkennen, und wir erhielten:
%Vor%Wenn wir nun die Kommentare zur Anzeige anordnen, ordnen wir eine Verkettung der Eltern- und Kommentar-ID an, die uns folgendes gibt:
%Vor%Welches genau die gleiche Liste wie zuerst gezeigt produziert. Mit Kommentar 11, den wir später hinzugefügt haben, an der richtigen Stelle eingefügt:
%Vor%Das Einrücken kann durch Überprüfen der Länge der CONCAT-Zeichenfolge und Multiplizieren der len (CONCAT (Abstammung, ID)) mit einer festgelegten Anzahl von Pixeln erfolgen. Das ist großartig, wir haben ein System zum Speichern von Kommentaren auf eine Weise, die ihre Abstammung erkennt.
Jetzt das Problem:
Nicht alle Kommentare sind gleich. Ein System der Kommentarbewertung ist erforderlich, um gute Kommentare zu unterscheiden. Nehmen wir an, jeder Kommentar hat eine Schaltfläche zum Hochladen. Während wir die Eltern behalten möchten, wenn ein Kommentar zwei direkte Antworten auf derselben Ebene hat, möchten wir zuerst die mit den meisten Upvotes anzeigen. Ich füge unten [eckige Klammern] einige Stimmen hinzu.
%Vor%In diesem Beispiel sind die Kommentare (01) und (03) beide auf der obersten Ebene, aber (03) hat [50 Stimmen] und (01) hat nur [6 Stimmen]. (01) erscheint oben nur aufgrund der Tatsache, dass es früher gebucht wurde und daher eine kleinere ID zugewiesen wurde. Ebenso sind (02) und (06) beide Antworten auf (01), müssen aber neu geordnet werden, damit derjenige mit den meisten Stimmen (06) an die Spitze gelangen kann.
Ich bin ganz und gar in dem Versuch stecken, das zu erreichen.
Ich stelle mir vor, dass jede Bestellung / Neuordnung und Indexierung besser auf einer Kommentar-Abstimmung statt auf Seitenladung durchgeführt werden würde, so dass die Seitenladezeit so schnell wie möglich sein kann, aber darüber hinaus habe ich absolut keine Ahnung!
Irgendwelche Ideen oder Licht, das Sie auf mögliche Wege werfen könnten, würden wirklich eine Last wegnehmen! Danke für deine Hilfe wie immer.
Bearbeiten: Als Antwort auf @ Paddys Lösung,
Wenn ich den von @Paddy angebotenen Ausdruck auf den Scheindaten ausführe, ist der erste Fehler, den ich bekomme:
%Vor%Dies kann behoben werden, indem der rekursiven Elementdefinition SELECT 'top 100 Prozent' hinzugefügt wird. Sobald dies erledigt ist, bekomme ich den Fehler:
%Vor%Dies kann gelöst werden, indem der CommentTree-Spezifikation eine Spalte "Level" hinzugefügt wird. Dies gibt dann die Daten aus, aber es gibt zuerst alle Kommentare der obersten Ebene zurück und dann etwas, das der richtigen Sortierreihenfolge ähnelt (aber nicht wirklich übereinstimmt).
Die Daten werden als solche zurückgegeben:
%Vor%Habe ich etwas falsch gemacht oder hat @Paddy etwas übersehen? Bitte akzeptieren Sie meine Entschuldigung, rekursive Funktionen sind sehr neu für mich.
Code unten sieht gut für Ihre Aufgabe aus. Es ist ein bisschen komplex, aber es war eine Herausforderung für mich, es in einem einzigen SELECT
zu machen. Sie können es in mehrere SELECT
mit Prefetch in temporäre Tabellen (für Leistungszwecke) aufteilen oder zusammenhalten.
Danke für die Frage, es war interessant!
Bitte beachten Sie, dass ParentID
für Wurzelknoten 0
, nicht NULL
sein muss.
In dieser Abfrage mache ich folgendes:
SELECT
. position = 1
position = parent_position + 1
position = prev_sibling_position + prev_sibling_number_of_descendants
BEARBEITEN Dieselbe Lösung, aber ohne CTE.
%Vor%Obwohl Sie nicht direkt mit Ihrer Frage in Verbindung stehen, würde ich vorschlagen, zum Nested Set-Modell . Ich weiß, es ist eine Menge Nacharbeit, aber früher oder später werden Sie feststellen, dass es die beste Wahl ist:)
Tags und Links sql mysql sorting hierarchical-data commenting