This query is running an upsert which is being called from PHP, I wasn't getting the updates except for one table, which was really odd. I tried the query and noticed this was seeming to be the case. If I run it for the following value, the row does not update.
Row
operation_attendee_id operation_id member_id status
1 5 1 1
Query:
INSERT INTO
`operation_attendee` (
`operation_id`,
`member_id`,
`status`)
VALUES
(5,
1,
3)
ON DUPLICATE KEY UPDATE
`status` = 3
This will not update the table, but there is a unique index on operation_id, member_id
If I run for this row
operation_attendee_id operation_id member_id status
0 7 1 1
Same exact query, different numbers
INSERT INTO
`operation_attendee` (
`operation_id`,
`member_id`,
`status`)
VALUES
(7,
1,
3)
ON DUPLICATE KEY UPDATE
`status` = 3
This one updates fine. I'm really perplexed as to why this seems to be the only value set that is updating.
EDIT: Adding table DDL and all indexes:
CREATE TABLE `operation_attendee` (
`operation_attendee_id` int(11) NOT NULL,
`operation_id` int(11) NOT NULL,
`member_id` int(11) NOT NULL,
`status` int(11) NOT NULL,
PRIMARY KEY (`operation_attendee_id`),
UNIQUE KEY `uk_operation_member` (`operation_id`,`member_id`),
KEY `fk_operation_attendee_operation1_idx` (`operation_id`),
KEY `fk_operation_attendee_member1_idx` (`member_id`),
KEY `fk_operation_attendee_operation_attendee_status1_idx` (`status`),
CONSTRAINT `fk_operation_attendee_member1` FOREIGN KEY (`member_id`) REFERENCES `member` (`member_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_operation_attendee_operation1` FOREIGN KEY (`operation_id`) REFERENCES `operation` (`operation_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_operation_attendee_operation_attendee_status1` FOREIGN KEY (`status`) REFERENCES `operation_attendee_status` (`operation_attendee_status_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8
I also tried to run the query with foreign key check off and it still doesn't update.
and
It seems it was an issue with the surrogate key.
I removed it (it was not needed for that table, someone else built it a long while back), and then replace the primary key with the unique key I was using prior (removed the unique key as well since it was redundant) the query now seems to be working fine.
I'm not sure why it was causing issues in terms of an underlying reason, but it works now. I would think the unique key I put on the table would have matched the conditions for the ON DUPLICATE KEY UPDATE requirement.
Related
I have this table:
CREATE TABLE comments(
comment_id int(11) NOT NULL auto_increment,
user_id int(11) NOT NULL,
product_id int(11) NOT NULL,
comment_text varchar(1000) COLLATE utf8_czech_ci NOT NULL,
uploaded datetime NOT NULL,
primary key(comment_id),
constraint fk_user_comments foreign key(user_id) references user(user_id) ON UPDATE CASCADE ON DELETE CASCADE,
constraint fk_product_comments foreign key(product_id) references product(product_id) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;
and I'm trying to insert data into this table.
INSERT INTO comments(user_id,product_id,comment_text,uploaded) VALUES(1,'brbr',1,Now());
But for some reason I keep getting this error:
Error Code: 1452. Cannot add or update a child row: a foreign key constraint fails (`project`.`comments`, CONSTRAINT `fk_product_comments` FOREIGN KEY (`product_id`) REFERENCES `product` (`product_id`) ON DELETE CASCADE ON UPDATE CASCADE)
User with id 1 exists and product with id 1 exists so now i have no idea whats causing the problem.
You've got your column list's order messed up.
You're attempting to insert a row with a product_id of 'brbr' (which MySQL treats as 0) and a comment text of 1 (which MySQL converts as to '1').
Reordering the the column list to match the values (or vise-versa) should solve it:
INSERT INTO comments
(user_id, product_id, comment_text, uploaded)
VALUES (1, 1, 'brbr', NOW());
-- Here ---^
This because you are not adding value according to your column sequence.
This is correct query.
INSERT INTO comments(user_id,product_id,comment_text,uploaded) VALUES(1,1,'brbr',Now())
I met the same problem today as I was dealing with Schema that wasn't designed by me. I added tables and relationships (FK) and things went KaBoom!
Upon investigation, I found the other buddy was using MyIsam Engine for that table and I was using InnoDB.
Changing the table from MyIsam to InnoDB ssolved the Issue!
I have a products table, and a product_variants table (one-to-many).
The product_variants table has the following structure:
CREATE TABLE product_variants (
id int(11) NOT NULL AUTO_INCREMENT,
id_product int(11) NOT NULL,
id_colourSet int(11) DEFAULT NULL,
id_size int(11) DEFAULT NULL,
PRIMARY KEY (id),
UNIQUE KEY UNIQUE (id_product,id_colourSet,id_size),
KEY idx_prod (id_product),
KEY idx_colourSet (id_colourSet),
KEY idx_size (id_size),
CONSTRAINT fk_df_product_variants_id_colurSet FOREIGN KEY (id_colourSet) REFERENCES df_colour_sets (id_colourSet) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT fk_df_product_variants_id_product FOREIGN KEY (id_product) REFERENCES df_products (id) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT fk_df_product_variants_id_size FOREIGN KEY (id_size) REFERENCES df_sizes (id) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB
The options are known at compile-time. Each option is foreign-keyed to a dedicated table, and the unique key is the combination of all options.
I then insert products with an "ON DUPLICATE KEY UPDATE ..." statement, and if a variant already exists the query will use an existing variant.
The problem is that certain products do not have a color, nor a size. In this case the unique constraint fails and I insert lots of almost-empty rows in the product_variants table.
In order to solve this problem I am creating a "NULL" value for each option (e.g. "NO_COLOR", "NO_SIZE") in the respective option tables, and using that as the default value for the option columns in the product_variants table.
Would this be the recommended solution? Is there a better way of structuring this data? I would really like to avoid an EAV design.
Thank you
Designating a magic value that means "missing value" is not the right solution in almost every case. That's what NULL is for.
It's also not clear how "NO_COLOR" is used for an integer. I guess it would map to the value 0, which is typically not used in an auto-increment column.
You can create another column to be a hash of the three unique key columns, defaulted to '' to avoid null problems. Then put a unique constraint on that hash.
CREATE TABLE product_variants (
id int(11) NOT NULL AUTO_INCREMENT,
id_product int(11) NOT NULL,
id_colourSet int(11) DEFAULT NULL,
id_size int(11) DEFAULT NULL,
option_hash binary(16) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY (option_hash),
KEY idx_prod (id_product),
KEY idx_colourSet (id_colourSet),
KEY idx_size (id_size),
CONSTRAINT fk_df_product_variants_id_colurSet FOREIGN KEY (id_colourSet) REFERENCES df_colour_sets (id_colourSet) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT fk_df_product_variants_id_product FOREIGN KEY (id_product) REFERENCES df_products (id) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT fk_df_product_variants_id_size FOREIGN KEY (id_size) REFERENCES df_sizes (id) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB;
CREATE TRIGGER product_variants_ins BEFORE INSERT ON product_variants
FOR EACH ROW SET option_hash = UNHEX(MD5(CONCAT_WS('|',
COALESCE(id_product, ''),
COALESCE(id_colourSet, ''),
COALESCE(id_size, ''))));
CREATE TRIGGER product_variants_upd BEFORE UPDATE ON product_variants
FOR EACH ROW SET option_hash = UNHEX(MD5(CONCAT_WS('|',
COALESCE(id_product, ''),
COALESCE(id_colourSet, ''),
COALESCE(id_size, ''))));
I am trying to insert pseudo data into my db to get going, and in one particular table I have two columns which are FK's and PK's of the table; fk_product_manf_code and fk_content_id. To my understanding, these are considered composite keys in their current state.
So I add data to the table:
fk_product_manf_code fk_content_id
NOV-ABC123 1
I then want to associate another content_id to the same product_manf_code, so I perform the following:
INSERT INTO `mydb`.`package_contents`
(`fk_product_manf_code`, `fk_content_id`)
VALUES
('NOV-ABC123', 2);
However I'm greeted with the following error:
Error Code: 1062. Duplicate entry 'NOV-ABC123' for key 'fk_product_manf_code_UNIQUE'
I don't understand what's going, because I thought a composite key makes 2 columns unique? So why is it kicking up a fuss about just 1 column being unique?
Here is the table CREATE statement
CREATE TABLE `package_contents` (
`fk_product_manf_code` varchar(255) NOT NULL,
`fk_content_id` int(11) NOT NULL,
PRIMARY KEY (`fk_content_id`,`fk_product_manf_code`),
UNIQUE KEY `fk_content_id_UNIQUE` (`fk_content_id`),
UNIQUE KEY `fk_product_manf_code_UNIQUE` (`fk_product_manf_code`),
CONSTRAINT `content_id` FOREIGN KEY (`fk_content_id`) REFERENCES `contents` (`content_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `product_manf_code` FOREIGN KEY (`fk_product_manf_code`) REFERENCES `products` (`product_manf_code`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
So, you are learning why composite primary keys are a pain, especially for foreign key constraints. Not only are integer keys more efficient, but a single key is easier to work with.
I would suggest changing your table structure to be more like this:
CREATE TABLE package_contents (
package_contents_id int not null auto_increment primary key,
fk_product_manf_id int NOT NULL,
fk_content_id int(11) NOT NULL,
UNIQUE KEY (fk_content_id, fk_product_manf_id),
CONSTRAINT content_id FOREIGN KEY (fk_content_id)
REFERENCES contents(content_id) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT product_manf_code FOREIGN KEY (fk_product_manf_id)
REFERENCES products(product_manf_id) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Note that I changed the manufacturer code to an id as well. This should also reduce the size of the table, assuming that the "code" is longer than 4 bytes.
If you do this for all your tables, the database will be a bit more efficient, and you won't need superfluous unique constraints. The foreign key constraints should always be to primary keys (unless there is a very good reason for using a different unique key).
I have created two tables in MySQL 5.6.11 as shown below by means of MySQL Workbench 5.2.47.
The country table:
delimiter $$
CREATE TABLE `country` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`country_name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INC
REMENT=2 DEFAULT CHARSET=utf8$$
The state_table:
delimiter $$
CREATE TABLE `state_table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`state_name` varchar(45) DEFAULT NULL,
`country_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `country_fk` FOREIGN KEY (`id`) REFERENCES `country` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT=''$$
There is one row in the country table with the id 1. It allows only one (child) row to be inserted into its child table state_table. If more rows are attempted, then the following error occurs.
ERROR 1452: Cannot add or update a child row: a foreign key constraint
fails (social_networking.state_table, CONSTRAINT country_fk
FOREIGN KEY (id) REFERENCES country (id) ON DELETE CASCADE ON
UPDATE CASCADE)
SQL Statement:
INSERT INTO `social_networking`.`state_table` (`id`, `state_name`, `country_id`) VALUES ('2', 'xxx', '1')
Actually, I'm trying to map these tables using an ORM (JPA) where I always see only OneToOne relationship.
What am I missing?
Well, I find the answer, the solution, my english is not very well but I think can explain you. I get this error after try to create a trigger, My database was created in phpmyadmin, and this error was make me crazy, the problem was that I before create the trigger, I load a lot of data in my tables, and in my child table was some data that have no match in my parent table, ej: my child table "chat" have a "id_jugador=1" and in my parent table there wasn't that "id_jugador", that was my mistake, I hope help you, Argentina Rulz ;)
I think you have a typo in your foreign key constraint, country_id should probaby be the foreign key to country. When id is the foreign key, you can only insert one row since it just happens to get id=1 which is the same id as the row in country;
CONSTRAINT `country_fk` FOREIGN KEY (`id`)
REFERENCES `country` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
should probably be
CONSTRAINT `country_fk` FOREIGN KEY (`country_id`)
REFERENCES `country` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
An SQLfiddle to test with.
I had the same problem and it was not wrong relationships name.
I had problem with different records, ie, tried registering a record that did not exist in another table so generated this error.
Check if the record exists in another table to insert their correct relationship, otherwise, this error appears.
Hope this help you.
example:
table1(
id1 INT PRIMARY KEY,
name1 VARCHAR(50)
)
table2(
id2,<--- want to add FOREIGN KEY to this field
name2 VARCHAR(50)
)
Before adding constraint foreign key you must have the right value between id1 and id2, so you should update that id field with the value that map each other.
Possible Solution
if you have live data, then check all column values.
i.e. if you have 'x'->table as primary one having 'a'->column and 'y'->table as secondary with 'b'->column, then all values in 'b'->column must exist in 'a'->column if any value that exists in 'b'->column and not exist in 'a'->column then it will give as such error..
Hope this help.. for newbie..
I'm having an issue INSERTING with the composite keys in my MySQL table DESP_Features_Weak.
I already took a look at
MySQL composite unique on FK's, but my problem is a little bit different.
INSERT INTO DESP_Features_Weak (details, Features_f_id, fk_desp_id, fk_dfws_id) VALUES (NULL, 2, 1, 5);
yields,
Error Code: 1062. Duplicate entry '1-2' for key 'PRIMARY'
Oddly however searching for a record with a 1,2 key (or even a 2,1 key) doesn't return any records, so there isn't a duplicate entry.
I read over in the MySQL documentation and a few people seem to have dropped their indexes to fixed their problem; I did the same and it doesn't seem to have changed anything, although I believe there is still an index named PRIMARY which I have been unable to drop.
This is just a personal database I've thrown together in MySQL Workbench, it's not in production or anything.
A dump of the related table looks like this:
CREATE TABLE `DESP_Features_Weak` (
`DESP_Features_Weakcol` varchar(45) DEFAULT NULL,
`Details` mediumtext,
`fk_desp_id` int(11) NOT NULL,
`Features_f_id` int(11) NOT NULL,
`CostType_ct_id` int(11) NOT NULL,
`cost_amount` decimal(18,2) DEFAULT NULL,
`askedAboutFeatureFees` tinyint(1) DEFAULT NULL,
`fk_dfws_id` int(11) DEFAULT NULL,
PRIMARY KEY (`fk_desp_id`,`Features_f_id`),
KEY `fk_DESP_Features_Weak_Features1` (`Features_f_id`),
KEY `fk_DESP_Features_Weak_DESP_Feature_Weak_State1` (`fk_dfws_id`),
CONSTRAINT `fk_DESP_Features_Weak_DigitalEditionsSolutionProvider1` FOREIGN KEY (`fk_desp_id`) REFERENCES `DigitalEditionsSolutionProvider` (`desp_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_DESP_Features_Weak_DESP_Feature_Weak_State1` FOREIGN KEY (`fk_dfws_id`) REFERENCES `DESP_Feature_Weak_State` (`dfws_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_DESP_Features_Weak_Features1` FOREIGN KEY (`Features_f_id`) REFERENCES `Features` (`f_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/