string-werte bei der eingabe überprüfen

Hallo zusammen!

Ich habe eine Tabelle für meine DVDs, die so (ähnlich) aussieht:

    movie     |    release    |           actor          |   ...   |
--------------+---------------+--------------------------+---------|
 Equilibrium  |   2003-05-01  | Christian Bale           |   ...   |
 Oceans 12    |   2004-06-01  | Brad Pitt,George Clooney |   ...   |

Die Spalte ‘actor’ ist vom Typ “text”… Nun würde ich gerne sicherstellen, dass bei der Eingabe von Schauspielern
sichergestellt wird, dass nur Werte aus einer Liste zugelassen werden (z.B. bei Schreibfehlern [Clooney / Cloony]),
damit gewährleistet ist, dass ich sie beim suchen (WHERE actor ~* ‘.clooney.’) auch alle finde…

Ich habe das mal mit einem eigenen ‘enum’-Typ versucht, und die Spalte als Array gestaltet, damit mehrere Werte gespeichert
werden können… aber leider können Einträge aus einem ‘enum’ nicht gelöscht werden, und das suchen in einem Array mit regexp
ist auch nicht trivial… jetzt wollte ich also wissen, ob es einen postgres-eigenen Mechanismus gibt, der nur ‘actor’-strings aus
einer Liste (z.B. einer eigenen ‘actors’-Tabelle) zulässt… durch ein Komma getrennt…

PS: Ich weiss, dass der Eine oder Andere jetzt sicherlich die Hände über dem Kopf zusammenschlägt, aber da ich Datenbank-
Anfänger / Hobbyist bin, würde ich die Einfachheit meiner DVD-Tabelle gerne erst mal beibehalten, bevor ich mich noch weiter
mit Normalisierung und komplizierteren ‘join’-queries beschäftige… vor allem vor der manuellen Erstellung der “junction-table”
graut es mir ein wenig… :astonished:

Geht schon so…

Du suchst sowas:

test=*> create table prueftabelle (name text primary key);
CREATE TABLE
test=*> create table dvd (actor text references prueftabelle);
CREATE TABLE
test=*> insert into prueftabelle values ('akretschmer');
INSERT 0 1
test=*> insert into prueftabelle values ('cornfed');
INSERT 0 1
test=*> insert into dvd values ('test');
ERROR:  insert or update on table "dvd" violates foreign key constraint "dvd_actor_fkey"
DETAIL:  Key (actor)=(test) is not present in table "prueftabelle".
test=*> insert into dvd values ('akretschmer');
INSERT 0 1

Das ist aber eigentlich aus ungeschickt, da die Strings nun immer wieder auftauchen. Ist da ein Typo ist das überall zu ändern.

Besser also in der prueftabelle mit einem numerischen Key als primary Key zu arbeiten und diesen als Fremdschlüssel in der dvd-Tabelle zu speichern. Deine Angst vor Join legst Du nun bitte ganz, ganz schnell ab, denn das brauchst immer und immer wieder.

Man sollte sowas gleich von Anfang richtig machen - auch bei einem Hobby-Projekt.

Das Erstellen der “junction” Tabelle ist auch nicht aufwändiger, als die Komma-separierten Einträge in der Tabelle zu speichern.

Du glaubst gar nicht wie oft ich zu hören bekomme “Das wurde am Anfang so (=falsch) gemacht, und das können wir jetzt nicht mehr ändern” und dann werden Foren mit Fragen überhäuft wie man mit dem schlechten Design dann doch noch irgendwie über die Runden kommt. Was oft zu unnötig komplizierten und fehlerhaften “Lösungen” führt.

Und gerade als Anfänger sollte man es möglichst richtig machen. Wenn man viel Erfahrung hat, kann man eventuell verstehen welche Nachteile eine “falsches” Design mit sich bringt und ob es das wirklich wert ist.

Irgendein schlauer Mensch hat mal gesagt: “Wenn etwas wert ist getan zu werden, dann ist es auch wert richtig getan zu werden”.

Absolut richtig. Ich sehe bei unseren Kunden gerade im Bereich Datenbanken so unglaublich viel unglaublich schlecht gemachtes Zeugs, das ist mit Worten gar nicht zu beschreiben.
Und wenn man das anspricht kommt einklich immer: ‘ja, mag sein, aber das können wir jetzt nicht mehr ändern’.

Von daher: mache es gleich richtig. Später ist es zu spät.

Vielen Dank für die schnelle Reaktion!

Stimmt schon, kann man es auch gleich richtig machen (statt aufzuschieben)! Dann nur noch kurz zum Verständnis zwei Anfängerfragen:
1.)
ich erstelle also folgende 3 Tabellen:

  • movie (movie_id [PK], title, release, genre, …)
  • actor (actor_id [PK], name, lastname, …)
  • movie_actor (id [PK], movie_id [FK], actor_id [FK]) – (movie_actor.movie_id [FK] referenz auf movie.movie_id [PK])

und dann die “junction”-table füllen (mit “davor grausen” meine ich hauptsächlich das ständige nachsehen nach den IDs, ist ja doch
etwas abstrakter als die Namen direkt einzugeben… wird wohl einen Samstagnachmittag in Anspruch nehmen :slight_smile: )

2.)
in meiner nicht normalisierten Tabelle konnte ich halt immer schön mit (SELECT title,release FROM movie WHERE actor ~* ‘.clooney.’) nachsehen…
für den Einstieg: wie würde denn eine ‘join’-query z.B. aussehen, mit der ich nach den Filmen schaue, in denen der Herr Clooney mitspielt? Gibt’s auch
empfehlenswerte Links oder Literatur, welche die ‘join’-Thematik (also inner, outer, left, right, …) verständlich erklären? (Englisch kein Problem…)

Danke nochmals!

Da gibt es eine Grafik, die, wie ich finde, das sehr schön grafisch darstellt:

Vielen Dank, Ulti!

Danke für die nützliche Grafik! Alles auf einen Blick… habe mich in der Zwischenzeit auch vermehrt mit z.B. JOINS beschäftigt
und schäme mich so ein bisschen für meinen vorigen Post… :astonished:

Beide Anfänger-Fragen wurden eigentlich schon beantwortet:

  • Frage 1: castorp hat hier schon einmal genau meine erste Frage beantwortet: Zwischentabelle erstellen? m zu n Beziehung
  • Frage 2: mit ein bisschen nachlesen kommt man auch mit JOINS klar…
    (habe halt einfach mal nachgefragt, ohne mich ein bissl’ selbst damit beschäftigt zu haben… ahem…)

Also nochmal vielen Dank für die Antwort, Ulti, und für die sehr nützliche Grafik!!