I’ve a table with unique constrain on 3 columns:
PROBLEM:
Let’s say one row is
col5 col7 col9
lemon orange apple
if I try to modify that very same row to (just update to capital letter):
col5 col7 col9
lemon Orange apple
I get the error Duplicate entry lemon-Orange-apple. Basically mysql compares the proposed modification, not just to the other rows of the table, but also to itself, the modified row (before the modification).
After some troubleshooting, I believe it’s related to LONGTEXT… but not sure how to solve it…
QUESTION
Is there a way to keep the table/columns case insensitive, but let understand mysql that I’m just modifying a row, so it doesn’t have to compare the row values to itself (the modified row)?
UPDATE (more details)
Is anybody able to reproduce this problem?
Server version: 10.4.17-MariaDB
After running SHOW CREATE TABLE this is the result:
CREATE TABLE `mytable`
( `post_ID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'my comment',
`col1` varchar(255) DEFAULT NULL COMMENT 'unique or NULL',
`col2` varchar(255) NOT NULL,
`col3` int(11) DEFAULT NULL,
`col4` int(11) DEFAULT NULL COMMENT 'CONSTRAIN: Accepts only NULL and post_ID',
`col5` longtext NOT NULL,
`col6` longtext NOT NULL,
`col7` longtext NOT NULL,
`col8` longtext NOT NULL,
`col9` longtext NOT NULL,
`col10` longtext NOT NULL,
PRIMARY KEY (`post_ID`), UNIQUE KEY `col1` (`col1`),
UNIQUE KEY `col5` (`col5`(255),`col7`(255),`col9`(255)) USING HASH COMMENT '!!!These columns together MUST be unique!!!',
KEY `key_1` (`col3`), KEY `key_2` (`col4`) )
ENGINE=InnoDB AUTO_INCREMENT=120 DEFAULT CHARSET=utf8mb4
Insert test data:
INSERT INTO `mytable`
(`post_ID`, `col1`, `col2`, `col3`, `col4`, `col5`, `col6`, `col7`, `col8`, `col9`, `col10`)
VALUES (NULL, NULL, '', NULL, NULL, 'apple', '', 'orange', '', 'apple', '');
Try to Update orange to Orange (just by typing the word Orange into phpMyAdmin field):
UPDATE `mytable` SET `col7` = 'Orange' WHERE `mytable`.`post_ID` = 120
Error:
#1062 - Duplicate entry 'apple-Orange-apple' for key 'col5'
TRIED SOLUTIONS
I tried to modify collation to utf8mb4_bin or latin7_general_cs (as proposed on other questions) for CaSe sEnSiTivE comparisons; it solves the problem of modify only cApS, but it doesn’t work for me because all searches became CaSe sEnSiTivE (obviously) and when I search the table for "orange" it will not find "Orange".
Tried also to alternate make table utf8mb4_bin and columns utf8mb4_general_ci (and viceversa), but with no luck. Same problems.
After some troubleshooting, I believe it’s related to LONGTEXT… but not sure how to solve it…
2
Answers
[SOLVED!!]
By luck and chance, problem is solved!
Not sure how, but these are the steps I did:
[at this step still not working, but useful for next steps]
Brute/Force Restart the server (actually the battery died :o !!)
in phpMyAdmin: Optimize Table (in the hope that this was rebuilding the index)
TA DAAA! Now we are back on business : ) !
Thanks to everybody for your support!
MySQL 8.0.13 supports functional indexes. So, you can do what you want using a unique index:
In older versions of 8.0, you can mimic this by creating computed columns and then creating an index on those columns.
Here is a simpler example using only one column.