Unix Technical Forum

foreign key problem

This is a discussion on foreign key problem within the MySQL forums, part of the Database Server Software category; --> I am not sure how to set up the foreign keys on this one, as I've never done foreign ...


Go Back   Unix Technical Forum > Database Server Software > MySQL

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 02-28-2008, 07:17 AM
Jim Michaels
 
Posts: n/a
Default foreign key problem

I am not sure how to set up the foreign keys on this one, as I've never done
foreign keys before (and I'm sure it shows). I have a tree of information.
I can insert into the categories table, but not anything else - I get
foreign key errors (and I am not sure how to interpret the error).
Cannot add or update a child row: a foreign key constraint fails
(`db0/subcategories`, CONSTRAINT `subcategories_ibfk_2` FOREIGN KEY
(`subcat_id`) REFERENCES `subcategories` (`cat_id`) ON DELETE CASCADE)


I am also curious if the foreign key definition in subcategories would cause
the database to fail or error on a delete because of the recursion. (that's
where the tree is stored).


CREATE TABLE `categories` (
`cat_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
`category` VARCHAR(100) NOT NULL DEFAULT '' COMMENT 'your category here',
PRIMARY KEY(`cat_id`),
UNIQUE KEY `ix_ccat_id` (`cat_id`),
INDEX `ix_ccat`(`category`)
) ENGINE=InnoDB;

CREATE TABLE `subcategories` (
`sub_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ignore',
`cat_id` INTEGER UNSIGNED NOT NULL DEFAULT 0 COMMENT 'copy of cat_id from
categories table',
`subcat_id` INTEGER UNSIGNED NOT NULL DEFAULT 0 COMMENT 'cat_id of
subcategory',
FOREIGN KEY (`cat_id`) REFERENCES `categories`(`cat_id`) ON DELETE
CASCADE,
FOREIGN KEY (`subcat_id`) REFERENCES `subcategories`(`cat_id`) ON DELETE
CASCADE,
PRIMARY KEY(`sub_id`),
INDEX `ix_sccat_id`(`cat_id`),
INDEX `ix_scsubcat_id`(`subcat_id`)
) ENGINE=InnoDB;

CREATE TABLE `categoryroots` (
`root_id` int(10) unsigned NOT NULL auto_increment COMMENT 'ignore',
`cat_id` int(10) unsigned NOT NULL default '0' COMMENT 'copy of cat_id
from categories table',
PRIMARY KEY (`root_id`),
FOREIGN KEY (`cat_id`) REFERENCES `subcategories`(`cat_id`) ON DELETE
CASCADE,
UNIQUE KEY `ix_crcat_id` (`cat_id`)
) ENGINE=InnoDB;

/*
c
f-b
g |
h |
i-c-a
j |
k |
l-d
m
----n
*/
INSERT INTO categories(cat_id,category) VALUES
(1,'a'),
(2,'b'),
(3,'c'),
(4,'d'),
(5,'e'),
(6,'f'),
(7,'g'),
(8,'h'),
(9,'i'),
(10,'j'),
(11,'k'),
(12,'l'),
(13,'m'),
(14,'n');

INSERT INTO categoryroots(cat_id) VALUES
(1),
(14);

INSERT INTO subcategories(cat_id,subcat_id) VALUES
(1,2),
(1,3),
(1,4),
(2,5),
(2,6),
(2,7),
(3,8),
(3,9),
(3,10),
(4,11),
(4,12),
(4,13);




Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 02-28-2008, 07:17 AM
Jerry Stuckle
 
Posts: n/a
Default Re: foreign key problem

Jim Michaels wrote:
> I am not sure how to set up the foreign keys on this one, as I've never done
> foreign keys before (and I'm sure it shows). I have a tree of information.
> I can insert into the categories table, but not anything else - I get
> foreign key errors (and I am not sure how to interpret the error).
> Cannot add or update a child row: a foreign key constraint fails
> (`db0/subcategories`, CONSTRAINT `subcategories_ibfk_2` FOREIGN KEY
> (`subcat_id`) REFERENCES `subcategories` (`cat_id`) ON DELETE CASCADE)
>
>
> I am also curious if the foreign key definition in subcategories would cause
> the database to fail or error on a delete because of the recursion. (that's
> where the tree is stored).
>
>
> CREATE TABLE `categories` (
> `cat_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
> `category` VARCHAR(100) NOT NULL DEFAULT '' COMMENT 'your category here',
> PRIMARY KEY(`cat_id`),
> UNIQUE KEY `ix_ccat_id` (`cat_id`),
> INDEX `ix_ccat`(`category`)
> ) ENGINE=InnoDB;
>
> CREATE TABLE `subcategories` (
> `sub_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ignore',
> `cat_id` INTEGER UNSIGNED NOT NULL DEFAULT 0 COMMENT 'copy of cat_id from
> categories table',
> `subcat_id` INTEGER UNSIGNED NOT NULL DEFAULT 0 COMMENT 'cat_id of
> subcategory',
> FOREIGN KEY (`cat_id`) REFERENCES `categories`(`cat_id`) ON DELETE
> CASCADE,
> FOREIGN KEY (`subcat_id`) REFERENCES `subcategories`(`cat_id`) ON DELETE
> CASCADE,
> PRIMARY KEY(`sub_id`),
> INDEX `ix_sccat_id`(`cat_id`),
> INDEX `ix_scsubcat_id`(`subcat_id`)
> ) ENGINE=InnoDB;
>
> CREATE TABLE `categoryroots` (
> `root_id` int(10) unsigned NOT NULL auto_increment COMMENT 'ignore',
> `cat_id` int(10) unsigned NOT NULL default '0' COMMENT 'copy of cat_id
> from categories table',
> PRIMARY KEY (`root_id`),
> FOREIGN KEY (`cat_id`) REFERENCES `subcategories`(`cat_id`) ON DELETE
> CASCADE,
> UNIQUE KEY `ix_crcat_id` (`cat_id`)
> ) ENGINE=InnoDB;
>


(data snipped)

Jim,

Your problem is right here:

FOREIGN KEY (`subcat_id`) REFERENCES `subcategories`(`cat_id`) ON
DELETE CASCADE,

Generally you don't use a foreign key to reference the same table. If I
understand what you're trying to do, referencing categories should be
sufficient.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex@attglobal.net
==================
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3 (permalink)  
Old 02-28-2008, 07:17 AM
Bill Karwin
 
Posts: n/a
Default Re: foreign key problem

"Jim Michaels" <jmichae3@yahoo.com> wrote in message
news:5rOdnSBK5PrqbkrenZ2dnUVZ_sydnZ2d@comcast.com. ..
> Cannot add or update a child row: a foreign key constraint fails
> (`db0/subcategories`, CONSTRAINT `subcategories_ibfk_2` FOREIGN KEY
> (`subcat_id`) REFERENCES `subcategories` (`cat_id`) ON DELETE CASCADE)


You can't add to a table a reference to the same table if the table hasn't
been created yet.
This is true if the SQL interpreter is just parsing the CREATE TABLE
statement.

To make self-referencing foreign keys, you have to create the table without
that foreign key constraint (but do create the field to be used as the
reference), then use ALTER TABLE to add the constraint.

For example:

CREATE TABLE `subcategories` (
`sub_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ignore',
`cat_id` INTEGER UNSIGNED NOT NULL DEFAULT 0 COMMENT 'copy of cat_id from
categories table',
`subcat_id` INTEGER UNSIGNED NOT NULL DEFAULT 0 COMMENT 'cat_id of
subcategory',
FOREIGN KEY (`cat_id`) REFERENCES `categories`(`cat_id`) ON DELETE
CASCADE,
PRIMARY KEY(`sub_id`),
INDEX `ix_sccat_id`(`cat_id`),
INDEX `ix_scsubcat_id`(`subcat_id`)
) ENGINE=InnoDB;

ALTER TABLE `subcategories` ADD CONSTRAINT
FOREIGN KEY (`subcat_id`) REFERENCES `subcategories`(`cat_id`)
ON DELETE CASCADE;

Regards,
Bill K.


Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #4 (permalink)  
Old 02-28-2008, 07:18 AM
Axel Schwenke
 
Posts: n/a
Default Re: foreign key problem

Jerry Stuckle <jstucklex@attglobal.net> wrote:
> Jim Michaels wrote:
>>
>> CREATE TABLE `subcategories` (
>> `sub_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
>> `cat_id` INTEGER UNSIGNED NOT NULL DEFAULT 0,
>> `subcat_id` INTEGER UNSIGNED NOT NULL DEFAULT 0,
>> FOREIGN KEY (`cat_id`) REFERENCES `categories`(`cat_id`) ON DELETE CASCADE,
>> FOREIGN KEY (`subcat_id`) REFERENCES `subcategories`(`cat_id`) ON DELETE CASCADE,
>> PRIMARY KEY(`sub_id`),
>> INDEX `ix_sccat_id`(`cat_id`),
>> INDEX `ix_scsubcat_id`(`subcat_id`)
>> ) ENGINE=InnoDB;


> Your problem is right here:
>
> FOREIGN KEY (`subcat_id`) REFERENCES `subcategories`(`cat_id`) ON
> DELETE CASCADE,
>
> Generally you don't use a foreign key to reference the same table.


Although this design looks a bit weird, a foreign key into the same
table is no problem with InnoDB. In fact it is very useful if you
want to hold simple parent<->child relation in a single table.


XL
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #5 (permalink)  
Old 02-28-2008, 07:18 AM
Jerry Stuckle
 
Posts: n/a
Default Re: foreign key problem

Axel Schwenke wrote:
> Jerry Stuckle <jstucklex@attglobal.net> wrote:
>
>>Jim Michaels wrote:
>>
>>>CREATE TABLE `subcategories` (
>>> `sub_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
>>> `cat_id` INTEGER UNSIGNED NOT NULL DEFAULT 0,
>>> `subcat_id` INTEGER UNSIGNED NOT NULL DEFAULT 0,
>>> FOREIGN KEY (`cat_id`) REFERENCES `categories`(`cat_id`) ON DELETE CASCADE,
>>> FOREIGN KEY (`subcat_id`) REFERENCES `subcategories`(`cat_id`) ON DELETE CASCADE,
>>> PRIMARY KEY(`sub_id`),
>>> INDEX `ix_sccat_id`(`cat_id`),
>>> INDEX `ix_scsubcat_id`(`subcat_id`)
>>>) ENGINE=InnoDB;

>
>
>>Your problem is right here:
>>
>> FOREIGN KEY (`subcat_id`) REFERENCES `subcategories`(`cat_id`) ON
>>DELETE CASCADE,
>>
>>Generally you don't use a foreign key to reference the same table.

>
>
> Although this design looks a bit weird, a foreign key into the same
> table is no problem with InnoDB. In fact it is very useful if you
> want to hold simple parent<->child relation in a single table.
>
>
> XL


To some extent that's true. However, it also runs into the problem you
see here. He can't insert because the foreign key doesn't exist yet.

I should have added the solution is you need to remove the constraint,
add the first element, then add the constraint back in.

And BTW - although it might work sometimes, it's generally frowned upon
to reference you own table for this very reason. Another way to do it
is to have a second table with the parent-child relationships.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex@attglobal.net
==================
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #6 (permalink)  
Old 02-28-2008, 07:18 AM
Martijn Tonies
 
Posts: n/a
Default Re: foreign key problem


> >>>CREATE TABLE `subcategories` (
> >>> `sub_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
> >>> `cat_id` INTEGER UNSIGNED NOT NULL DEFAULT 0,
> >>> `subcat_id` INTEGER UNSIGNED NOT NULL DEFAULT 0,
> >>> FOREIGN KEY (`cat_id`) REFERENCES `categories`(`cat_id`) ON DELETE

CASCADE,
> >>> FOREIGN KEY (`subcat_id`) REFERENCES `subcategories`(`cat_id`) ON

DELETE CASCADE,
> >>> PRIMARY KEY(`sub_id`),
> >>> INDEX `ix_sccat_id`(`cat_id`),
> >>> INDEX `ix_scsubcat_id`(`subcat_id`)
> >>>) ENGINE=InnoDB;

> >
> >
> >>Your problem is right here:
> >>
> >> FOREIGN KEY (`subcat_id`) REFERENCES `subcategories`(`cat_id`) ON
> >>DELETE CASCADE,
> >>
> >>Generally you don't use a foreign key to reference the same table.

> >
> >
> > Although this design looks a bit weird, a foreign key into the same
> > table is no problem with InnoDB. In fact it is very useful if you
> > want to hold simple parent<->child relation in a single table.
> >
> >
> > XL

>
> To some extent that's true. However, it also runs into the problem you
> see here. He can't insert because the foreign key doesn't exist yet.
>
> I should have added the solution is you need to remove the constraint,
> add the first element, then add the constraint back in.


Right. That sounds bad -> modifying metadata to get your data in.

Why not insert a NULL instead and update your inserted row when
you've got your FK data in order?

Oh right, now I see:
CREATE TABLE `subcategories` (
`sub_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ignore',
`cat_id` INTEGER UNSIGNED NOT NULL DEFAULT 0 COMMENT 'copy of cat_id from
categories table',
`subcat_id` INTEGER UNSIGNED NOT NULL DEFAULT 0 COMMENT 'cat_id of
subcategory',
FOREIGN KEY (`cat_id`) REFERENCES `categories`(`cat_id`) ON DELETE
CASCADE,
FOREIGN KEY (`subcat_id`) REFERENCES `subcategories`(`cat_id`) ON DELETE
CASCADE,
PRIMARY KEY(`sub_id`),
INDEX `ix_sccat_id`(`cat_id`),
INDEX `ix_scsubcat_id`(`subcat_id`)
) ENGINE=InnoDB;


"subcat_id" is NOT NULL? How can that be? A sub-category
ALWAYS has to refer to a sub-category? The "default 0" looks
like there's a dummy sub category. That sounds bad as well.

IMO, the better thing to do is modify the design and split up this
table.


--
Martijn Tonies
Database Workbench - tool for InterBase, Firebird, MySQL, Oracle & MS SQL
Server
Upscene Productions
http://www.upscene.com
Database development questions? Check the forum!
http://www.databasedevelopmentforum.com


Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #7 (permalink)  
Old 02-28-2008, 07:18 AM
Axel Schwenke
 
Posts: n/a
Default Re: foreign key problem

Jerry Stuckle <jstucklex@attglobal.net> wrote:
> Axel Schwenke wrote:
>>>Jim Michaels wrote:


>>>Your problem is right here:
>>>
>>> FOREIGN KEY (`subcat_id`) REFERENCES `subcategories`(`cat_id`) ON
>>>DELETE CASCADE,
>>>
>>>Generally you don't use a foreign key to reference the same table.

>>
>>
>> Although this design looks a bit weird, a foreign key into the same
>> table is no problem with InnoDB. In fact it is very useful if you
>> want to hold simple parent<->child relation in a single table.



> To some extent that's true. However, it also runs into the problem you
> see here. He can't insert because the foreign key doesn't exist yet.


That's why I called his design 'weird'. Typically one has no NOT NULL
constraint on the parent id column. So root nodes are inserted with
parent id = NULL.

The other weird point is, that he has a FOREIGN KEY into another table
*and* a FOREIGN KEY into the same table. Usually you have only one of
them. If your nodes are all the same, you put them all into one table.
If some nodes (say: root nodes) are different, you put them in another
table.


XL
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #8 (permalink)  
Old 02-28-2008, 07:18 AM
Jim Michaels
 
Posts: n/a
Default Re: foreign key problem

I removed the offending foreign key. I could not insert the data into
categoryroots. foreign key problem again. forced to remove the foreign key
from categoryroots table so I could. why?

"Jerry Stuckle" <jstucklex@attglobal.net> wrote in message
news:hKGdnZyCgtS1akrenZ2dnUVZ_tqdnZ2d@comcast.com. ..
> Jim Michaels wrote:
>> I am not sure how to set up the foreign keys on this one, as I've never
>> done
>> foreign keys before (and I'm sure it shows). I have a tree of
>> information.
>> I can insert into the categories table, but not anything else - I get
>> foreign key errors (and I am not sure how to interpret the error).
>> Cannot add or update a child row: a foreign key constraint fails
>> (`db0/subcategories`, CONSTRAINT `subcategories_ibfk_2` FOREIGN KEY
>> (`subcat_id`) REFERENCES `subcategories` (`cat_id`) ON DELETE CASCADE)
>>
>>
>> I am also curious if the foreign key definition in subcategories would
>> cause
>> the database to fail or error on a delete because of the recursion.
>> (that's
>> where the tree is stored).
>>
>>
>> CREATE TABLE `categories` (
>> `cat_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
>> `category` VARCHAR(100) NOT NULL DEFAULT '' COMMENT 'your category
>> here',
>> PRIMARY KEY(`cat_id`),
>> UNIQUE KEY `ix_ccat_id` (`cat_id`),
>> INDEX `ix_ccat`(`category`)
>> ) ENGINE=InnoDB;
>>
>> CREATE TABLE `subcategories` (
>> `sub_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ignore',
>> `cat_id` INTEGER UNSIGNED NOT NULL DEFAULT 0 COMMENT 'copy of cat_id
>> from
>> categories table',
>> `subcat_id` INTEGER UNSIGNED NOT NULL DEFAULT 0 COMMENT 'cat_id of
>> subcategory',
>> FOREIGN KEY (`cat_id`) REFERENCES `categories`(`cat_id`) ON DELETE
>> CASCADE,
>> FOREIGN KEY (`subcat_id`) REFERENCES `subcategories`(`cat_id`) ON
>> DELETE
>> CASCADE,
>> PRIMARY KEY(`sub_id`),
>> INDEX `ix_sccat_id`(`cat_id`),
>> INDEX `ix_scsubcat_id`(`subcat_id`)
>> ) ENGINE=InnoDB;
>>
>> CREATE TABLE `categoryroots` (
>> `root_id` int(10) unsigned NOT NULL auto_increment COMMENT 'ignore',
>> `cat_id` int(10) unsigned NOT NULL default '0' COMMENT 'copy of cat_id
>> from categories table',
>> PRIMARY KEY (`root_id`),
>> FOREIGN KEY (`cat_id`) REFERENCES `subcategories`(`cat_id`) ON DELETE
>> CASCADE,
>> UNIQUE KEY `ix_crcat_id` (`cat_id`)
>> ) ENGINE=InnoDB;
>>

>
> (data snipped)
>
> Jim,
>
> Your problem is right here:
>
> FOREIGN KEY (`subcat_id`) REFERENCES `subcategories`(`cat_id`) ON DELETE
> CASCADE,
>
> Generally you don't use a foreign key to reference the same table. If I
> understand what you're trying to do, referencing categories should be
> sufficient.
>
> --
> ==================
> Remove the "x" from my email address
> Jerry Stuckle
> JDS Computer Training Corp.
> jstucklex@attglobal.net
> ==================



Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #9 (permalink)  
Old 02-28-2008, 07:18 AM
Jim Michaels
 
Posts: n/a
Default Re: foreign key problem

but then I can't insert any data.

"Bill Karwin" <bill@karwin.com> wrote in message
news:dr9u620499@enews4.newsguy.com...
> "Jim Michaels" <jmichae3@yahoo.com> wrote in message
> news:5rOdnSBK5PrqbkrenZ2dnUVZ_sydnZ2d@comcast.com. ..
>> Cannot add or update a child row: a foreign key constraint fails
>> (`db0/subcategories`, CONSTRAINT `subcategories_ibfk_2` FOREIGN KEY
>> (`subcat_id`) REFERENCES `subcategories` (`cat_id`) ON DELETE CASCADE)

>
> You can't add to a table a reference to the same table if the table hasn't
> been created yet.
> This is true if the SQL interpreter is just parsing the CREATE TABLE
> statement.
>
> To make self-referencing foreign keys, you have to create the table
> without that foreign key constraint (but do create the field to be used as
> the reference), then use ALTER TABLE to add the constraint.
>
> For example:
>
> CREATE TABLE `subcategories` (
> `sub_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ignore',
> `cat_id` INTEGER UNSIGNED NOT NULL DEFAULT 0 COMMENT 'copy of cat_id from
> categories table',
> `subcat_id` INTEGER UNSIGNED NOT NULL DEFAULT 0 COMMENT 'cat_id of
> subcategory',
> FOREIGN KEY (`cat_id`) REFERENCES `categories`(`cat_id`) ON DELETE
> CASCADE,
> PRIMARY KEY(`sub_id`),
> INDEX `ix_sccat_id`(`cat_id`),
> INDEX `ix_scsubcat_id`(`subcat_id`)
> ) ENGINE=InnoDB;
>
> ALTER TABLE `subcategories` ADD CONSTRAINT
> FOREIGN KEY (`subcat_id`) REFERENCES `subcategories`(`cat_id`)
> ON DELETE CASCADE;
>
> Regards,
> Bill K.
>



Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #10 (permalink)  
Old 02-28-2008, 07:18 AM
Jerry Stuckle
 
Posts: n/a
Default Re: foreign key problem

Jim Michaels wrote:
> I removed the offending foreign key. I could not insert the data into
> categoryroots. foreign key problem again. forced to remove the foreign key
> from categoryroots table so I could. why?
>


Jim,

When using foreign keys, the item must exist in the referenced table
before you can add it to the current table.

In this case it means to add an item to categoryroots with a cat_id of
1, you need to first have an entry with cat_id of 1 in the subcategories
table.

And please don't top post.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex@attglobal.net
==================
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 05:42 PM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com