Probleme mit Fremdschlüssel

BaldrianForte

Benutzer
Beiträge
7
Buch: Datenbanksysteme - Eine Einfühung von Alfons Kemper / Andre Eickler
Es wird eine kleine Universitätswelt simuliert: Studenten, Profs, Assistenten, Vorlesungen...

Der folgende Code funktioniert, außer die Tabelle Assistenten.
Dort meldet mysql bzgl der letzten Zeile einen Fehler:
--> ERROR 1005 (HY000): Can't create table 'db.assistenten' (errno: 150)

Weiß jemand, warum es da eine Fehlermeldung gibt?
(Wenn ich den Fremdschlüssel weglasse, geht es)

Code:
CREATE TABLE Studenten
      (MatrNr        INTEGER PRIMARY KEY,
        Name          VARCHAR(30) NOT NULL,
        Semester      INTEGER);

CREATE TABLE Professoren
      (PersNr        INTEGER PRIMARY KEY,
        Name          VARCHAR(30) NOT NULL,
        Rang          CHAR(2) CHECK (Rang in ('C2', 'C3', 'C4')),
        Raum          INTEGER UNIQue);

CREATE TABLE Assistenten
      (PersNr        INTEGER PRIMARY KEY,
        Name          VARCHAR(30) NOT NULL,
        Fachgebiet    VARCHAR(30),
        Boss          INTEGER,
        FOREIGN KEY    (Boss) REFERENCES Professoren);

CREATE TABLE Vorlesungen
      (VorlNr        INTEGER PRIMARY KEY,
        Titel          VARCHAR(30),
        SWS            INTEGER,
        gelesenVon    INTEGER REFERENCES Professoren);

CREATE TABLE hoeren
      (MatrNr        INTEGER REFERENCES Studenten ON DELETE CASCADE,
        VorlNr        INTEGER REFERENCES Vorlesungen ON DELETE CASCADE,
        PRIMARY KEY    (MatrNr, VorlNr));

CREATE TABLE voraussetzen
      (Vorgaenger    INTEGER REFERENCES Vorlesungen ON DELETE CASCADE,
        Nachfolger    INTEGER REFERENCES Vorlesungen ON DELETE CASCADE,
        PRIMARY KEY    (Vorgaenger, Nachfolger));

CREATE TABLE pruefen
      (MatrNr        INTEGER REFERENCES Studenten ON DELETE CASCADE,
        VorlNr        INTEGER REFERENCES Vorlesungen,
        PersNr        INTEGER REFERENCES Professoren,
        Note          NUMERIC(2,1) CHECK (Note between 0.7 and 5.0),
        PRIMARY KEY    (MatrNr, VorlNr));
 
Werbung:
Danke, funktioniert. Der Code war so 1:1 von der CD aus dem Buch entnommen, aber dort anscheinend fehlerhaft.
vg

Du gibts keine Engine an. Welche MySQL-Inkarnation verwendest Du?

Ich frage, weil bis vor kurzem war MyISAM Default-Engine. Dies akzeptiert wohl die Syntax für Fremdschlüssel. Mehr aber auch nicht.

Code:
mysql> create table master(i int primary key);
Query OK, 0 rows affected (0.01 sec)

mysql> create table slave (i int references master);
Query OK, 0 rows affected (0.00 sec)

mysql> insert into slave values (1);
Query OK, 1 row affected (0.00 sec)

Du siehst den Fehler?

Dieser und viele andere Bugs wird ihnen präsentiert von MySQL und MyISAM ;-)


Andreas
 
Buch: Datenbanksysteme - Eine Einfühung von Alfons Kemper / Andre Eickler

Laut Kurzbeschreibung auf Amazon:

"Dieses Buch vermittelt eine systematische und umfassende Einführung in moderne Datenbanksysteme."


Steht da drin, auf welche DB man sich bezieht?

Ich seh grad noch: da werden auch CHECK-Constraints gesetzt. Da MySQL diese zwar von der Syntax her akzeptiert, aber vollständig ignoriert, denke ich mal, MySQL kann da in dem Satz nicht gemeint sein ;-)


Andreas
 
Der Kemper ist eigentlich sowas wie ein Standardwerk, was relationale Datenbanken angeht.
Die Datenbankschemas werden in dem zugehörigen Übungsbuch (zum Lehrbuch) für DB2, Oracle, SQL Server auf der CD bereit gestellt.
Die Schemata sehen aber bei allen drei gleich aus.
Ich bin noch nicht so fit. Arbeite mich gerade in mysql 5.5 ein. (Als Vorbereitung aufs nächste Semester). Deshalb sehe ich den Fehler (noch) nicht. Vorher habe ich ein Bisschen mit postgresql gearbeitet (aber nicht tiefgründig). Mysql ist schon etwas anders. Die Doku jedenfalls, leider, ist nicht so toll. vg
 
Der Kemper ist eigentlich sowas wie ein Standardwerk, was relationale Datenbanken angeht.
Die Datenbankschemas werden in dem zugehörigen Übungsbuch (zum Lehrbuch) für DB2, Oracle, SQL Server auf der CD bereit gestellt.
Die Schemata sehen aber bei allen drei gleich aus.
Ich bin noch nicht so fit. Arbeite mich gerade in mysql 5.5 ein. (Als Vorbereitung aufs nächste Semester). Deshalb sehe ich den Fehler (noch) nicht. Vorher habe ich ein Bisschen mit postgresql gearbeitet (aber nicht tiefgründig). Mysql ist schon etwas anders. Die Doku jedenfalls, leider, ist nicht so toll. vg


