Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

Verknüpfung mit einer Tabelle von drei möglichen

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von TonySunshine, 8 Mai 2013.

  1. TonySunshine

    TonySunshine Benutzer

    Hallo zusammen,

    ich bin eigentlich recht fit in SQL habe jetzt aber mal ein Problem bei dem ich Hilfe gebrauchen könnte.

    Auf meiner website kann man sich mit Facebook, Google Plus oder Twitter anmelden, dafür habe ich jeweils drei Tabellen erstellt und referenziere von meiner Tabelle User auf die entsprechende Id.

    Mein Problem ist jetzt wie ich ein möglichst kurze und schnelle Abfrage machen kann sodass ich von der UserId auf den Usernamen komme.

    Meine erste überlegung war ein UNION über alle drei Tabellen, das finde ich allerdings sehr kompliziert und wahrscheinlich ist es auch nicht besonders schnell.

    Hier mal meine Struktur:
    sql.jpg
    Ich habe beispielsweise die UserId 12 und möchte dazu per SQL den Usernamen, weiß aber nicht das User 12 ein Facebook User ist. Jemand eine Idee?

    Vielen Dank
    Dennis
     
  2. akretschmer

    akretschmer Datenbank-Guru

    Dein Schema skaliert nicht: wenn morgen ein weiterer Dienst dazukommt, änderst Du ALLES. Mach einfach eine Tabelle für social Media, wo derzeit halt Twitter, Fratzenbuch und Gurgel drin stehen, und eine weitere Spalte in Deiner User-Tabelle mit FK auf die eben genannte Tabelle. Damit löst sich dann auch Dein Problem.
     
    Walter gefällt das.
  3. TonySunshine

    TonySunshine Benutzer

    Genau das hatte ich gehofft nicht machen zu müssen.

    Könnte ich nicht in die User Tabelle eine Spalte Network hinzufügen in der "Facebook", "Google" ... steht und mein SQL Befehl dann irgendwie so aufbauen das die Verknüpfung zur richtigen Tabelle automatisch anhand dieser Network Spalte gemacht wird?

    Ja hatte ich auch drüber nachgedacht, aber ich wollte gerne dem User die Möglichkeit geben zusätzlich zu seinem facebook account, auch seinen Google Account angeben zu können um die Freundesliste beider Netzwerke zu sehen.

    Außerdem hätte ich gedacht das es etwas schneller ist, weil die einzelnen Tabellen ja nicht so groß sind wie eine große, oder?
     
  4. akretschmer

    akretschmer Datenbank-Guru

    So etwa:

    Code:
    kretschmer@tux:~$ psql test
    Timing is on.
    psql (9.2.4)
    Type "help" for help.
    
    test=# create table social_media(id int primary key, name text);
    NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "social_media_pkey" for table "social_media"
    CREATE TABLE
    Time: 362,040 ms
    test=*# create table my_users(id serial primary key, name text);
    NOTICE:  CREATE TABLE will create implicit sequence "my_users_id_seq" for serial column "my_users.id"
    NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "my_users_pkey" for table "my_users"
    CREATE TABLE
    Time: 93,477 ms
    test=*# create table user_media (user_id int references my_users, media_id int references social_media, primary key(user_id, media_id));
    NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "user_media_pkey" for table "user_media"
    CREATE TABLE
    Time: 68,268 ms
    test=*#
    
    Über welche Größen reden wir? Selbst im 2-stelligen Millionenbereich würde ich mir da noch keine Gedanken machen.
     
  5. ukulele

    ukulele Datenbank-Guru

    Wenn du nur eine Tabelle zum speichern der Anmeldeinformationen nutzt muss das ja nicht zwigend heißen das auch immer nur eine Anmeldung existiert. Du fügst der Tabelle eine Spalte "Dienst" hinzu die zwischen Google und Co. unterscheidet und ein User kann dann eben mehrere Anmeldungen in dieser Tabelle haben, das skaliert dann wunderbar. Theoretisch kann man so auch Konten für Personengruppen anlegen die aber nicht alle den selben Zugang sondern jeder seinen eigenen verwenden.

    In deiner jetzigen Form kannst du mit einem UNION von 3 Selects arbeiten, das sollte kein Problem darstellen. Du kannst natürlich auch mit dynamischem SQL einen Befehl erstellen in dem du andere Bedingungen mit abfragst aber schneller wird das auch nicht als grade 3 Tabellen abzufragen. Die Dauer hierfür sollte weit unter einer Sekunde liegen.
     
  6. TonySunshine

    TonySunshine Benutzer

    Damit willst du mir sagen das ich eine weitere Tabelle anlegen sollte, damit der Benutzer mehrere Social Network benutzen kann? Hmm ja ok ist auch ne idee, finde es allerdings mit einer Tabelle pro Social Network schöner.

    Kann ich nicht sowas in die richtung machen, wie ich mit der Network Spalte in der Tabelle User beschrieben hatte? Irgendwie in die Richtung:
    SELECT n.* FROM User u, [u.Network] n WHERE n.Id=u.[u.Network]


    Ach echt? Ok ich unterschätze wohl die geschwindigkeit von sql. dann ist die geschwindigkeit kein argument.
     
  7. TonySunshine

    TonySunshine Benutzer

    Mein abfragen sind teilweise eh schon lang und um dann nur den UserNamen herauszubekommen, wollte ich das UNION verhindern zu benutzen. Danach wären meine Abfragen ja alle 3 - n mal so lang wie vorher. Außerdem wollte ich verhindern das ich alle SQL Abfragen anfassen muss, wenn ein weiteres Social Network hinzufüge
     
  8. ukulele

    ukulele Datenbank-Guru

    In diesem Fall würde ich auf jeden Fall auf eine ein-Tabellen-Lösung wechseln. Tabelle "Logins" enthällt dann ein Fremdschlüssel der auf das Userprofil verweißt, den eigentlichen Login und den jeweiligen Dienst per ID, Kennung oder eben Name, das ist auch nicht so dramatisch. Ein User kann dann mehrere Logins führen, sogar mehrere pro Dienst und bei einem neuen Dienst muss an der Tabellenstruktur nichts geändert werden.
     
  9. TonySunshine

    TonySunshine Benutzer

    Hmm OK also wisst ihr auch nicht wie man so was verknüpft? Schade, trotzdem vielen dank für eure Hilfe
     
  10. ukulele

    ukulele Datenbank-Guru

    Doch wie schon geschrieben bei mehreren Tabellen mit UNION.
     
  11. TonySunshine

    TonySunshine Benutzer

    naja da ist ja das problem, das ich bei einem neuen social network jedes mal alle meine sql abfragen ändern muss.

    die einzige lösung wäre gewesen, wenn ich die verknüpfung anhand des spalten namen hätte machen können z.b in der tabelle "user" gibt es die spalte "google" und wenn in der eine id steht verknüpfe ich diese mit der gleich namigen tabelle "google"
     
  12. ukulele

    ukulele Datenbank-Guru

    Nein das ist nicht die einzige Lösung, habe ja versucht dir eine ein Tabellen Lösung schmackhaft zu machen.

    Natürlich kannst du eine Spalte "google" machen und einen Fremdschlüssel auf die Tabelle "google" verweisen lassen. Aber in diesem Fall musst du ja grade deine Tabellenstruktur und deine Abfragen bei einem neuen Dienst ergänzen. Wenn du das nicht willst macht es überhaupt keinen Sinn eine Tabelle für jeden Dienst anzulegen sondern nur eine Tabelle für alle Dienste zu nutzen.
     
  13. TonySunshine

    TonySunshine Benutzer

    das ich die möglichkeit habe alles in eine tabelle zu machen ist mir klar, auch wie ich eine spalte user.google mit der tabelle google.id verknüpfe ist mir klar. du verstehst nicht was ich meine.

    meine frage war ob ich eine spalte "user.name" in der jeweils der wert 'Facebook', 'Google' oder 'Twitter' stehen kann, automatisch dazu bringen kann die spalte "user.facebook" mit der spalte"facebook.id" zu verknüpfen bzw. die spalte "user.google" mit "google.id" usw.

    In dem Fall würde ich bei einem neuen network einfach eine neue spalte z.b. "user.linkedin" anlegen und eine neue tabelle "linkedin" und müsste keinen meiner sql abfragen anfassen, weil die automatisch anhand der "user.name" spalte die verknüpfung automatisch machen würde.

    ich dachte es gäbe sowas wie:

    SELECT n.* FROM User u, [u.Name] n WHERE n.Id=u.[u.Network]
     
  14. akretschmer

    akretschmer Datenbank-Guru

    Du kannst Dir gern sowas wünschen, aber das gibt es halt (derzeit) im SQL-Standard nicht. Punkt.

    Was es gibt, sind tonnenweise Abhandlungen über relationale Datenbanken, und es ist fast immer gut, sich daran zu halten.
     
  15. ukulele

    ukulele Datenbank-Guru

    Naja du kannst schon ein SQL Script basteln aber in einer Abfrage geht es definitiv nicht.
    Code:
    DECLARE    @tabelle VARCHAR(20),
            @char VARCHAR(255)
     
    SELECT    @tabelle = u.Network
    FROM    [User] u
    WHERE    u.id = 123
     
    SET        @char = '
    SELECT    login
    FROM    ' + @tabelle
     
    EXEC    @char
    Du fragst erst den Inhalt der Spalte mit dem Dienstnamen ab, schreibst ihn in eine Variable, erzeugst das SQL Statement als String (vorsicht, SQL Injection möglich!) und führst das mit EXEC aus.
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden