Ankündigung

Einklappen
Keine Ankündigung bisher.

Thread Darstellung

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Thread Darstellung

    Hallo,

    ich habe eine MySQL Tabelle in der eine Art Forenunterhaltungen gespeichert wird.

    ID : Integer
    ReplyID : Integer
    Kommentar : Text

    Jeder Eintrag enhält einen Kommentar.
    ReplyID ist >-1 wenn der Kommentar eine Antwort auf einen anderen Kommentar darstellt. Es kann belibig viele Kommentare und Antworten geben.
    Also eine Baumstruktur

    Meine Frage bezieht sich auf die Codegestaltung.

    Ich würde zur Darstellung eine rekursive PHP-Funktion erstellen, welche als Parameter eine RefID erhält.
    In der Funktion "select * from Table where RefID = :ParamRefID" und
    für jeden vorhandenen Datensatz die Funktion mit der aktuellen ID erneut auftrufen.
    Das wird prinzipiell funtionieren, allerdings genieriere ich eine Unmenge an SQL-Selects.

    Gibt es nicht einen geschickteren Weg um solch eine Unterhaltung darzustellen?

    Gruß
    FXPHP


  • #2
    Zitat von FXPHP Beitrag anzeigen
    Gibt es nicht einen geschickteren Weg um solch eine Unterhaltung darzustellen?
    Ja. Das rekursive Zeugs gleich in der DB machen. Allerdings braucht man dazu eine DB, die das auch kann. MySQL kann es nicht.
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

    Kommentar


    • #3
      Wie kann es eine DB, die es kann?
      Standards - Best Practices - AwesomePHP - Guideline für WebApps

      Kommentar


      • #4
        Gibt es nicht einen geschickteren Weg um solch eine Unterhaltung darzustellen?
        Ich glaube, das hängt auch von dem ab, was du konkret mit den Daten anstellen willst.

        Du könntest beispielsweise pro Eintrag auch den „Thread“ mitspeichern. Aber ob es Sinn ergibt, dann – zum Beispiel – alle Einträge eines Threads auszulesen und die rekursive Geschichte in PHP zu lösen, lässt sich so nicht beurteilen, denke ich.

        Generell zu Performance-Fragen die Warnung vor premature optimization.

        Kommentar


        • #5
          Zitat von rkr Beitrag anzeigen
          Wie kann es eine DB, die es kann?
          Angenommen, Du hast:

          Code:
          test=*# \d fxphp
                Table "public.fxphp"
            Column   |  Type   | Modifiers
          -----------+---------+-----------
           thread_id | integer | not null
           reply_id  | integer |
           t         | text    |
          Indexes:
              "fxphp_pkey" PRIMARY KEY, btree (thread_id)
          Foreign-key constraints:
              "fxphp_reply_id_fkey" FOREIGN KEY (reply_id) REFERENCES fxphp(thread_id)
          Referenced by:
              TABLE "fxphp" CONSTRAINT "fxphp_reply_id_fkey" FOREIGN KEY (reply_id) REFERENCES fxphp(thread_id)
          mit diesen Daten:

          Code:
          test=*# select * from fxphp ;
           thread_id | reply_id |                       t
          -----------+----------+------------------------------------------------
                   1 |          | erster thread
                   2 |        1 | erster thread, erste antwort
                   3 |          | zweiter thread
                   4 |        3 | zweiter thread, erste antwort
                   5 |        1 | erster thread, zweite antwort
                   6 |        2 | erster thread, erste antwort auf erste antwort
          (6 rows)
          Gesamtüberblick;

          Code:
          test=*# with recursive basis as (select *, 0 as level, row_number() over () as thread from fxphp where reply_id is null union all select fxphp.*, basis.level+1, thread from fxphp join basis on (basis.thread_id=fxphp.reply_id)) select thread_id, repeat('-',level) || '>', t, thread from basis order by thread, reply_id;
           thread_id | ?column? |                       t                        | thread
          -----------+----------+------------------------------------------------+--------
                   2 | ->       | erster thread, erste antwort                   |      1
                   5 | ->       | erster thread, zweite antwort                  |      1
                   6 | -->      | erster thread, erste antwort auf erste antwort |      1
                   1 | >        | erster thread                                  |      1
                   4 | ->       | zweiter thread, erste antwort                  |      2
                   3 | >        | zweiter thread                                 |      2
          (6 rows)
          oder

          Code:
          test=*# with recursive basis as (select *, 0 as level, row_number() over () as thread from fxphp where reply_id is null union all select fxphp.*, basis.level+1, thread from fxphp join basis on (basis.thread_id=fxphp.reply_id)) select thread_id, reply_id, repeat('-',level) || '>', t, thread from basis order by thread, coalesce(reply_id,0), reply_id;
           thread_id | reply_id | ?column? |                       t                        | thread
          -----------+----------+----------+------------------------------------------------+--------
                   1 |          | >        | erster thread                                  |      1
                   2 |        1 | ->       | erster thread, erste antwort                   |      1
                   5 |        1 | ->       | erster thread, zweite antwort                  |      1
                   6 |        2 | -->      | erster thread, erste antwort auf erste antwort |      1
                   3 |          | >        | zweiter thread                                 |      2
                   4 |        3 | ->       | zweiter thread, erste antwort                  |      2
          (6 rows)
          Ist sicher noch ausbaufähig.
          PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

          Kommentar


          • #6
            Oder einfach ein Nested Set verwenden, das kann sogar MySQL.
            VokeIT GmbH & Co. KG - VokeIT-oss @ github

            Kommentar


            • #7
              Wobei ein einziges Nested Set wahrscheinlich nicht wahnsinnig witzig wird, wenn es dann irgendwann mal 100 K Einträge oder so sein sollten.

              Auch wenn man ein Set „pro Thread“ anlegen würde, wären sicher noch Szenarien denkbar, in denen Einfügeoperationen sehr teuer werden würden. (100 K Einträge in einem Thread halt. )

              (Falls ich da jetzt nicht was übersehe. Bin mit den Dingern nicht so firm. Und alle Ansätze laufen irgendwann in scaling issues.)

              Kommentar


              • #8
                Separierte Nested Sets pro Thread, ein vernünftiges Limit für die Anzahl Antworten pro Thread und das Problem sollte keines sein, es wird ja nach wie vor x-fach so oft gelesen wie geschrieben, das kann sich durchaus lohnen.
                Die Alternative wären dann noch Pfade, auf Rekursion würde ich aber in jedem Fall verzichten.
                VokeIT GmbH & Co. KG - VokeIT-oss @ github

                Kommentar

                Lädt...
                X