lixx: MySQL und Beziehungstabelle

Hallo Leute!

ich weiß, dass ist jetzt schon ein alter Hut ... und ich kappier's noch immer nicht ;)

Ich möchte in MySQL zwei Tabellen mittels einer n:m Beziehung verknüpfen. Also drei Tabellen. Ich weiß, dass geht mit dem JOIN-Befehl. Aber wie? Nach langwierigem Suchen habe ich folgendes gefunden:

TabelleA
TabelleB -> Beziehungstabelle
TabelleC

SELECT TabelleA.id, TabelleA.SpalteA
FROM TabelleA
JOIN TabelleB ON TabelleB.Aid = TabelleA.id
JOIN TabelleC ON TabelleC.id = TabelleB.Cid
WHERE TabelleC.wert = 'A';

Aber irgenwie kommt mir das schon sehr lange vor. Funtionieren tut es, aber ist es auch effizient? Gibt es da nicht eine einfachere Methode?

lg lixx

  1. yo,

    Aber irgenwie kommt mir das schon sehr lange vor. Funtionieren tut es, aber ist es auch effizient? Gibt es da nicht eine einfachere Methode?

    das ist genau die richtige methode, um die tabellen miteinander zu verbinden. dann noch richtige indexe gesetzt, falls nicht schon vorhanden und dann passt das schon.

    Ilja

    1. Na dann, Super!

      Danke, Ilja!

      lg lixx

      1. Hallo!

        Noch eine Frage: um einen Ausschluß zu bekommen, (um das Beispiel fortzusetzen) also alle Menschen die in keiner Partei sind, ist dann folgender Befehl notwendig:

          
        SELECT  
         Menschen.Menschen_ID,  
         Menschen.Menschen_Vorname,  
         Menschen.Menschen_Nachname  
        FROM  
         Menschen  
        LEFT JOIN  
         Menschen_Parteien ON (Menschen_Parteien_Menschen_ID = Menschen_ID)  
        LEFT JOIN  
         Parteien ON (Parteien.ID = Menschen_Parteien_Parteien_ID)  
        WHERE  
         Parteien.ID IS NULL  
        
        

        stimmt das soweit?

        lg lixx

        1. yo,

          stimmt das soweit?

          ja, vollkommen richtig. Eine kleine verbesserung, es würde reichen über die Beziehungstabelle zu gehen, um festzustellen, ob ein mensch einer partei zugeordnet ist. ist er es nicht, hat seine ID in der Menschen_Parteien Tabelle keinen eintrag.

          Ilja

  2. Ich möchte in MySQL zwei Tabellen mittels einer n:m Beziehung verknüpfen. Also drei Tabellen. Ich weiß, dass geht mit dem JOIN-Befehl.

    Nein, das geht nicht mit dem JOIN, JOIN ist für Abfragen vorgesehen, die bspw. gegen (oder "an" ;) die drei Tabellen (Tabelle "A", "Tabelle B", "Tabelle AB") gerichtet sind.

    Wenn Du zum Beispiel Menschen und pol. Parteien hast, dann können Menschen in n Parteien Mitglied sein (zumindest theor. ;) und Parteien haben m Mitglieder, dann macht man folgendes i.p. Daten-Design:

    Menschen:
    Menschen_ID,
    Menschen_Vorname,
    Menschen_Nachname,
    Menschen_Geburtsdatum          -- etc.
    Parteien:
    Parteien_ID,
    Parteien_Name                  -- etc.
    Menschen_Parteien:
    Menschen_Parteien_ID,
    Menschen_Parteien_Menschen_ID,
    Menschen_Parteien_Parteien_ID
    (bewährte Namensgebung aus dem Hause "King Lully" ;)
    (Es geht da einerseits um eine regelnutzende Namengabe und DB-weit eindeutige Datenfeldnamen, auch wenns im ersten Moment bekloppt aussieht.)

    UND richtet für "Menschen_Parteien_Menschen_ID" und "Menschen_Parteien_Parteien_ID" Fremdschlüssel ein (ggf. auch einen eindeutigen Index auf beide o.g. Datenfelder).

    Erst dann kann von einer implementierten Beziehung die Rede sein.

    Aber wie? Nach langwierigem Suchen habe ich folgendes gefunden:

    TabelleA
    TabelleB -> Beziehungstabelle
    TabelleC

    SELECT TabelleA.id, TabelleA.SpalteA
    FROM TabelleA
    JOIN TabelleB ON TabelleB.Aid = TabelleA.id
    JOIN TabelleC ON TabelleC.id = TabelleB.Cid
    WHERE TabelleC.wert = 'A';

    Weder Namensgebung noch Darstellung der SQL-Query überzeugen, was wäre dagegen von:

      
    SELECT  
     Menschen.Menschen_ID,  
     Menschen.Menschen_Vorname,  
     Menschen.Menschen_Nachname  
    FROM  
     Menschen  
    JOIN  
     Menschen_Parteien ON (Menschen_Parteien_Menschen_ID = Menschen_ID)  
    JOIN  
     Parteien ON (Parteien.ID = Menschen_Parteien_Parteien_ID)  
    WHERE  
     (Parteien_Name = 'CSU')  
    
    

    Wundervoll, oder? Und wie intuitiv!

    Aber irgenwie kommt mir das schon sehr lange vor. Funtionieren tut es, aber ist es auch effizient? Gibt es da nicht eine einfachere Methode?

    Oracle kann die "n:m" angeblich automatisiert verwalten, ist ja eigentlich eher ein anderes DB-Objekt als eine Tabelle, erinnert mich an einen Index (na gut, bei King Lully bekommen die "n:m"-Tabellen immer eine ID ;).

    1. Hallo Lully!

      Irgendwie werde ich aus Deinem Kommentar nicht schlau. Der Aufbau der Tabellen ist bis auf die Namensgeben genau gleich. Mein Beispiel diente ja nur der Veranschaulichung.

      Das ist aber das, was mich am meisten irritiert:

      Nein, das geht nicht mit dem JOIN, JOIN ist für Abfragen vorgesehen, die bspw. gegen (oder "an" ;) die drei Tabellen (Tabelle "A", "Tabelle B", "Tabelle AB") gerichtet sind.

        
       SELECT  
        Menschen.Menschen_ID,  
        Menschen.Menschen_Vorname,  
        Menschen.Menschen_Nachname  
       FROM  
        Menschen  
       JOIN  
        Menschen_Parteien ON (Menschen_Parteien_Menschen_ID = Menschen_ID)  
       JOIN  
        Parteien ON (Parteien.ID = Menschen_Parteien_Parteien_ID)  
       WHERE  
        (Parteien_Name = 'CSU')  
      
      

      Soweit ich Dich verstanden habe stimmt das Beispiel aber der Stil stört dich, oder?

      lg lixx

      1. Soweit ich Dich verstanden habe stimmt das Beispiel aber der Stil stört dich, oder?

        Nein, es gibt eben das Datendesign (das in grossen Teil in Deiner Frage ausgeklammert worden ist) und die Abfrage gegen das Datendesign (JOIN etc.). Dazu kommen noch Stilfragen, aber da hatten wir uns ja klar geaeussert.

        Es spricht übrigens nichts dagegen, wenn Du Dir eine kleine DB aufbaust (sollte max. 10 Minuten dauern) und Dir die Fragen selbst beantwortest. (Vgl. auch Deine Frage weiter unten.)

        1. Es spricht übrigens nichts dagegen, wenn Du Dir eine kleine DB aufbaust (sollte max. 10 Minuten dauern) und Dir die Fragen selbst beantwortest. (Vgl. auch Deine Frage weiter unten.)

          Na, hab ich doch eh! ;)
          Und bei mir funzt es auch.

          Es ist nur so, dass man bei kleinen Datenbanken nicht immer alles berücksichtigen kann und so viel Erfahrung habe ich auch noch nicht. Desshalb frage ich lieber, ob ich richtig liege oder völlig auf dem Holzweg. Und JOIN-Abfragen zu kappieren ist nun wirklich schwer (denk' mal an Deine Anfangszeit ;).

          lg lixx

          1. Und JOIN-Abfragen zu kappieren ist nun wirklich schwer (denk' mal an Deine Anfangszeit ;).

            Ja, das ist technisch gesehen eine Matrizenmultiplikation deren Produkt gefiltert und anderswie bearbeitet daherkommt.

            Wichtig ist, dass man bereit ist ein und denselben Fehler mehrfach zu machen.   ;)

            1. Wichtig ist, dass man bereit ist ein und denselben Fehler mehrfach zu machen.   ;)

              ... davon könnt' ich Dir Geschichten erzählen ... *gg*

              danke & lg lixx