Okay. Ich zeig Dir, wie es richtig wäre:

Code:
test=# create table master(i int primary key);
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "master_pkey" for table "master"
CREATE TABLE
Time: 3,726 ms
test=*# create table slave (i int references master);
CREATE TABLE
Time: 1,638 ms
test=*# insert into slave values (1);
ERROR:  insert or update on table "slave" violates foreign key constraint "slave_i_fkey"
DETAIL:  Key (i)=(1) is not present in table "master".
Time: 1,423 ms

Die Befehle (create table, insert) sind exakt gleich, nur die Reaktion ist anders.

Du willst lernen, wie 'richtige' Datenbanken funktionieren, so mit referentieller Integrität, Fremdschlüsseln, CHECK-Constraints und so. Das lernt man besser mit Systemen, die das auch unterstützen.

Weiteres 'finde den Fehler' - Beispiel:

MySQL:
Code:
mysql> create table foo (i int check(i < 10));
Query OK, 0 rows affected (0.00 sec)

mysql> insert into foo values (11);
Query OK, 1 row affected (0.00 sec)

PostgreSQL:
Code:
test=*# create table foo (i int check(i < 10));
CREATE TABLE
Time: 2,202 ms
test=*# insert into foo values(11);
ERROR:  new row for relation "foo" violates check constraint "foo_i_check"
DETAIL:  Failing row contains (11).
Time: 0,459 ms

Frage: welchen Wert hat eine DB, die die Syntax zwar 'schluckt', aber vollständig ignoriert? Meiner Meinung nach ist MySQL als Lernsystem vollständig ungeeignet. Und auch als Produktivsystem. Es ist eigentlich für ALLE Anwendungen ungeeignet, außer als Negativbeispiel.


Andreas
 
Mh, was Du erklären willst, verstehe ich.
Im DB-Praktikum (in dem ich vorab war) gab es bei PostgreSQL Probleme mit Funktionen.
(Wir sollten ein php-web-postgresql-Raumverwaltungssystem erstellen)
(Es zeigten sich einige Probleme, weshalb postgresql zukünftig wohl nicht mehr verwendet werden wird)
Dennoch, Du kennst auch mysql. Was schlägst Du persönlich vor?
Ich habe mich für mysql entschieden, weil ich hoffte, da beim besseren DBMS zu sein.
 
Mh, was Du erklären willst, verstehe ich.
Im DB-Praktikum (in dem ich vorab war) gab es bei PostgreSQL Probleme mit Funktionen.
(Wir sollten ein php-web-postgresql-Raumverwaltungssystem erstellen)
(Es zeigten sich einige Probleme, weshalb postgresql zukünftig wohl nicht mehr verwendet werden wird)
Dennoch, Du kennst auch mysql. Was schlägst Du persönlich vor?
Ich habe mich für mysql entschieden, weil ich hoffte, da beim besseren DBMS zu sein.


Was ich von MySQL halte hab ich, denke ich, schon deutlich gemacht. Dieser Thread, letzter Beitrag von mir, letzter Satz.

Mich würde interessieren, welche Probleme Du mit PostgreSQL hattest. Könntest Du dazu im PG-Unterforum einen neuen Thread starten? Ich denke, da vielleicht helfen zu können...


Andreas
 
Also im Vergleich würde ich auch Postgres vorziehen, aber ich will nicht abstreiten das auch MySQL, wenn man die Eigenheiten kennt, genutzt werden kann. Ich würde nur lieber bei Postgres nach Problemlösungen suchen als bei MySQL ;)
 
Es war eine reine sql-Datei. postgresql läßt keine Funktionen zu (irgendwo gabs da Probleme, die bei Mysql nicht bestehen). Unser Team hat sich da sehr gewundert, weil es Arbeit erschwerte. Was es genau war, kann ich leider nicht sagen, weil ich es vor nem halben Jahr nicht verstand und auch heute noch nicht soweit bin. Für mich aber war klar, dass ich mich deshalb von postgresql (bis ich sql halbwegs kann) distanziere. Wenn jemanden aus der alten Gruppe erwische, frage ich noch Mal nach und geb Dir Bescheid. vg
 
Es war eine reine sql-Datei. postgresql läßt keine Funktionen zu (irgendwo gabs da Probleme, die bei Mysql nicht bestehen).


Ähm, just for Info: Du kannst in PostgreSQL sehr wohl Funktionen definieren, das sogar in verschiedenen Programmiersprachen. Von pl/pgsql angefangen (ähnlich zu Oraggle) weiter über C, PL/Perl, Pl/Phyton, Pl/Tcl, Pl/Sh, Pl/lolcode, Pl/v8, ... das geht sogar 'inline' innerhalb von SQL, ohne daß man eine Funktion erst definieren muß - mittels DO - Statement.

Du kannst in PG z.B. auch Indexe auf das Resultat von Funktionen anlegen - sog. funktionale Indexe. Wenn Du also z.B. in Deiner Tabelle 5 Spalten hast, daraus etwas berechnest, und im WHERE diese Berechnung als Bedingung hast, so kannst Du einen Index auf diese Funktion setzen.

Ich behaupte einfach mal, daß PG da um Größenordnungen leistungsfähiger als MySQL ist.


Andreas
 
Werbung:
Was ich sagte, war nicht ganz richtig.
Ein Bekannter schreibt gerade (Zitat)
"soweit ich mich erinnere, hatten wir festgestellt, dass es bei postgre keine stored procedures gibt. Unsere Lösung war, dass wir einfach die normalen "functions" verwendet hatten. Diese erfüllen den gleichen Zweck."
vg
 
Zurück
Oben