Wie fügtman bei einem FOREIGN KEY Zyklus ein
Wie fügtman bei einem FOREIGN KEY Zyklus ein
am 12.07.2006 19:48:53 von Markus Malkusch
Hi, ich habe folgende Tabellen:
mysql> show CREATE TABLE problem_category_cost_factor_history\G
*************************** 1. row ***************************
Table: problem_category_cost_factor_history
Create Table: CREATE TABLE `problem_category_cost_factor_history` (
`problem_category_cost_factor_history_id` int(11) NOT NULL auto_increment,
`problem_category_id` int(11) NOT NULL default '0',
`user_id` int(11) NOT NULL default '0',
`cost_factor` double NOT NULL default '0',
`change_time` timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY (`problem_category_cost_factor_history_id`),
KEY `user_id` (`user_id`),
KEY `problem_category_id` (`problem_category_id`),
CONSTRAINT `problem_category_cost_factor_history_ibfk_1` FOREIGN KEY
(`user_id`) REFERENCES `user` (`user_id`),
CONSTRAINT `problem_category_cost_factor_history_ibfk_2` FOREIGN KEY
(`problem_category_id`) REFERENCES `problem_category`
(`problem_category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
mysql> show CREATE TABLE problem_category\G
*************************** 1. row ***************************
Table: problem_category
Create Table: CREATE TABLE `problem_category` (
`problem_category_id` int(11) NOT NULL auto_increment,
`problem_category_name` varchar(32) NOT NULL default '',
`parent_id` int(11) default NULL,
`problem_category_cost_factor_history_id` int(11) NOT NULL default '0',
PRIMARY KEY (`problem_category_id`),
KEY `problem_category_cost_factor_history_id`
(`problem_category_cost_factor_history_id`),
KEY `parent_id` (`parent_id`),
CONSTRAINT `problem_category_ibfk_1` FOREIGN KEY
(`problem_category_cost_factor_history_id`) REFERENCES
`problem_category_cost_factor_history`
(`problem_category_cost_factor_history_id`),
CONSTRAINT `problem_category_ibfk_2` FOREIGN KEY (`parent_id`) REFERENCES
`problem_category` (`problem_category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
D.h. beide Tabellen referenzieren sich gegenseitig. Wie fügt man bei sowas
einen neuen Datensatz ein. Ein Insert bei einer Tabelle scheitert mit
einem "ERROR 1216 (23000): Hinzufgen eines Kind-Datensatzes schlug aufgrund
einer Fremdschlssel-Beschränkung fehl"
--
http://hommingberger-gepardenforelle.malkusch.de/
Re: Wie fügt man bei einem FOREIGN KEY Zyklus ein
am 12.07.2006 20:09:24 von Johannes Vogel
Hi Markus
Markus Malkusch wrote:
> mysql> show CREATE TABLE problem_category_cost_factor_history\G
> mysql> show CREATE TABLE problem_category\G
>
> D.h. beide Tabellen referenzieren sich gegenseitig. Wie fügt man bei sowas
> einen neuen Datensatz ein. Ein Insert bei einer Tabelle scheitert mit
> einem "ERROR 1216 (23000): Hinzufgen eines Kind-Datensatzes schlug aufgrund
> einer Fremdschlssel-Beschränkung fehl"
Immer schön der Reihe nach. Erst den Eintrag der Fremdtabelle, dann
denjenigen, der auf diesen zeigt.
Users Bookings
id <----. id
firstname `-- idUsers
Erst Users-Eintrag, dann Bookings-Eintrag.
Oder hab ich deine Frage falsch verstanden?
HTH, Johannes
Re: Wie fügtman bei einem FOREIGN KEY Zyklus ein
am 12.07.2006 20:22:06 von Andreas Kretschmer
Andreas
--
q: why do so many people take an instant dislike to mysql?
a: it saves time (oicu in #postgresql)
Explaining the concept of referential integrity to a mysql user is like
explaining condoms to a catholic (Shadda in #postgresql)
Re: Wie fügt man bei einem FOREIGN KEY Zyklus ein
am 12.07.2006 21:16:43 von Kai Ruhnau
Andreas Kretschmer wrote:
> begin Markus Malkusch wrote:
>> D.h. beide Tabellen referenzieren sich gegenseitig. Wie fügt man bei sowas
>> einen neuen Datensatz ein. Ein Insert bei einer Tabelle scheitert mit
>> einem "ERROR 1216 (23000): Hinzufgen eines Kind-Datensatzes schlug aufgrund
>> einer Fremdschlssel-Beschränkung fehl"
>
> Der Trick ist, dies 'deferrable' zu definieren:
>
>
> test=# create table t1 (id int primary key);
> NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t1_pkey" for table "t1"
> CREATE TABLE
> test=# create table t2 (id int primary key references t1 initially deferred deferrable);
> NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t2_pkey" for table "t2"
> CREATE TABLE
> test=# alter table t1 add column id2 int references t2 initially deferred deferrable;
> ALTER TABLE
> test=# begin;
> BEGIN
> test=# insert into t2 values (1);
> INSERT 0 1
>
>
> Man sollte nun in dieser Transaktion noch dafür sporgen, daß der Bezug
> in der anderen Richtung auch noch zustande kommt, sonst schlägt COMMIT
> fehl.
>
> Ja, ich weiß, hier ist mysql-Land. Ob das da auch so geht, weiß ich
> nicht. Obiges ist jedenfalls _NICHT_ MySQL.
Leider nein, InnoDB überprüft Foreign Key Constraints immer sofort und
nicht erst beim Commit.
Die etwas unschönere Variante ist (auch wenn es das Datenmodell
eigentlich nicht hergibt) eine von beiden Referenzen als NULL zu
deklarieren und innerhalb der Transaktion dafür zu sorgen, dass nach
derselben niemals ein NULL-Wert im Feld enthalten ist.
Grüße
Kai
--
This signature is left as an exercise for the reader.
Re: Wie fügtman bei einem FOREIGN KEY Zyklus ein
am 12.07.2006 21:42:28 von Markus Malkusch
Kai Ruhnau:
> Leider nein, InnoDB überprüft Foreign Key Constraints immer sofort und
> nicht erst beim Commit.
D.h. also ohne am Schema was zu ändern ist ein Einfügen nie möglich.
--
http://hommingberger-gepardenforelle.malkusch.de/
Re: Wie fügt man bei einem FOREIGN KEY Zyklus ein
am 12.07.2006 22:45:38 von Helmut Chang
Markus Malkusch schrieb:
> Kai Ruhnau:
>
>> Leider nein, InnoDB überprüft Foreign Key Constraints immer sofort und
>> nicht erst beim Commit.
>
> D.h. also ohne am Schema was zu ändern ist ein Einfügen nie möglich.
SET FOREIGN_KEY_CHECKS = 0;
INSERT...;
INSERT...;
SET FOREIGN_KEY_CHECKS = 1;
schon probiert?
gruss, heli
Re: Wie fügtman bei einem FOREIGN KEY Zyklus ein
am 12.07.2006 23:30:30 von Markus Malkusch
Helmut Chang:
> SET FOREIGN_KEY_CHECKS = 0;
> INSERT...;
> INSERT...;
> SET FOREIGN_KEY_CHECKS = 1;
>
> schon probiert?
Danke, das geht.
--
http://hommingberger-gepardenforelle.malkusch.de/
Re: Wie fügt man bei einem FOREIGN KEY Zyklus ein
am 13.07.2006 12:23:43 von Kai Ruhnau
Markus Malkusch wrote:
> Helmut Chang:
>
>> SET FOREIGN_KEY_CHECKS = 0;
>> INSERT...;
>> INSERT...;
>> SET FOREIGN_KEY_CHECKS = 1;
>>
>> schon probiert?
>
> Danke, das geht.
Jein, denn du schaltest so komplett die Constraint-Ãberprüfung ab. Bei
SET FOREIGN_KEY_CHECKS=1 werden nicht mit einem mal wieder alle
überprüft, sondern MySQL (InnoDB) nimmt alles was dazwischen
stattgefunden hat ungeprüft hin.
SET FOREIGN_KEY_CHECKS ist eher etwas für mysqldump um die (gültig
referenzierenden) Tabellen einfach ex- bzw. importierbar zu machen.
GrüÃe
Kai
--
This signature is left as an exercise for the reader.
Re: Wie fügtman bei einem FOREIGN KEY Zyklus ein
am 13.07.2006 12:29:36 von Andreas Kretschmer
Andreas
--
Andreas Kretschmer
Linux - weil ich es mir wert bin!
GnuPG-ID 0x3FFF606C http://wwwkeys.de.pgp.net
Deutsche PostgreSQL User Group: http://pgug.de