sabse: 2 1:n beziehungen auf einmal

Hey!

...Wenn man das so sagen kann :)
Ich erarbeite gerade mit DBDesigner 4 eine riesige Datenbank und habe nun folgenden Fall:

"usr"               "kunde"

  • id                + id
  • stammdaten_id---- + firma
  • krzl              + strasse
       |                + usw
       |                + usr_id_betreuer
       |                + usr_id_kdzg
       |
    "stammdaten"
  • id
  • vorname
  • nachname
  • usw

ich kann mit DBDesigner 4 nicht 2 Beziehungen erstellen, obwohl das m.M.n. sinn macht.

Die Tabelle "kunde" hat 2 Spalten die sich jeweils 1:n auf die Tabelle "usr" beziehen.
Zum einen gibt es pro Kunde einen Betreuer, dieser steht in "usr". "stammdaten" sagt uns auch wo der "user" wohnt und welche E-Mail-Adresse er hat usw...
Zum anderen werden Kunden auch einem User zugeordnet damit sich unterscheiden lässt wohin Provisionen fließen.
Betreuer und Kunden-Zuordnungen ist eben nicht das selbe.
Wie mache ich das jetzt mit DBDesigner?
Der erstellt mir nämlich nur "usr_id" wenn ich eine Beziehung erstellen möchte Und umbenennen kann ich das dann auch nicht.
Macht es sinn auf beide einen Index zu legen?
Fragen über Fragen! :D

Ich hoffe mein Problem ist klar?
Also ich hätte kein Problem, wenn DBDesigner das einfach nicht kann, aber ich hätte ein Problem wenn ich einen Denkfehler habe und dieser mir erst durch diesen Thread aufällt... aber ich denke nicht :D

