Foreign Key "breaks" after a while - mysql

After several days of application running successfully I suddenly see errors:
Cannot add or update a child row: a foreign key constraint fails
If I run the SQL outside the context of the application sure enough it fails.
The data looks good and the constraints worked previously. Further, if I drop the constraints and add them back as they were everything works again.
I have to go through and drop/add the constraints until everything works again.
Any ideas of what I may be doing wrong here or quick way to recreate all FK's quickly?
Example FK Contraints:
CONSTRAINT `FKC92ACD965FF39405` FOREIGN KEY (`foodItem_id`) REFERENCES `FoodItem` (`id`),
CONSTRAINT `FKC92ACD966C592425` FOREIGN KEY (`meal_id`) REFERENCES `Meal` (`id`)
Example SQL:
into MealItem
(foodItem_id, meal_id, quantity)
values(150, 277, 0.375)
Thanks,
Bruce

I have never heard of a case where InnoDB foreign keys work intermittently and need to be dropped and recreated. And I don't recommend you adopt a habit of running unnecessary ALTER TABLE statements.
The more likely explanation is that you first tried to insert a row to MealItem before the referenced rows in either FoodItem or Meal have been inserted.
You can find more information on the exact foreign key constraint that was violated, by running:
mysql> pager less
mysql> SHOW ENGINE INNODB STATUS;
Look for the subsection something like the following:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
...some information about the transaction and thread context...
insert into MealItem (foodItem_id, meal_id, quantity) values(150, 277, 0.375)
Foreign key constraint fails for table `mydatabase/MealTime`:
CONSTRAINT `FKC92ACD965FF39405` FOREIGN KEY (`foodItem_id`) REFERENCES `FoodItem` (`id`),
Trying to add in child table, in index `foodItem_id` tuple:
DATA TUPLE: 2 fields; ...some binary description of the row you tried to insert... 
But in parent table `mydatabase/FoodItem`, in index `PRIMARY`,the closest match we can find is record:
...some binary description of MySQL's guess at a row near the one that's missing...
I've mocked up this example, and omitted some of the less useful stuff. This diagnostic information is relatively easy to read (compared to some). From this you can discover exactly which constraint had a conflict, and which parent table is missing the needed row.
Re your comment:
You wouldn't happen to be using OS X and MySQL between 5.5.8 and 5.5.12? I found the error you mention in reference to a bug that appeared in a specific version of MySQL, and only on OS X. Details here: http://bugs.mysql.com/bug.php?id=60309
The bug should be fixed if you upgrade to at least 5.5.13, or preferably upgrade to the latest
(5.5.32 as of June 2013).

Related

Mysql cannot add or update child row, Foreign key related failure

