Problems setting one-to-many relationships on PHPMyAdmin - mysql

I am having a problem setting my one-to-many relationships on PHPMyAdmin
Here is tbl_books
book_id (primary key)
bookcat_id_fk (foreign key 'on update restrict, on delete restrict')
bookname
bookdesc
Here is tbl_bookcat
bookcat_id (primary key)
bookcat_name
The relationship between the two should be that there is ONE category to MANY books, so a one-to-many relationship.
The problem that am getting would be that I am getting the error: Duplicate entry '1' for key bookcat_id_fk
This means that I am unable to assign more books to the same category because of this, so my one-to-many relationship is not working. I have searched but I could find the answer I was wondering if you could help me out.
Thanks.

I suspect your key definition bookcat_id_fk is UNIQUE, but without seeing the full dump don't know for sure. Anyway, I believe this is what you're trying to achieve:
CREATE TABLE IF NOT EXISTS `tbl_bookcat` (
`bookcat_id` int(11) NOT NULL,
`bookcat_name` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `tbl_books` (
`book_id` int(11) NOT NULL,
`bookcat_id_fk` int(11) NOT NULL,
`bookname` varchar(255) NOT NULL,
`bookdesc` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `tbl_bookcat`
ADD PRIMARY KEY (`bookcat_id`);
ALTER TABLE `tbl_books`
ADD PRIMARY KEY (`book_id`),
ADD KEY `bookcat_id_fk` (`bookcat_id_fk`);
ALTER TABLE `tbl_bookcat`
MODIFY `bookcat_id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `tbl_books`
MODIFY `book_id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `tbl_books`
ADD CONSTRAINT `tbl_books_ibfk_1` FOREIGN KEY (`bookcat_id_fk`) REFERENCES `tbl_bookcat` (`bookcat_id`);

Related

cannot add foreign key constraint in phpmyadmin

While creating 2 tables in phpmyadmin I am getting an error like this.
MySQL said: Documentation
#1215 - Cannot add foreign key constraint
My table structures are
CREATE TABLE `iwd_storelocator_manufacturer` (
`entity_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT ,
`name` varchar(255) NOT NULL ,
`code` varchar(255) NOT NULL ,
`grayscale_image` varchar(255) NULL ,
`color_image` varchar(255) NULL ,
PRIMARY KEY (`entity_id`)
);
CREATE TABLE `iwd_storelocator_manufacturer_to_store` (
`manufacturer_id` int(11) UNSIGNED NOT NULL ,
`store_id` int(11) NOT NULL ,
`preferred` int NULL ,
PRIMARY KEY (`manufacturer_id`, `store_id`),
FOREIGN KEY (`store_id`) REFERENCES `iwd_storelocator_store` (`store_id`) ON DELETE RESTRICT ON UPDATE CASCADE,
FOREIGN KEY (`manufacturer_id`) REFERENCES `iwd_storelocator_manufacturer` (`entity_id`) ON DELETE RESTRICT ON UPDATE CASCADE
);
Can you tell me whats the problem in it?
This is my iwd_storelocator_store table
iwd_storelocator_store
In order to know exactly what is wrong, you must check in LATEST FOREIGN KEY ERROR section.
Use this query to find this out:
SHOW ENGINE INNODB STATUS
Also, make sure that all the data types are the same: the data type of the child column must match the data type from the parent column.
If the problem is the order of creation of the tables (which can cause this error), just run set foreign_key_checks=0 so you can create the tables in any order rather than having to create all the parents tables BEFORE the child tables.
Finally, make sure that the encoding is the same for all the tables.
EDIT: in your case, you should also give us the structure of iwd_storelocator_store table
Now that we have your iwd_storelocator_store table, I think that you should create an index on store_id column as it is not the primary key of the table

Odd Error in mariaDB Foreign Keys

Hi i hope some one can help my problem is that when i try to add a foreign key constraint i get this error.
My database name is "hazard"
Child:
CREATE TABLE `child` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`a` INT(11) NULL DEFAULT NULL,
`b` INT(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
Parent:
CREATE TABLE `parent` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`alfa` INT(11) NULL DEFAULT NULL,
`beta` INT(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
Those are the create codes (using HeidiSQL)
and when i try to add a foreign key
with
ALTER TABLE CHILD MODIFY COLUMN A INT,add constraint fk_parent_child FOREIGN KEY(A) REFERENCES PARENT(ALFA);
or
ALTER TABLE CHILD add constraint fk1 foreign key (a) references parent(alfa);
I get the same error
Can't create table 'hazard.#sql-d04_53' (errno: 150)
this is happening to many of my classmates using MariaDB and mySQL
Beforehand an apology for the inconvenience and I hope you guys can help us.
Add
KEY (`alfa`)
to the parent table. "The referenced columns must be a PRIMARY KEY or a UNIQUE index." – https://mariadb.com/kb/en/mariadb/foreign-keys/
http://sqlfiddle.com/#!9/b4c12
Error 150 usually means you are updating the tables in the wrong order. That is, your first INSERT violates the FOREIGN KEY constraint that your second INSERT will fix.
In your case you are doing ALTER instead of INSERT. Swap the order of the ALTERs. If that does not work, check the data to see that you won't be violating FK constraints. If you get past that, read on...
In extreme cases, you can turn off foreign key constraints while doing the inserts, then turn them back on. (But that leaves you vulnerable to screw-ups.)

How to add Foreign Key (MySQL)

I'm extremely new to SQL and I'm trying to perform a simple ALTER TABLE to create a new column and use it as a foreign key to reference another simple table in my database. I've altered both tables to be InnoDB
However, when executing the ALTER TABLE code, I get the following error:
Error 1452 Cannot add or update a child row:
a foreign key constraint fails (`toys`.<result 2 when
explaining filename '#sql-6d4_6'>, CONSTRAINT
`#sql-6d4_6_ibfk_1` FOREIGN KEY (`toy_id`) REFERENCES `toys` (`toy_id`))
Below are the DESC of both tables:
Table 1:
FIELD TYPE NULL KEY EXTRA
toy_id int(11) NO PRI auto_increment
toy varchar(50) YES
Table 2:
FIELD TYPE NULL KEY EXTRA
boy_id int(11) NO PRI auto_increment
boy varchar(50) YES
And this is the ALTER query I was trying to perform:
ALTER TABLE boys
ADD COLUMN toy_id INT NOT NULL,
ADD CONSTRAINT toys_toy_id_fk
FOREIGN KEY(toy_id)
REFERENCES toys(toy_id);
I've looked all over trying to figure it out, but with no luck. Thanks in advance, and please be kind to this newbie :)
EDIT:
Here are the SHOW CREATE TABLE for both tables:
TABLE 1:
CREATE TABLE `toys` (
`toy_id` int(11) NOT NULL AUTO_INCREMENT,
`toy` varchar(50) DEFAULT NULL,
PRIMARY KEY (`toy_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8
TABLE 2:
CREATE TABLE `boys` (
`boy_id` int(11) NOT NULL AUTO_INCREMENT,
`boy` varchar(50) DEFAULT NULL,
PRIMARY KEY (`boy_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8
You can't add a NOT NULL column to a table that has more than zero rows, when the column is constrained to values that match those in the parent table, and yet has only NULL values because it's a new, unpopulated column with no DEFAULT.
The workaround is to do it in stages: add the column, but don't declare it NOT NULL, and don't declare the foreign key yet.
ALTER TABLE boys
ADD COLUMN toy_id INT;
Then populate it with valid data that matches some value(s) in your toys table.
UPDATE boys SET toy_id = ...;
Then alter the column to be NOT NULL, and create the constraint:
ALTER TABLE boys MODIFY COLUMN toy_id INT NOT NULL,
ADD CONSTRAINT toys_toy_id_fk
FOREIGN KEY(toy_id)
REFERENCES toys(toy_id);

Problems with MySQL bidirectional relationship and mirrored foreign keys

i have to create two tables with a bidirectional relationship, as in the figure given below.
But it always gives an error. I am using the following query for creating the tables.
CREATE TABLE IF NOT EXISTS `rpt_operation` (
`op_id` int(45) NOT NULL,
`component` int(45) NOT NULL,
`ideal_time` time NOT NULL,
`handling_time` time NOT NULL,
PRIMARY KEY (`op_id`),
INDEX (component),
FOREIGN KEY (component)
REFERENCES rpt_component(comp_id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `rpt_component` (
`comp_id` int(45) NOT NULL,
`lot_code` int(60) NOT NULL,
`lot_color` varchar(60) NOT NULL,
`drawing_num` int(60) NOT NULL,
`revision_num` int(60) NOT NULL,
`operation` int(45) NOT NULL,
PRIMARY KEY (`comp_id`),
INDEX (operation),
FOREIGN KEY (operation)
REFERENCES rpt_operation(op_id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
The error appear in the line component int(45) NOT NULL of rpt_operation table.
Any help will be appreciated.
Thanks in advance
Your table structure is impossible. You can't insert any records into rpt_operation because there are no records in rpt_component for the component foreign key, and you can't insert any records into rpt_component because there are no records in rpt_operation for the operation foreign key.
If you make one or both of those fields nullable, then the table structure is still recursive, so you have to add one of the foreign keys manually, for example:
ALTER TABLE rpt_operation
ADD CONSTRAINT
FOREIGN KEY (component)
REFERENCES rpt_component(comp_id);
I would suggest you to use a linking-table to resolve this problem. This is not a viable solution and requires workarounds.

Foreign key between MySQL InnoDB tables not working...why?

I have the following tables:
specie (MyIsam)
image (InnoDB)
specie_map (InnoDB)
The specie_map table should map an image to a specie, and therefore has the following columns:
specie_id
image_id
Both are int 11, just like the id columns of the specie and image tables. I know I can't create a foreign key between specie_id and specie=>id, since the specie table is a MyIsam table. However, I would expect it to be possible to create a foreign key between image_id and image=>id.
I can create that foreign key and it will save it, however, the CASCADE action I have associated with it does not work. When I delete an image, it does not delete the specie_map entry that is associated with it. I would expect this to work, as this foreign key is between InnoDB tables. Both columns are indexed and of the same data type.
Is this a limitation of MySQL, or am I doing something else wrong?
Update: as requested hereby the table definitions. I have snipped unimportant columns:
-- ----------------------------
-- Table structure for `image`
-- ----------------------------
DROP TABLE IF EXISTS `image`;
CREATE TABLE `image` (
`id` int(11) NOT NULL auto_increment,
`guid` char(36) default NULL,
`title` varchar(255) NOT NULL,
`description` text,
`user_id` int(11) NOT NULL,
`item_id` int(11) default NULL,
`date_uploaded` timestamp NOT NULL default '0000-00-00 00:00:00',
`date_created` timestamp NOT NULL default '0000-00-00 00:00:00',
`date_modified` timestamp NOT NULL default '0000-00-00 00:00:00',
`status` enum('softdeleted','tobedeleted','active') default 'active',
PRIMARY KEY (`id`),
KEY `image_user` (`user_id`),
KEY `image_item` (`item_id`),
KEY `image_mod_by` (`moderated_by`),
CONSTRAINT `image_mod_by` FOREIGN KEY (`moderated_by`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `image_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='stores image data (not file data)';
-- ----------------------------
-- Table structure for `specie`
-- ----------------------------
DROP TABLE IF EXISTS `specie`;
CREATE TABLE `specie` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(256) NOT NULL,
`commonname` varchar(256) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=22 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
-- ----------------------------
-- Table structure for `specie_map`
-- ----------------------------
DROP TABLE IF EXISTS `specie_map`;
CREATE TABLE `specie_map` (
`id` int(11) NOT NULL auto_increment,
`image_id` int(11) NOT NULL,
`specie_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`karma` int(11) NOT NULL,
`date_created` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `image_id` (`image_id`),
KEY `specie_id` (`specie_id`),
CONSTRAINT `specie_map_ibfk_1` FOREIGN KEY (`image_id`) REFERENCES `image` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Foreign keys works only with InnoDb in mysql. MyISAM doesn't support them (the statements are ignored).
And is there any reason why you mix multiple DB engines?
I think you should post the exact DDL statements you used when you attempted to create these tables and the foreign key. Foreign keys between innodb tables work fine, but there are still a few things to look out for:
0) Both tables must be InnoDB. This was already highlighted by the other posters and this is probably the immediate cause of your problem.
1) the data type of the referencing columns (those that make up the foreign key) and their respective referenced columns should be the same. For example, you can't create a foreign key constrain on an INT UNSIGNED column to a plain INT column.
2) if the foreign key is created as part of the table DDL, be sure to put the foreign key definition in the constraints section, that is, below all column definitions. For example:
CREATE TABLE parent (
id int unsigned PRIMARY KEY
);
CREATE TABLE child (
parent_id int unsigned
, foreign key (parent_id)
references parent (id)
);
will work but this:
CREATE TABLE child (
parent_id int unsigned
foreign key references parent (id)
);
won't. It will fail silently because MySQL's parser ignores these types of constraint definitions even before InnoDB gets to create the table (silly, but that's how it is)
3) There must be an index over all the referenced columns. Usually the referenced columns will together make up a primary key or a unique constraint anyway, but it is your job to define this before defining the foreign key.
Final word of advice: if you think your DDL is ok but you still get an error when you execute it, for example like this:
ERROR 1005 (HY000): Can't create table 'test.child' (errno: 150)
Warning (Code 150): Create table 'test/child' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns.
Error (Code 1005): Can't create table 'test.child' (errno: 150)
Then these errors may still not reveal the true nature of the error (silly again, but that's how it is). To shed more light on it, run this command immediately after your attempt to create the foreign key:
SHOW ENGINE INNODB STATUS;
This will give you a bunch of status info, and one section there looks like this:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
120122 11:38:28 Error in foreign key constraint of table test/child:
foreign key (parent_id) references parent (id) ):
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
for correct foreign key definition.
As you can see, this gives a bit more information and reveals the true problem, namely "column types in the table and the referenced table do not match for constraint"
So please, post your actual DDL, I'm sure there is a problem in there somewhere.