Good morning,
I have an application where the user ids were stored lowercase.
Some batch import, in the user table some users stored a uppercase
id, and for some applicative logic, in other tables that have a
foreign key to the user table, their user ids are stored lowercase.
MySQL didn't throw any error probalby because the collation used is
"case insensitive".
My problem is that the application is Java and java strings are case
sensitive, so now I want to set user ids to lowercase EVERYWHERE.
I supposed that I could execute with ease these commands:
- update mytable1 set USER_ID = LOWER(USER_ID);
- update mytable2 set USER_ID = LOWER(USER_ID);
- update mytable3 set USER_ID = LOWER(USER_ID);
But for some tables I got some Foreign key constraint to throw an
error. (butwhy they didn't throw an error on the insert but just on
the update???)
And if I try to disable foreign key checks during these updates, I get
some "duplicate key" errors where USER_ID is a part of composite key
with other columns. (but I don't have any data that might cause a real
duplicate key error just changing the case of one column)
Have you any idea how to solve this situation without
stopping/recreating the DB? (it's a production environment)
Thanks
Comments
Re: Foreign key and uppercase / lowercase values
By Ananda Kumar at 05/16/2012 - 06:42why are not using any where condition in the update statment
Re: Foreign key and uppercase / lowercase values
By Shawn Green (MySQL) at 05/16/2012 - 11:35Hello Ananda,
On 5/16/2012 6:42 AM, Ananda Kumar wrote:
WHERE clauses are not required. Performing a command without one will
affect ever row on the table.
Have you tried ?
SET foreign_key_checks=0;
<a href="http://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_foreign_key_checks" title="http://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_foreign_key_checks">http://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysv...</a>
If that does not work, you would need to first un-create your Foreign
Key relationships, update your key values (the USER_ID fields), then
re-create your Foreign Key relationships.
Regards,
Re: Foreign key and uppercase / lowercase values
By GF at 06/12/2012 - 09:20Good morning.
The application is Java.
The database version is : Server version: 5.1.49-3 (Debian)
This is an example of the problem:
mysql> show variables like '%colla%';
+----------------------+-----------------+
| Variable_name | Value |
+----------------------+-----------------+
| collation_connection | utf8_unicode_ci |
| collation_database | utf8_unicode_ci |
| collation_server | utf8_unicode_ci |
+----------------------+-----------------+
3 rows in set (0.00 sec)
mysql> update MY_TABLE set USER_ID = LOWER(USER_ID) where USER_ID = 'XXYYZZ';
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign
key constraint fails etc. etc.
Since the used collation is "_ci" (I suppose it means case
insensitive) I don't understand why it is giving an error trying to
change a value to lowercase.
I did try on a test environment to use the trick (SET
foreign_key_checks=0;) but I don't understand why I should disable the
foreign key checks when I am NOT violating them.
The application was able to write in some other tables the USER_ID in
lowercase. And I think that was an expected behaviour because the
collation is case insensitive!
Why now I can't set some values from uppercase to lowercase?
There is not any weird character in the USER_ID column, just from A to Z.
Thank you.
On Wed, May 16, 2012 at 5:35 PM, Shawn Green <shawn.l. ... at oracle dot com> wrote:
RE: Foreign key and uppercase / lowercase values
By Rick James at 06/13/2012 - 19:40To discuss this further, please provide SHOW CREATE TABLE for the table in question and the table(s) tied to it via FOREIGN KEYs.
Re: Foreign key and uppercase / lowercase values
By GF at 06/15/2012 - 03:44I think the following might give complete information (I removed some
columns not involved in the problem)
Server version: 5.1.49-3 (Debian)
SET collation_connection = utf8_unicode_ci;
Query OK, 0 rows affected (0.00 sec)
show variables like '%colla%';
+----------------------+-----------------+
| Variable_name | Value |
+----------------------+-----------------+
| collation_connection | utf8_unicode_ci |
| collation_database | utf8_unicode_ci |
| collation_server | utf8_unicode_ci |
+----------------------+-----------------+
3 rows in set (0.00 sec)
show variables like '%char%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)
select USER_ID from TBL_USER where USER_ID = 'GIUSEPPE';
+----------+
| USER_ID |
+----------+
| GIUSEPPE |
+----------+
1 row in set (0.00 sec)
select USER_ID from TBL_USER where USER_ID = 'giuseppe';
+----------+
| USER_ID |
+----------+
| GIUSEPPE |
+----------+
1 row in set (0.00 sec)
update TBL_USER set USER_ID = LOWER(USER_ID) where USER_ID = 'GIUSEPPE';
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign
key constraint fails (`myschema`.`TBL_COMMENT`, CONSTRAINT
`FK4F6E52581590B46E` FOREIGN KEY (`USER_ID`) REFERENCES `TBL_USER`
(`USER_ID`))
| TBL_USER | CREATE TABLE `TBL_USER` (
`USER_ID` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
<< cut >>
PRIMARY KEY (`USER_ID`),
<< cut >>
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
| TBL_COMMENT | CREATE TABLE `TBL_COMMENT` (
<< cut >>
`ID` bigint(20) NOT NULL AUTO_INCREMENT,
<< cut >>
`USER_ID` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
<< cut >>
PRIMARY KEY (`ID`),
<< cut >>
KEY `FK4F6E52581590B46E` (`USER_ID`),
<< cut >>
CONSTRAINT `FK4F6E52581590B46E` FOREIGN KEY (`USER_ID`) REFERENCES
`TBL_USER` (`USER_ID`),
<< cut >>
) ENGINE=InnoDB AUTO_INCREMENT=7876 DEFAULT CHARSET=utf8
COLLATE=utf8_unicode_ci |
RE: Foreign key and uppercase / lowercase values
By Rick James at 06/15/2012 - 13:00You are very close to a standalone test case. Please create such. Then post it on bugs.mysql.com .
Re: Foreign key and uppercase / lowercase values
By GF at 06/18/2012 - 04:09<a href="http://bugs.mysql.com/bug.php?id=65648" title="http://bugs.mysql.com/bug.php?id=65648">http://bugs.mysql.com/bug.php?id=65648</a>
On Fri, Jun 15, 2012 at 7:00 PM, Rick James <rjames@yahoo-inc.com> wrote:
Re: Foreign key and uppercase / lowercase values
By Shawn Green (MySQL) at 06/15/2012 - 15:05On 6/15/2012 1:00 PM, Rick James wrote:
Before he submits a test case, he should also review
<a href="http://bugs.mysql.com/bug.php?id=27877" title="http://bugs.mysql.com/bug.php?id=27877">http://bugs.mysql.com/bug.php?id=27877</a>
<a href="http://dev.mysql.com/doc/refman/5.5/en/news-5-5-21.html" title="http://dev.mysql.com/doc/refman/5.5/en/news-5-5-21.html">http://dev.mysql.com/doc/refman/5.5/en/news-5-5-21.html</a>
This has been a well-discussed problem both inside and outside the MySQL
development processes.
Regards,
RE: Foreign key and uppercase / lowercase values
By Rick James at 06/15/2012 - 15:19Those refer _only_ to German 'ß' LATIN SMALL LETTER SHARP S. The example GF gave did not involve that character.
To my knowledge, that is the only case where MySQL changed a collation after releasing it.
Re: Foreign key and uppercase / lowercase values
By Shawn Green (MySQL) at 06/15/2012 - 16:40On 6/15/2012 3:19 PM, Rick James wrote:
Yes, it has been the only occurrence. However, the esset (sharp S) is
just one example of the alternative spelling letters that were affected
by the collation change. Thorn, the AE ligand, and many others fall into
that same category.
Regards,
Re: Foreign key and uppercase / lowercase values
By walter at 06/15/2012 - 18:34At 16.40 15/06/2012 -0400, Shawn Green wrote:
ß = Eszett (which in German is the spelling of SZ, although it originated as a double S ligature (U+017F + s) - SZ comes from its "sharp" pronunciation).
The absence of an uppercase equivalent and its ligature behavior more evident than for other ligatures (although this has changed with the 1996 reform of German writing) have caused more than a headache to people dealing with charsets and collations.
Speaking of collations, I found this website useful (especially when I had to compare collations of different RDBMSs):
<a href="http://www.collation-charts.org/" title="http://www.collation-charts.org/">http://www.collation-charts.org/</a>
Sorry for being OT, but every now and then it's worthwhile to share also some OT knowledge.
Walter Tross
RE: Foreign key and uppercase / lowercase values
By Rick James at 05/16/2012 - 11:27What language(s) are involved? What collation are you using now?
The German sharp-S does not work well with case folding.
utf8_unicode_ci could have stuff folding together.
Etc.
If you can find a USER_ID that is causing trouble, please provide
SELECT HEX(USER_ID) FROM ... WHERE ...
for further discussion.
Instead of changing the data, why not do the casefolding as you SELECT into Java?