Datenbankdesign ENUM, SET
am 07.11.2007 15:07:31 von steffen horstHallo,
ich hatte bis vor einigen Tagen eine Tabelle mit drei Feldern: INT,
ENUM und SET, also z.B.:
id INT
fragesteller ENUM (person_A1, person_A2, person_A3)
antwortende SET (person_A1, person_A2, person_A3)
Da es mehrere solcher Personengruppen (Gruppe_A: person_A1, person_A2,
person_A3; Gruppe_B: person_B1, person_B2, ...) gab, hab ich für jede
eine solche Tabelle angelegt, also z.B.:
TABLE gruppe_A
id INT
fragesteller ENUM (person_A1, person_A2, person_A3)
antwortende SET (person_A1, person_A2, person_A3)
TABLE gruppe_B
id INT
fragesteller ENUM (person_B1, person_B2, person_B3)
antwortende SET (person_B1, person_B2, person_B3)
Die Anfrage für alle Einträge war einfach:
SELECT id, fragesteller, antwortende
FROM gruppe_A
Nun möchte ich nicht ständig neue Tabellen für neue Gruppen anlegen,
sondern alle Einträge in einer Tabelle ablegen. Das ist offensichtlich
zunächst unmöglich, da ich nicht alle Personen in SET und ENUM
aufnehmen kann. Das heißt, ich benötige schon vier Tabellen:
TABLE frage
id INT
fragesteller_id INT
gruppe_id INT // da alle Fragen nun in eine Tabelle kommen
TABLE antwort
frage_id INT
person_id INT
TABLE person
id INT
name VARCHAR
TABLE gruppe
id INT
name VARCHAR
Nun kann ich also über gruppe_id die Fragen den Gruppen zuordnen und
über frage_id die Antworten den Fragen.
Die vorher so leichte Anfrage
SELECT id, fragesteller, antwortede
FROM tabelle1
ist nun überaus aufwändig! Jetzt benötige ich zunächst alle Fragen
einer Gruppe, also etwa so:
SELECT id, name
FROM frage, person
WHERE gruppe_id = 0
AND fragesteller_id = person.id
Und dann muss ich zu jedem dieser Anfrageergebnisse (mit $i = id) eine
weitere Anfrage ausführen:
SELECT name
FROM antwort, person
WHERE frage_id = $i
AND antwort.person_id = person.id
Das heißt, was vorher eine Anfrage war, sind nun (1+n) Anfragen (mit n
als Anzahl der Fragen einer Gruppe).
Gibt es nicht ein besseres Design als dieses??
Eine (ebenfalls seltsame) Möglichkeit, die mir spontan einfällt ist
diese:
Angenommen, es gibt nicht mehr als 10 Personen in einer Gruppe. Dann
könnte man das Problem eventuell in etwa so lösen:
TABLE frage
id INT
gruppe_id INT
fragesteller_id INT
antwortende BIT(10)
TABLE person
id INT
mitglieds_nr INT (1-10)
gruppe_id INT
name VARCHAR
TABLE gruppe
id INT
name VARCHAR
SELECT id, name, antwortende
FROM frage, person
WHERE frage.gruppe_id = 0
AND fragesteller_id = person.id
Um die Mitgliedsnamen aufzulösen, benötigt man natürlich dann noch
eine weitere Anfrage. Oder gibts da noch irgendwas SINNVOLLES?
Normalisiert ist nur der aktuelle Stand, aber der erzwingt einen
Haufen mehr Anfragen.
Danke für jegliche Hilfen, steffen