lixx: Relationale Datenbank

Schönen Abend!

Ich hätte da eine Grudsatzfrage, wie man am Besten mit einer relationalen Datenbank umgeht.

Verwendet wird MySQL 4.1 und PHP5.

Meine Struktur ist folgende:

Adressen ( id )
Adressen_Gruppen ( aid, gid )
Gruppen ( id )

Wenn ich nun eine Adresse anlege, habe ich im Eingabeformular eine Optionsliste (<select ... multiple="multiple">) mit der man der Adresse (mehrere) Gruppen zuteilen kann.

INSERT INTO Adressen ...
INSERT INTO Adressen_Gruppen ... VALUES (...), (...), (...)

Soweit alles klar.

Wovon ich nun keinen dunst habe, ist wie man dann diese Datensätze aktualisiert.

Nehmen wir an, es gibt die Gruppen "Auto", "Haus", "Dorf"

Nun habe ich eine Adresse angelegt die in der Gruppe "Auto" und "Haus" ist. Wenn ich jetzt den Datensatz im Eingabeformular bearbeite und der Adresse die Gruppen "Haus" und "Dorf" zuweise, was soll dann passieren?

Grob gesprochen müßte ich zuerst alle referenzierten Datensätze aus der Tabelle "Adressen_Gruppen" löschen und die neuen anlegen.

Wird das wirklich so gemacht, oder gibt es eine Möglichkeit, die Datensätze zu löschen, die man nicht mehr braucht und die hinzuzufügen, die neu dazugekommen sind?

Wäre für jede Hilfe dankbar!

