Matze: MySQL - Frage zu Beziehungstabellen

Hallo!

Ich hab 3 Tabellen, Tabellen A und B mit den Datensätzen und Tabelle C mit der Zuordnung.
Wenn ich jetzt in Tabelle B einen neuen Datensatz einfüge, wird eine Beziehung zu Tabelle A hergestellt. Die Tabelle A besitzt selbst keine Abhängigkeit.

Wenn ich also in Tabelle B einen Datensatz einfüge, muss ich anschließend noch die Beziehung zu Tabelle A in Tabelle C speichern.

Meine Frage ist jetzt, ob ich dazu die 2 INSERT-Statements brauche oder ob es dafür etwas ähnliches wie ON DELETE|UPDATE CASCADE etwas gibt, dass mir die Einträge in beiden Tabellen gleichzeitig erstellt.

Danke und Grüße, Matze

  1. Die Automatik die du suchst, weiß doch nichts von den Abhängigkeiten. Wenn du was in A und B einfügst, wer sagt der Automatik dann dass es überhaupt Abhängigkeiten gibt und welche das genau sind?

    1. Hey!

      Die Automatik die du suchst, weiß doch nichts von den Abhängigkeiten. Wenn du was in A und B einfügst, wer sagt der Automatik dann dass es überhaupt Abhängigkeiten gibt und welche das genau sind?

      Was spricht dagegen diese Abhängkeit mit ins Statement zu schreiben?
      Umgedreht geht es ja auch mit REFERENCES.

      Grüße, Matze

      1. Hallo,

        Was spricht dagegen diese Abhängkeit mit ins Statement zu schreiben?
        Umgedreht geht es ja auch mit REFERENCES.

        Es ist ja nicht zwingend gesagt, dass diese Verknüpfung gleichzeitig passieren soll.

        Man denke an eine Web-Anwendung, bei der Du beide Objekte unabhängig voneiander erstellst (= die INSERTS in den zwei Tabellen ausführst) und erst zu einem späteren Zeitpunkt die Zuordnung durchführst, und damit die beiden Tabellen in der dritten verknüpfst - das muss ja nicht zwingend ein und dieselbe Aktion sein.

        Du könntest evtl. so etwas was Du haben willst mit einem http://dev.mysql.com/doc/refman/5.1/de/create-trigger.html@INSERT-Trigger basteln.

        Die Frage ist aber, ob Du das zwingend brauchst.

        Die drei INSERTS hintereinander ausführen und dann innerhalb einer Transaktion kappseln, sollte auch seinen Zweck erfüllen:
        Entweder diese klappt, dann sind die Einträge korrekt miteinander verknüpft, oder eins der INSERTS schlägt fehl, dann entfernt ein Rollback alle drei Einträge - die referentielle Integrität bliebe damit auch gewahrt.

      2. Hi!

        Was spricht dagegen diese Abhängkeit mit ins Statement zu schreiben?
        Umgedreht geht es ja auch mit REFERENCES.

        Ein DBMS, das Referenzen verwaltet (MySQL mit InnoDB-Engine), macht dies nur im Hinblick auf DBMS-technische Aspekte (Verweisziel muss vorhanden sein). Es berücksichtigt nicht die Beziehungen gemäß der Anwendungslogik. Wenn du was Zusammenhängendes haben willst, erstell eine Stored Procedure. Wenn du einen Automatismus haben möchtest, nimm einen Trigger.

        Lo!

  2. Hi!

    Ich hab 3 Tabellen, Tabellen A und B mit den Datensätzen und Tabelle C mit der Zuordnung.
    Wenn ich jetzt in Tabelle B einen neuen Datensatz einfüge, wird eine Beziehung zu Tabelle A hergestellt. Die Tabelle A besitzt selbst keine Abhängigkeit.

    Drei Tabellen benötigt man nur bei einer m:n-Beziehung. Das heißt, wenn zu einem A beliebig viele (inklusive keine) B existieren können _und_ umgekehrt. Wenn zu einem Eintrag in B ein Verweis zu _einem_  Eintrag in A existieren soll, braucht es nur eine weitere Spalte in B und keine dritte Tabelle.

    Lo!

    1. Hi dedlfix!

      Drei Tabellen benötigt man nur bei einer m:n-Beziehung. Das heißt, wenn zu einem A beliebig viele (inklusive keine) B existieren können _und_ umgekehrt. Wenn zu einem Eintrag in B ein Verweis zu _einem_  Eintrag in A existieren soll, braucht es nur eine weitere Spalte in B und keine dritte Tabelle.

      Oh ok, danke! Dann spar ich mir mal die ganze Arbeit.
      Ich hätte nämlich auch gleich noch ein Problem mit einer GROUP BY Anweisung dabei :)

      Damit ich mir nicht weiter den Kopf zerbreche, kannst du mir vielleicht grad meinen Fehler nennen.

      Also die 3 Tabellen:

      TabelleA
      category | id
      TabelleB -> Beziehungstabelle
      categoryId | dataId | id
      TabelleC
      data | moreData | andStillMoreData | id

      Mein Versuch:

      SELECT TabelleA.category AS category,  
             TabelleA.id AS catId,  
             TabelleC.data AS data,  
             TabelleC.moreData AS mD,  
             TabelleC.andStillMoreData AS asmD,  
             TabelleC.id AS dId  
      FROM TabelleA  
      JOIN TabelleB ON TabelleB.categoryId = TabelleA.id  
      JOIN TabelleC ON TabelleC.id = TabelleB.dataId  
      GROUP BY TabelleB.categoryId
      

      ^^^^^^^^^^^^^^^^^^^

      Dabei erhalte ich aber immer nur den jeweils ersten Wert der zutrifft.
      Wieso ist das so?
      Und wie krieg ich alle Datensätze aus TabelleC die in TabelleB mit Tabelle A verknüpft sind?

      Danke für deine Hilfe!

      Grüße, Matze

      1. Hi!

        Ich hätte nämlich auch gleich noch ein Problem mit einer GROUP BY Anweisung dabei :)
        Dabei erhalte ich aber immer nur den jeweils ersten Wert der zutrifft.
        Wieso ist das so?

        Eine Gruppierung nimmt man, wenn man Aggregatfunktionen darauf anwenden möchte. Üblicherweise lassen DBMSe in der SELECT-Klausel nur die Felder zu, über die gruppiert wurde und die Aggregatfunktionen. MySQL sieht das anders. Aber du missverstehst das Gruppieren, so wie es aussieht. Du willst stattdessen einen Gruppenwechsel und den bekommt man durch eine ungruppierte aber sortierte Abfrage und wertet beim Ergebnismengenauslesen jeweils den vorhergehenden Wert der "Gruppierspalte" aus und macht bei Unterschieden, das was man tun möchten (neue Zwischenüberschrift oder ähnliches).

        Und dann gibt es auch noch GROUP_CONCAT(), wenn dir pro Gruppe eine Liste der Werte mit Trennzeichen aneinandergereiht reicht.

        Und wie krieg ich alle Datensätze aus TabelleC die in TabelleB mit Tabelle A verknüpft sind?

        Frag C gejoint mit B. A brauchst du nur, wenn du daraus Daten benötigst. Ansonsten ist ein vorhandener Datensatz in B schon eine Aussage, dass eine Beziehung zu A besteht.

        Lo!

        1. Hey!

          Danke, ich war wirklich auf dem Holzweg. Ich weiß auch nicht was mich da gepackt hat.

          Grüße, Matze

      2. Hallo,

        Ich hätte nämlich auch gleich noch ein Problem mit einer GROUP BY Anweisung dabei :)

        Damit ich mir nicht weiter den Kopf zerbreche, kannst du mir vielleicht grad meinen Fehler nennen.

        SELECT TabelleA.category AS category,

        TabelleA.id AS catId,
               TabelleC.data AS data,
               TabelleC.moreData AS mD,
               TabelleC.andStillMoreData AS asmD,
               TabelleC.id AS dId
        FROM TabelleA
        JOIN TabelleB ON TabelleB.categoryId = TabelleA.id
        JOIN TabelleC ON TabelleC.id = TabelleB.dataId
        GROUP BY TabelleB.categoryId

          
        
        > Dabei erhalte ich aber immer nur den jeweils ersten Wert der zutrifft.  
          
        Nein. Du erhältst nicht vorhersagbare Werte in den Spalten, die bei gleichen Werten in der Spalte TabelleB.categoryId unterschiedliche Werte aufweisen.  
          
        
        > Wieso ist das so?  
          
        Weil Dein MySQL-Server so konfiguriert ist, dass er solche Abfragen zuläßt.  
        Das ist MySQL-Standard, [ich finde das nicht gut](https://forum.selfhtml.org/?t=195578&m=1309185).  
          
          
        Freundliche Grüße  
          
        Vinzenz
        
        1. Moin Vinzenz!

          Wieso ist das so?

          Weil Dein MySQL-Server so konfiguriert ist, dass er solche Abfragen zuläßt.
          Das ist MySQL-Standard, ich finde das nicht gut.

          Das ist wirklich ein merkwürdiges Verhalten.
          Abgesehen davon, dass ich tatsächlich ein Brett vor dem Kopf hatte was GROUP BY angeht, hat mich das Ergebnis ziemlich irritiert.

          Ich geb auch zu, dass ich nur angenommen habe es wäre der erste passende Datensatz der mir ausgeliefert wird. Tatsächlich enthalten alle 3 Tabellen nur jeweils 3 Testwerte. Da können sich Zufallswerte schon mal gleichen, ohne dass man es merkt.

          Danke für den Hinweis!

          Grüße, Matz