Saaaaabse

  1. Hallo,

    ich kenne zwar das Programm nicht mit dem du arbeitest, aber ich vermute einfach einmal folgendes:

    Betreuer     Kunden
    ---------    ------
    ID           ID
    Name         Betruer ID
                 Provision ID

    Wobei "Betruer ID" = "Provision ID" ist.
    Meiner meinung nach ist dies ein Fehler, da man von 2 Spalten wieder auf eine zurückgeht.

    Ich würde dir folgenden Ansatz empfehlen:

    Betreuer     Kunden        Provision
    ---------    ----------    ---------
    ID           ID            ID
    Name         Betruer ID    Kunden ID
                 Name          Betreuer ID
                 Adresse       Provision (%, €, ...)
                               Vertrag Nr.

    Dieser Ansatz müsste Funktionieren.
    Bei einer Datenbank sollte man alle Werte, die man in eine Eigene Tabelle schreiben kann auch in eine Schreiben. Dadurch vermeidet man viele Probleme.

    Danach sollte dieses Problem mit deinem Programm auch funktionieren.
    Bei den Datenbank-Programmen ist es aber wichtiger, dass du die Logik programmieren kannst.

    mfg Manfred

  2. Die Tabelle "kunde" hat 2 Spalten die sich jeweils 1:n auf die Tabelle "usr" beziehen.

    Beziehungen finden zwischen Tabellen und den dahinter stehenden realen Objekten statt. Das von Dir gewschilderte Szenario deutet auf:

    • den Einsatz eines kombinierten Fremdschlüssels hin
    • (alternativ) auf Murks im Datendesign hin

    Frag bitte ruhig noch einmal nach, wenn irgendwas unklar.

  3. Hallo sabse !

    ---

    Lass bitte erst 'mal klaeren, ob ich das richtig verstanden habe :

    "usr"               "kunde"

    • id                + id
    • stammdaten_id---- + firma

    Dieser Link meint nicht das Feld "firma", oder ?
    Sondern diese beiden
       |                + usr_id_betreuer
       |                + usr_id_kdzg
    sind die Fremdschluessel, richtig ?

    Die Tabelle "kunde" hat 2 Spalten die sich jeweils 1:n auf die Tabelle "usr" beziehen.

    Aus deinem erlaeuternden Text und aus der Feldbenennung les ich n:1, also 1 Betreuer(in usr) hat n Kunden und
    ein User/"kdzg" hat auch n Kunden.

    War das so gemeint ?

    Wenn das so ist, find ich den DB-Entwurf an der Stelle
    o.k.

    ---

    uu DB Designer

    Der erstellt mir nämlich nur "usr_id" wenn ich eine Beziehung erstellen möchte Und umbenennen kann ich das dann auch nicht.

    Um das FK-Feld umzubenennen kann man auf die Seite
    der Link-Linie klicken die der "n"-Kardinalitaet
    entspricht.
    In der Mitte steht der Name des Dialogs steht
    der Name des FK-Feldes.

    Hab das mal gemacht (mit DBD 4.0.5.4 Beta)
    und krieg sowas in der exportierten DDL Datei

    [...]
    CREATE TABLE kunde (
      id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
      usr_id_kdzg INTEGER UNSIGNED NOT NULL,
      usr_id_betreuer INTEGER UNSIGNED NOT NULL,
      PRIMARY KEY(id),
      INDEX kunde_FKIndex1(usr_id_betreuer),
      INDEX kunde_FKIndex2(usr_id_kdzg),
      FOREIGN KEY(usr_id_betreuer)
        REFERENCES usr(id)
          ON DELETE NO ACTION
          ON UPDATE NO ACTION,
      FOREIGN KEY(usr_id_kdzg)
        REFERENCES usr(id)
          ON DELETE NO ACTION
          ON UPDATE NO ACTION
    );
    [...]

    War es das was Du wolltest ?

    Macht es sinn auf beide einen Index zu legen?

    EINFACH, (nicht-UNIQUE)

    Ein Index macht i.A. INSERT langsamer aber
    SELECT schneller.
    Die betroffenen Tabellen scheinen Stammdaten zu
    beinhalten - also i.A von mehr Lese- als
    Schreiboperationen betroffen zu sein.
    => Index waere vielleicht sinnvoll, gerade da es sich
    um FK handelt.

    UNIQUE

    Das wuede die Realationen jeweils zu 1:1 veraendern.
    Dann sollte vielleicht das Design insgesamt neu
    ueberdacht werden.

    1. Macht es sinn auf beide einen Index zu legen?
      EINFACH, (nicht-UNIQUE)
      =======================
      Ein Index macht i.A. INSERT langsamer aber
      SELECT schneller.
      Die betroffenen Tabellen scheinen Stammdaten zu
      beinhalten - also i.A von mehr Lese- als
      Schreiboperationen betroffen zu sein.
      => Index waere vielleicht sinnvoll, gerade da es sich
      um FK handelt.

      Du hast sabse wesentlich besser verstanden als die anderen.   :)

      Das mit dem Index in der Tabelle 'kunde' auf 'usr_id_betreuer' und
      'usr_id_kdzg' habe ich aber nicht verstanden, wie meinst Du das? 'id' dürfte doch wohl der Primärschlüssel auf 'usr' sein und wenn nicht in 'kunde' gezielt nach 'usr_id_betreuer' oder 'usr_id_kdzg' gesucht wird, dann macht ein Index doch keinen Sinn?!

      1. Hallo !

        Das mit dem Index in der Tabelle 'kunde' auf 'usr_id_betreuer' und
        'usr_id_kdzg' habe ich aber nicht verstanden, wie meinst Du das? 'id' dürfte doch wohl der Primärschlüssel auf 'usr' sein und wenn nicht in 'kunde' gezielt nach 'usr_id_betreuer' oder 'usr_id_kdzg' gesucht wird, dann macht ein Index doch keinen Sinn?!

        Oh ja, das hab ich schlecht formuliert...
        Ich meinte JEWEILS einen Index auf die FK, damit

        SELECT [..] JOIN ON usr.id=kunde.usr_id_benutzer

        und

        SELECT [..] JOIN ON usr.id=kunde.usr_id_kdzg

        schneller werden.Ich vermute, dass diese JOINS oft gebraucht werden. (z.B. fuer die Provisionsabrechung die sabse beschrieben hatte )

        Gruss

        Holger

        1. Ich meinte JEWEILS einen Index auf die FK, damit

          SELECT [..] JOIN ON usr.id=kunde.usr_id_benutzer

          und

          SELECT [..] JOIN ON usr.id=kunde.usr_id_kdzg

          schneller werden.Ich vermute, dass diese JOINS oft gebraucht werden. (z.B. fuer die Provisionsabrechung die sabse beschrieben hatte )

          Ach so, es geht Dir natürlich nicht um das Suchen ("WHERE"), sondern um das JOINen, das in der Tat häufig vorkommen dürfte. - Da stand ich wohl auf dem Schlauch.

          Aber dennoch, noch einmal die Frage: Macht ein Index auf ein Datenfeld Sinn, wenn dieses ein Fremdschlüssel ist und auf einen Primärschlüssel (einer zweiten Tabelle) verweist, und wenn über dieses ganz primär nur GeJOINt (nicht geWHEREt ;) wird? Ist mir irgendwie völlig unklar, wie das den SELECT (inl. JOIN) optimieren soll.

          Ilja??   ;)

          1. Hallo Hamstar!

            Aber dennoch, noch einmal die Frage: Macht ein Index auf ein Datenfeld Sinn, wenn dieses ein Fremdschlüssel ist und auf einen Primärschlüssel (einer zweiten Tabelle) verweist, und wenn über dieses ganz primär nur GeJOINt (nicht geWHEREt ;) wird? Ist mir irgendwie völlig unklar, wie das den SELECT (inl. JOIN) optimieren soll.

            Bei 'nem einfachen JOIN ( "ueber alles" ) bringt's wahrscheinlich nichts, aber bei

            SELECT u.foo, k.bar
                   FROM usr u
                        JOIN kunde k ON u.id = k.usr_id_kdzg
            -- Jetzt kommt's :-)
                             WHERE u.foo = 'schnurrdiburr';

            Wenn auf u.foo ein Index liegt zeigt mir EXPLAIN dass zumindest MySQL von k uber den Index laeuft und erst dann nach k joined.

            Ohne den Index macht "er" es anscheinend umgekehrt, was mir suboptimal erscheint - indem WHERE ist ja gar kein Feld von k enthalten.

            Gruss

            Holger

            P.S.: Schreibst Du das FROM mit in die erste Zeile ?

            1. aehemm...

              suboptimal

              da hab ich Unsinn geschrieben, das macht "er" bei dem (INNER) JOIN schon richtig; "er" grenzt vor der teuren Stringsuche die Ergemnismenge ein, bei LEFT OUTER sucht er andersherum.

              Ist doch doch wohl good practice INNER mit anzugeben..

              Sry

              Holger