lg lixx

  1. Hallo,

    Wird das wirklich so gemacht, oder gibt es eine Möglichkeit, die Datensätze zu löschen, die man nicht mehr braucht und die hinzuzufügen, die neu dazugekommen sind?

    welche Datensätze hinzuzufügen und welche Du löschen musst, das solltest Du in der API (sprich PHP) ermitteln. PHP hat nette Funktionen, um mit Arrays umzugehen. Es ist keine gute Idee, das DBMS unnötig damit zu belasten, Einträge zuerst zu löschen, nur um sie anschließend wieder anzulegen.

    Freundliche Grüße

    Vinzenz

    1. Guten Morgen!

      Danke für die Antwort.

      @King^Lully:

      Versuche erst einmal mit Adressen und Gruppen klarzukommen, wir bezweifeln einfach mal, dass eine weitere Entität "Adressen_Gruppen" benötigt wird.

      Zuerst hatte ich zwei Tabellen und in der Adress-Tabelle ein Feld in denen die ID der Gruppe als Kommaseperierter String eingetragen war. Nachdem ich damit auch Probleme hatte hat man mir in diesem Forum geraten eine MN-Rel zu erstellen. Die Probleme waren der Art, wenn eine Gruppe gelöscht wurde, alle Adressen die der Gruppe zugeteilt wurden aktualisiert hätten werden müssen.

      @Vinzenz Mai

      welche Datensätze hinzuzufügen und welche Du löschen musst, das solltest Du in der API (sprich PHP) ermitteln. PHP hat nette Funktionen, um mit Arrays umzugehen. Es ist keine gute Idee, das DBMS unnötig damit zu belasten, Einträge zuerst zu löschen, nur um sie anschließend wieder anzulegen.

      Aber wie ich das jetzt verstehe, wird das auch so gemacht und es gibt dabei keine einfachere lösung?

      Die Vorgehensweise beim UPDATE wäre also die:

      1. Mit PHP die Differenzen ermitteln
      2. UPDATE Adressen -- des aktualisierten Datensatzes
      3. INSERT INTO Adressen_Gruppen -- "Dorf"
      4. DELETE FROM Adressen_Gruppen -- "Auto"

      und beim DELETE einer Gruppe:

      1. DELETE FROM Gruppen
      2. DELETE FROM Adressen_Gruppen -- mit der id der Gruppe

      Beim UPDATE ersterer Variante (nicht relational) wäre ich so vorgegangen:

      1. UPDATE Adressen -- Neuer Kommaseperierter Inhalt

      Beim Löschen:

      1. DELETE Gruppen
      2. UPDATE Adressen -- Vielleicht mit FIND_IN_SET, CONCAT etc. Neue Liste ohne der Gruppen-ID erstellen und aktualisieren.

      Ehrlich gesagt, weiß ich auch nicht was die bessere Variante ist. Daher wollte ich einmal wissen, wie Profis das machen ;)

      lg lixx

      1. Zuerst hatte ich zwei Tabellen und in der Adress-Tabelle ein Feld in denen die ID der Gruppe als Kommaseperierter String eingetragen war. Nachdem ich damit auch Probleme hatte hat man mir in diesem Forum geraten eine MN-Rel zu erstellen. Die Probleme waren der Art, wenn eine Gruppe gelöscht wurde, alle Adressen die der Gruppe zugeteilt wurden aktualisiert hätten werden müssen.

        Statt einem "Frickel-Feld" ist dann eine vernünftige "n:m"-Implementation per zusätzlicher Tabelle in der Tat richtig.

        Ehrlich gesagt, weiß ich auch nicht was die bessere Variante ist. Daher wollte ich einmal wissen, wie Profis das machen ;)

        Du hast doch zwei Entitäten "Adressgruppen" und "Adressen". Wenn Du da Beziehungen hinzufügen, ändern oder löschen möchtest, so machst Du das in der "n:m"-Tabelle. Wenn Du "Adressgruppen" bspw. löschen möchtest, dann prüfst Du, ob das möglich ist, oder ob abhängige Objekte existieren, die verweisen würden. Dasselbe gilt für die "Adressen". Wo ist das Problem? (Dass nicht mehr alles in einem Statement geht, sollte _kein_ Problem sein.)

        1. Guten Morgen!

          (Dass nicht mehr alles in einem Statement geht, sollte _kein_ Problem sein.)

          Schön wäre es doch, wenn es z.B. einen eigenen Befehl gäbe, der das erledigt. Zumindestens die Abgleichung der Relationen beim update. Jetzt benötige ich vier Abfragen und eine menge an PHP-Code.

          Meine Lösung sieht nun so aus:

          UPDATE Adressen -- Datensatz aktualisieren

          "DELETE FROM Adressen_Gruppen WHERE Adressen_ID='123' AND Gruppen_ID NOT IN ( ".implode(', ', $_REQUEST['Gruppen_ID'])." );" -- Nicht benötigte Geuppen löschen

          SELECT * FROM Adressen_Gruppen WHERE Adressen_ID='123'; -- Übrige Beziehungen holen

          -- Mit PHP bereits vorhabdene Beziehungen aus $_REQUEST['Gruppen_ID'] löschen

          INSERT INTO Adressen_Gruppen ( Adressen_ID, Gruppen_ID ) VALUES (...), (...), ... -- Neu hinzugekommene Relationen einfügen

          lg lixx

          1. Hallo

            Schön wäre es doch, wenn es z.B. einen eigenen Befehl gäbe, der das erledigt. Zumindestens die Abgleichung der Relationen beim update. Jetzt benötige ich vier Abfragen und eine menge an PHP-Code.

            ich verstehe Dich nicht.
            Du benötigst doch nur eine PHP-Funktion:

            function aktualisiere_adress_gruppen_zuordnung ( array zuordnung_neu, array zuordnung_alt)

            Du solltest bereits in einer PHP-Variablen haben:
            a) alte Gruppenzuordnung
               aus der Anzeige beim Formular
               (könntest Du z.B. in einer Session speichern)
            b) neue Gruppenzuordnung
               aus der Formularübermittlung

            Das heißt, dass Du für die Ermittlung der zu löschenden Gruppenzuordnungen und die Ermittlung der einzufügenden Zuordnungen _kein einziges_ SQL-Statement abschicken musst. Im Anschluß kommt genau ein DELETE-Statement und genau ein INSERT-Statement. D.h. Deine Funktion benötigt genau zwei SQL-Statements, um die Du sowieso nicht herumkommst:

            Du musst (ggf.) löschen:  DELETE
            Du musst (ggf.) einfügen: INSERT

            Auch wenn die Aktualisierung an der DB übertragen würde, Stichwort Stored Procedures (SP), MySQL 5.x, was Dir soweit ich mich erinnere noch nicht zur Verfügung steht, wären innerhalb der SP diese beiden Operationen durchzuführen. Es entfällt etwas Verbindungsoverhead.

            Weiterhin solltest Du berücksichtigen, wie oft solche Operationen vorkommen. Ich gehe nicht davon aus, dass sich die Gruppenzuordnungen häufig wechseln. Nachdem sie einmal ordentlich zugewiesen sind, wird es gelegentliche Änderungen geben.

            Freundliche Grüße

            Vinzenz

            1. Na das bringt mal frischen Wind in die Sache ;)

              Werde das gleich mal ausprobieren. Oft ist es nur eine Frage des WIE's.

              danke & lg lixx

  2. Meine Struktur ist folgende:

    Adressen ( id )
    Adressen_Gruppen ( aid, gid )
    Gruppen ( id )

    Wenn ich nun eine Adresse anlege, habe ich im Eingabeformular eine Optionsliste (<select ... multiple="multiple">) mit der man der Adresse (mehrere) Gruppen zuteilen kann.

    INSERT INTO Adressen ...
    INSERT INTO Adressen_Gruppen ... VALUES (...), (...), (...)

    Soweit alles klar.

    Wovon ich nun keinen dunst habe, ist wie man dann diese Datensätze aktualisiert.

    So weit, so breit.

    Nehmen wir an, es gibt die Gruppen "Auto", "Haus", "Dorf"

    Nun habe ich eine Adresse angelegt die in der Gruppe "Auto" und "Haus" ist. Wenn ich jetzt den Datensatz im Eingabeformular bearbeite und der Adresse die Gruppen "Haus" und "Dorf" zuweise, was soll dann passieren?

    Grob gesprochen müßte ich zuerst alle referenzierten Datensätze aus der Tabelle "Adressen_Gruppen" löschen und die neuen anlegen.

    Wird das wirklich so gemacht, oder gibt es eine Möglichkeit, die Datensätze zu löschen, die man nicht mehr braucht und die hinzuzufügen, die neu dazugekommen sind?

    Wäre für jede Hilfe dankbar!

    Versuche erst einmal mit Adressen und Gruppen klarzukommen, wir bezweifeln einfach mal, dass eine weitere Entität "Adressen_Gruppen" benötigt wird.

    Rückfragen sind uns - wie eigentlich meist - willkommen!