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

Anfängerfrage zu Datenkonsistenz: Constraint, Trigger oder ganz anders?

Dieses Thema im Forum "Datenmodellierung, Datenbank-Design" wurde erstellt von fraow, 16 September 2013.

  1. fraow

    fraow Neuer Benutzer

    Liebe Leute,

    ich habe, vereinfacht gesprochen, drei Tabellen:
    • nutzer (PK: id_nutzer)
    • einkaeufer (PK: id_einkaeufer, FK: id_nutzer)
    • lose (PK: id_los, FK: id_nutzer, id_einkaeufer)
    Ein Nutzer kann mehrere Einkäufer anlegen, die haben dann seine Nutzer-ID. Ein Einkaeufer kann auch id_nutzer = NULL haben und ist dann für alle Nutzer verwendbar.

    Wenn ein Los angelegt wird, soll sichergestellt werden, dass id_nutzer und id_einkaeufer auch als Wertepaar zusammen in der Einkäufer-Tabelle vorkommen. Ich weiß, dass der id_nutzer-Fremdschlüssel in der Lose-Tabelle hinderlich ist, aber da die Nutzer-ID in der Einkäufer-Tabelle NULL werden kann, könnte man den Besitzer des Los-Datensatzes gar nicht mehr feststellen. In der Lose-Tabelle kann id_nutzer logischerweise auch = NULL sein.

    Wie stelle ich am einfachsten sicher, dass in Lose nur ein gültiges Wertepaar aus id_einkaeufer und id_nutzer steht? Oder ist das so dumm, dass ich die Nutzer-ID auf jeden Fall aus lose rausnehmen sollte?
     
    Zuletzt bearbeitet: 16 September 2013
  2. akretschmer

    akretschmer Datenbank-Guru

    So?

    Code:
    test=# create table nutzer (id_nutzer int primary key);NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "nutzer_pkey" for table "nutzer"
    CREATE TABLE
    Time: 7,425 ms
    test=*# create table einkaeufer (id_einkaeufer int, id_nutzer int references nutzer, primary key(id_einkaeufer, id_nutzer));NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "einkaeufer_pkey" for table "einkaeufer"
    CREATE TABLE
    Time: 4,983 ms
    test=*# create table lose (id_los int primary key, id_nutzer int, id_einkaeufer int, foreign key(id_nutzer, id_einkaeufer) references einkaeufer);
    NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "lose_pkey" for table "lose"
    CREATE TABLE
    Time: 3,244 ms
    
    
    Andreas
     
  3. fraow

    fraow Neuer Benutzer

    Hallo Andreas,

    vielen Dank für deine Antwort. Da aber id_nutzer NULL sein kann, bekomme ich als Antwort, wenn ich den Fremdschlüssel erstellen will "Foreign Key is incorrectly formed".
    Mir ist noch was aufgefallen, was die Sache irgendwie schwieriger macht. Die Nutzer-ID bestimmt sozusagen immer den Ersteller und Nutzer des Datensatzes (bei Los wie bei Einkäufer). Ein Admin kann in beiden Tabellen einen Eintrag mit Nutzer-ID = NULL erstellen. Dann können andere Nutzer diesen Eintrag sozusagen als "Standardeintrag" nutzen (-> Standardlos oder Standardeinkäufer). Wenn jetzt z.B. ein normaler Nutzer ein Los erstellt, dass auf einen Standardeinkäufer verweist, muss als Nutzer-ID trotzdem seine ID im Los-Datensatz eingetragen sein und nicht NULL. Es muss dabei nur sichergestellt werden, dass die Einkäufer-ID auf einen seiner eigenen oder einen Standardeinkäufer verweist. Wenn der Admin ein Standardlos mit Nutzer-ID = NULL erstellt, so dürfen nur Standardeinkäufer genutzt werden. Das sind eigentlich die Einschränkungen. Ich versuch's noch mal zusammenzufassen..

    Tabelle Los
    - Nutzer-ID = NULL -> Einkäufer-ID darf nur von einem Standardeinkäufer mit Nutzer-ID ebenfalls = NULL kommen
    - Nutzer-ID != NULL -> Einkäufer-ID darf von einem Standardeinkäufer mit Nutzer-ID = NULL oder von einem Einkäufer des Nutzers mit der selben Nutzer-ID kommen

    Geht das immer noch mit Fremdschlüsseln? Kann ich da so eine Check-Constraint einbauen? Hab so viel gegoogelt gestern, aber werde einfach nicht schlauer. Die Syntax macht mir auch zu schaffen, ständig so kleine, kryptische Fehlermeldungen, die ich nicht deuten kann :( nutze übrigens MariaDB.
     
  4. akretschmer

    akretschmer Datenbank-Guru

    Wieso kann die NULL sein?

    Nein. Definiere halt die FK mit NOT NULL.

    Andreas
     
  5. fraow

    fraow Neuer Benutzer

    Wenn ich dann meinetwegen, um Standardeinkäufer und -lose zu erstellen, die Nutzer-ID auf "0" und nicht NULL setze (und dazu eben so eine Art "Standardnutzer" mit 0 als ID anlege), bliebe das Problem:

    Admin legt Standardeinkäufer an -> Nutzer-ID: 0, Einkäufer-ID: XX
    Normaler Nutzer mit ID YY legt Los mit Standardeinkäufer an -> Nutzer-ID: YY, Einkäufer-ID: XX

    Dann stimmt ja das Fremdschlüsselpaar nicht mehr. Ist aber so trotzdem richtig. Der Nutzer darf ja den Standardeinkäufer nutzen für seine Einträge.
     
  6. akretschmer

    akretschmer Datenbank-Guru

    Ja, und? Du kannst auch 99 oder 4711 als 'Standardnutzer' anlegen, die Interpretation ist nicht Aufgabe der DB.
     
  7. fraow

    fraow Neuer Benutzer

    Meinst du damit also, dass es, wenn ich eine Datenkonsistenz dieser Art gewährleisten möchte, Aufgabe des Clients sein muss?
     
  8. akretschmer

    akretschmer Datenbank-Guru

    Die Daten sind ja erst einmal konsistent. Du kannst natürlich mit der DB noch mmehr machen, z.B. daß jeder User nur seine eigene nutzer_id verwenden darf etc. Da geht vieles.
     
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