Error: cannot add or update a child row: foreign key constraint fails
Following is the code that is creating the error:
ALTER TABLE 'catalog_eav_attribute'
ADD CONSTRAINT 'FK_CATALOG_EAV_ATTRIBUTE_ID'
FOREIGN KEY ('attribute_id') REFERENCES 'eav_attribute' ('attribute_id)'
ON DELETE CASCADE ON UPDATE CASCADE;
I uploaded the Structure of SQL and its has no issue , but when i insert the data i am getting the above related error. I read somewhere and i predict its because of lousy data.What are the other possibilities for the error ? Any suggestions or solution will be great.
"For storage engines other than InnoDB, MySQL Server parses the FOREIGN KEY syntax in CREATE TABLE statements, but does not use or store it."
From: http://dev.mysql.com/doc/refman/5.5/en/ansi-diff-foreign-keys.html
I'm not sure, but if your table is MyISAM and not InnoDB, your syntax might not work.
The error message means whatever number you're trying to put into the attribute_id column doesn't yet exist in the eav_attribute.attribute_id column.
Can you insert a value that does already exist in eav_attribute.attribute_id? (You probably can.)
Can you provoke the same error by trying to insert a value that doesn't exist in eav_attribute.attribute_id?
Reconcile the differences, and you're done. You need to determine which attribute ids don't exist in eav_attribute.attribute_id, and fix that.

Foreign Key Constraint is incorrectly formed

There are several other questions about this topic that I have gone through, but I can't seem to figure out how their solutions apply to my tables. Check out the sqlfiddle. You can see it builds the schema just fine.
Basically, one table is a table of contacts/people. The second table is a table of countries. I am attempting to create a foreign key reference between contacts.country_id and countries.id.
Now, add the following to the panel on the left side:
ALTER TABLE `ultra_contacts`
ADD INDEX `fk_test` (`country_id`),
ADD CONSTRAINT `fk_test` FOREIGN KEY (`country_id`) REFERENCES `ultra_countries` (`id`) ON UPDATE CASCADE ON DELETE CASCADE`
The alter table code is not working for some reason. Any help would be appreciated.
The error is: Schema Creation Failed: Can't create table 'db_e342e.#sql-7711_1a4d2' (errno: 150): Using a 3rd party program (HeidiSQL) the error is a bit more detailed:
Foreign key constraint is incorrectly formed
You're trying to use foreign keys on a MyISAM table, which is not allowed (they only work with InnoDB). Take a look here: http://sqlfiddle.com/#!2/64951 All I've changed from your original is the table type (from MyISAM to InnoDB) and then I added the constraint. Worked fine.
Full disclosure - I'm the author of SQL Fiddle :)

Cascading delete removes unintended records

I typically develop in MS Access and occasionally connect to a MySQL back end. I have a MySQL back end that isn't cascading deletes as I'd expect when I delete records. I'm wondering if it's because of how I've set up the table relationships (foreign keys). I don't know enough about MySQL to know if I've done this right. In designer view I set up the relationships using the designer view in MySQL. For a composite primary key field (InterviewID, Coder ID) in tblInterviews I created two separate relations to tblSB for each of these two primary key fields (tblSB includes a 3rd field, SBid, as its composite PK). The designer view is a little different from Access in that you can't highlight more than one field at a time to set up relationships. I did find forums that discuss the syntax for setting up the relationship with the foreign key but I don't know if it's equivalent to what I did in designer. I suspect not because currently when I try to delete a specific record (unique InterviewID, CoderID combination) ALL interview records for the CoderID in the InterviewID, CoderID combination get deleted (and this cascades through to other child tables as well). I also am wondering if I need to set up my primary key in a way that I am not currently doing (e.g., setting it up as an index, also). Any help would be appreciated. Thanks in advance.
To see what you've created, look at the DDL. (SHOW CREATE TABLE)
To enforce foreign key constraints--including cascading deletes--you probably want to use the innodb engine. The myisam engine will accept DDL that declares foreign keys, but it won't enforce them.
MySQL will let a foreign key target a non-unique column. The MySQL docs say
Deviation from SQL standards: A FOREIGN KEY constraint that references
a non-UNIQUE key is not standard SQL. It is an InnoDB extension to
standard SQL.
They call it an extension to SQL. I call it a mistake.
It means you can declare tblSB.interviewID as a foreign key referencing tblInterviews.interviewID. A standard SQL dbms wouldn't allow that.
The 5.6 docs say
However, the system does not enforce a requirement that the referenced
columns be UNIQUE or be declared NOT NULL. The handling of foreign key
references to nonunique keys or keys that contain NULL values is not
well defined for operations such as UPDATE or DELETE CASCADE. You are
advised to use foreign keys that reference only UNIQUE and NOT NULL
keys.
To my way of thinking, they're saying, "It was a bad idea, but we don't know how to fix it. So it's up to you to avoid it. We could warn you when you try it, but we're not going to do that, either."
Based on your comments, I'd say this constraint is right . . .
CONSTRAINT tblInterviewRecordtblSB
FOREIGN KEY (InterviewID, CoderID)
REFERENCES tblinterviewrecord (InterviewID, CoderID)
ON DELETE CASCADE ON UPDATE CASCADE
but these two are not, and should be deleted.
CONSTRAINT tblSB_ibfk_1
FOREIGN KEY (InterviewID)
REFERENCES tblinterviewrecord (InterviewID)
ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT tblSB_ibfk_2
FOREIGN KEY (CoderID)
REFERENCES tblinterviewrecord (CoderID)
ON DELETE CASCADE ON UPDATE CASCADE

MySQL Foreign constraing inconsistencies

We're having weird errors on our production environment.
The error is:
MySQLIntegrityConstraintViolationException:
Cannot add or update a child row:
a foreign key constraint fails
('MSeHA_BARTLETT'.'document_version',
CONSTRAINT 'document_version_ibfk_1'
FOREIGN KEY ('document_id')
REFERENCES 'document' ('id')
ON DELETE CASCADE ON UPDATE CASCADE).
On SQL:
INSERT INTO 'document_version' SET
'document_id'='2002069',
'type_id'='2',
'subtype_id'='119091',
'status_id'='4',
'event_timestamp'='2012-02-08 15:02:00',
'provider_id'='1056'
ON DUPLICATE KEY UPDATE
'id'=LAST_INSERT_ID('id') ,
'type_id'='2',
'subtype_id'='119091',
'status_id'='4',
'provider_id'='1056'
With my knowledge of mysql and foreign keys, i had a few assumptions.
the table was locked. I used the cli to do this manually via locking/unlocking tables mid transaction, however it just waited patiently until the table was unlocked and finished...so no go.
so document_version is referencing document which has to be unique. Maybe 2 transactions at the same time try to insert the same document and mysql would give back different ids. Thsi would mean one would work fine, but the 2nd transaction would try to finish, but document would fail unique key constraints, making the document_id invalid? Thus failing the foreign key? Again, I re-enacted this via cli by starting 2 transactions, and letting them both insert the same row into document. Again mysql waited patiently on transaction #2 until the 1st transaction finished before letting it proceed and errored. Not the problem.
I'm at a loss. Any ideas are appreciated.

Adding foreign key to existing table gives error 1050 table already exists

I've a table CustomizationSet with the columns:
customization_set_guid (which is a non-nullable guid and also the primary key)
creator_account_guid
and a few others
And a table with existing data Registration with the columns:
registration_id (an int and the primary key)
customization_set_guid (also a guid (so a char(36)) which is nullable, and all entries are currently null)
and a few other columns
When I try and run
ALTER TABLE Registration ADD FOREIGN KEY
(
customization_set_guid
) REFERENCES CustomizationSet (
customization_set_guid
);
in MySQL Workbench, it gives the error 1050Table '.\dbname\registration' already exists.
If I try to use the UI to add the foreign keys with the Foreign Keys tab of the Alter Table Dialog, and choose CustomizationSet as the referenced table, it doesn't let me choose customization_set_guid in the list of columns.
I'm really not sure why it won't let me add this foreign key. I've just successfully created foreign keys between tables I just added. The Registration table has existed for awhile...
I got the same error, and it was due to the fact that the foreign key already existed. What you want is just to add the constraint:
ALTER TABLE Registration
ADD CONSTRAINT idx_Registration_CustomizationSet
FOREIGN KEY (customization_set_guid)
REFERENCES CustomizationSet(customization_set_guid);
It looks like there is a bug report for this at MySQL located here:
MySQL Bug 55296
In the end, I guess they upgraded their server and it fixed the issue. From reading it, I'm not sure though. They did have some workarounds like putting in constraint names/changing them. If you think this is the same, I would request that the bug is reopened.
At one point, they mention the types didn't match and workbench was responding with the wrong error (it should have been an errno 150, or errno 121). You can see the causes for those errors here:
MySQL Foreign Key Errors and Errno 150
So a team member figured this out. The one table was set with the type utf8_general, and another was set to the type default. I didn't think this was an issue, since the default is utf8_general, but apparently mysql just looks at the type names and not the underlying type.
I got the same error, and since my case wasnt mentioned yet, i ll post this answer and hopefully it may save somebody's time!
My two tables engines, where different.
The one was InnoDB, and the other MyIsam.
To change the engine of a table:
choose table, hit alter table, and then to hit that double arrow at
the right-most of the Workbench(so it will point upwards).
Now change the engine!
Check the Storage Engine type for CustomizationSet table.
I had a same issue but i could solve it by changing engine type to
InnoDB , because few types don't support foreign key constraints.
Not sure about the table already existing, but the reason it's not letting you choose the column you want is most likely due to the columns not being the same type. Check to ensure they are both the same type, same length, and have all the same options.
I'm not sure if it's a typo but shouldn't be
ALTER TABLE Registration ADD FOREIGN KEY
(
customization_set_guid
) REFERENCES CustomizationSet (
customization_set_guid
);
be something like
ALTER TABLE Registration ADD FOREIGN KEY
customization_set_guid_fk (customization_set_guid)
REFERENCES CustomizationSet (customization_set_guid);
I had a similar problem and in the end it was a problem of Integrity Constraint.
The Foreign Key column was referencing a foreign column that didnt
exist.
Try run the following to test whether this is the case:
select r.customization_set_guid, c.customization_set_guid
from Registration r
right join CustomizationSet c
on
r.customization_set_guid = c.customization_set_guid
where isnull(c.customization_set_guid);
When using MysqlWorkbench the error is misleading. My issue was that I was trying to add a foreign key constraint on table that already had rows and one of the rows was empty (did not meet the FK constraint. Instead of complaining that constraint will fail if applied, MysqlWorkbench reported that table exists.
Removing the offending row fixed (or adding and constraint acceptable value to the field) solved the problem.