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 zur Tabellen-Architektur

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von Michi77, 17 August 2014.

  1. Michi77

    Michi77 Benutzer

    Mahlzeit!

    In Sachen "Normalisierung" hatte ich mal gelernt, dass es Redundanzen zu vermeiden gilt und sich wiederholende Einträge in eine separate Tabelle ausgelagert werdne sollen (mal ganz banal formuliert).

    Nun habe ich immer wieder mal Datenbanken gesehen, in deren Tabellen Einträge "ausgeschrieben" wurden, statt per Foreign-Key auf eine saparate Tabelle zu verweisen. Also z. B. so:

    Name/Vorname/Gruppe
    Meier/Anton/MENSCH
    Rabbit/Roger/ TIER

    statt

    Name/Vorname/Gruppe
    Meier/Anton/1
    Rabbit/Roger/2

    ... mit einer separaten Tabelle "Gruppen" und dem entsprechenden Primary-Key.

    Was hat es damit auf sich und welche Variante ist zu empfehlen?

    Danke und viele Grüße!

    Michael
     
  2. akretschmer

    akretschmer Datenbank-Guru

    Faulheit. Unwissen.

    Die richtige.

    Ich denke mal, das hat auch geschichtliche Ursachen. MySQL konnte in früheren Versionen keine referentiellen Integritätschecks. Also das ganze Konzept von Fremdschlüsseln gab es nicht, in MyISAM. Und das wurde damals sogar noch als Vorteil dagestellt, bzw. daß man RI ja auch in der Applikation nachbilden könne.

    Mittlerweile kann MySQL ja zumindest das. Check-Constraints oder gar (ich geb zu, das ist kompliziert) Exclusion Constraints, kann MySQL ja nach wie vor nicht. Ist halt nach wie vor eine doch stark beschränkte Datenbank bzw. der Versuch, eine DB zu sein.
     
  3. Walter

    Walter Administrator Mitarbeiter

    Nicht jeder Programmierer der eine Datenbank erstellt hat auch Ahnung vom richtigen Design einer Datenbank :)
     
    Zuletzt bearbeitet: 18 August 2014
  4. Hony%

    Hony% Datenbank-Guru

    Hi Michael.

    Das kommt streng genommen auf die Art des Attributes an, da durch die Normalisierung Anomalien verhindern werden sollen. Da es sich in deinem Beispiel um wohl um eine Art "Flag" handelt macht es kaum einen Unterschied. Im Fall von MySQL dürfte Variante 1 mit ENUM-Feld sogar platzsparender sein.

    Gruß
    Hony
     
  5. ukulele

    ukulele Datenbank-Guru

    Variante 1 könnte
    - schneller sein
    - leichter abzufragen
    - mehr Platz verbrauchen
    - Alles davon
    - Nichts davon
    - Teile davon

    Je nach Länge des Feldes, Anzahl der vorkommenden Varianten. Der Normalform entspricht es nicht, es verursacht Redundanz genau wie eine Tabelle PLZ / Ort. Deswegen ist so eine Tabelle aber nicht zwigend "schlecht" designt.
     
  6. Michi77

    Michi77 Benutzer

    Wow - vielen Dank an alle für die schnellen und kompetenten Antworten!

    Ich hab mir bisher gedacht, dass damit Abfragen einfach auch leichter zu lesen sind, da man statt Keys in Form von Zahlen den "Sinn" dahinter mehr oder weniger ausschreibt. In einem kürzlich gesehenen Beispiel war es konkret so eingesetzt, dass darüber die Gruppenzugehörigkeit von Usern bestimmt wurde. Das Ganze war in einem kommagetrennten String im Feld gespeichert, also z. B.

    Gruppe
    user,admin,team2

    Ich hätte das wohl eher über Fremdschlüssel und dem Ergebnis

    Gruppe
    2,4,12

    gelöst.
     
  7. akretschmer

    akretschmer Datenbank-Guru

    Beides ist falsch. Stichwort Normalisierung.
     
  8. ukulele

    ukulele Datenbank-Guru

    Stimmt, Komma-getrennte Multi-Wert Felder sind DB technisch gruselig. Referenzen auf andere Tabellen in solchen Feldern zu platzieren ist vermutlich nicht mehr zu unterbieten. Am Ende sieht man dann aber doch wieder derartige "Code"-Feldner im gängigen CMS deiner Qual.
     
  9. Michi77

    Michi77 Benutzer

    Genau das!!

    Die aktuelle Version des CMS TYPO3 verwaltet seine User über solche Felder bezüglich der Gruppenzugehörigkeit :D

    Ich muss dann immer alles über FIND_IN_SET herausfiltern, was recht langsam sein dürfte...

    Richtig wäre dann Auslagerung in eine dritte Tabelle, oder?

    User (user_id, name)
    Gruppen (gruppen_id, gruppe)
    Gruppenzugehörigkeiten (user_id, gruppen_id)

    Viele Grüße!

    Michael
     
  10. ukulele

    ukulele Datenbank-Guru

    Dein CMS wird vermutlich nur "Gruppe 2,4,12" in der Tabelle ablegen und die Zuordnung Gruppen ID <-> Gruppenname irgendwie komplett selbst verwalten. Die DB dient also mehr als Speicher für Text, interpretieren tut es das CMS. Würde die DB diese Gruppen wirklich selbst relational abbilden wäre eine Zwischentabelle erforderlich.
     
  11. Michi77

    Michi77 Benutzer

    OK, machen wir es doch mal konkret!

    Ich will unser Intranet (basierend auf besagtem TYPO3) neu aufsetzen und stehe dabei vor der folgenden Herausforderung:

    Einem User (Tabelle fe_user) sollen Zugriffsrechte auf bestimmte Datensätze zugeordnet werden, die sich nach seiner Hierarchie in seinem Betrieb richten. Es gibt User, die sollen nur Datensätze aus ihrer Abteilung sehen und es gibt User, die alle Datensätze für den gesamten Kunden sehen dürfen.

    Welchen Bezug zum User schaffe ich jetzt hier am besten, damit ich bei Usern mit weiten Zugriffsrechten nicht tonnenweise Teilbereiche zuordnen muss?

    Beispiele:

    • User Meier darf nur auf die Datensätze zu Filiale 3, Filiale 9 und Filiale 67 zugreifen
    • User Schmidt darf auf alle Filialen des Kunden zugreifen
    Bisher habe ich das mit diesem beknackten FIND_IN_SET und endlosen CSVs gelöst, was die Abfragen ziemlich langsam gemacht hat. Kann ich das intelligenter lösen? Vielleicht mit einer Hierarchie in den Kunden-Entitäten?

    Danke für jeden Tipp!

    LG

    Michael
     
  12. akretschmer

    akretschmer Datenbank-Guru

    Das ist nicht gerade trivial. Die sauberste Lösung dafür wären, daß Du die User so als DB-User anlegst. Dazu, daß diese User so erst einmal GAR KEINEN Zugriff auf die Tabellen haben, sondern nur über Funktionen. Innerhalb dieser prüfst Du die Zugriffsrechte.

    Das ist aber a) nicht mal eben so realisierbar und b) wohl eher nicht unter der Haube eines anderen CMS, welches wohl weiter laufen soll. Ich hab sowas mal gesehen, bei Zalando. Aber, wie gesagt, da steckt 'ne Menge Arbeit dahinter, wenn es funktionieren soll.

    Du kannst Dir aber das mal durchlesen:


    sowie http://www.postgresql.org/docs/9.3/static/sql-createfunction.html und dort auf SECURITY DEFINER und andere Angaben zur Sicherheit achten.
     
  13. Michi77

    Michi77 Benutzer

    Danke schonmal, akretschmer!

    Meiner Einschätzung nach hätte ich wohl folgende Möglichkeiten
    • fe_users.zugriff_filialebene und fe_users.zugriff_kundenebene, wobei in diesen Feldern dann die Fremdschlüssel der Kunden/Filialen aufgelistet sind --> Werden dann halt wieder endlose CSVs und ich muss bei der Abfrage der Zugriffsrechte gleich zwei Felder berücksichtigen. Vorteil: Mit einem Verweis unter fe_users.zugriff_kundenebene hat der User Zugriff auf den gesamten Kunden, mühsames Zusammenklicken einzelner Filialen entfällt
    • Ich führe Hierarchien ein, indem aus Kunden und Filialen einfach "Bereiche" werden, die aufeinander aufbauen können (auch Kunden sind dann Bereiche, die als Untereinheiten Filialen haben) --> Könnte Abfragen schon recht kompliziert machen
    • Es gibt effektiv keine Kunden, sondern Benutzerrechte werden immer nur auf kleinster Ebene, also auf Filialebene erteilt --> Gibt ne mords Klickerei aber ist wohl das Sauberste
     
  14. Michi77

    Michi77 Benutzer

    Nochmal ne eher allgemeine Frage: Empfiehlt es sich, die "verbindende Tabelle" ebenfalls mit einem Primärschlüssel auszustatten?

    Also im obigen Beispiel die Tabelle, die z. B. Benutzer und deren Gruppen kombiniert.

    Vielen Dank!
     
  15. akretschmer

    akretschmer Datenbank-Guru

    Du kannst einen PK über die 2 Spalten legen.
     
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