MySQL: Duplicate entry for key (Formerly "What does 'idx' mean?") - mysql

Update: After a lot of painful research, I've discovered what the problem actually is and updated the title to make a little more sense. I'll put my answer below.
Unfortunately, I'm not able to copy the query that's giving me this problem because it belongs to my company, so I'll have to keep my question very specific.
I have an INSERT INTO ... SELECT query that's returning this error:
Duplicate entry <gobbledygook> for key 'idx_<tablename>'
The tablename at the end is the correct name, but it has this weird idx_ prefix before it that's not a part of any of the tables I'm currently working with. What is that idx? Does it have something to do with the information_schema?
Update: Apparently, I need to clarify something: There is no column with idx in the name.

The numerous websearches didn't reveal much when I was trying to solve this problem, but I did finally figure it out (and JohnH's answer helped me to do this).
I finally discovered that "idx" is not something created by MySQL, but a name that someone else gave to the index. I have never come across a uniqueness constraint on an index that wasn't a key before, so I didn't know where that error came from.
This command showed all of the indices:
SHOW INDEX FROM <tablename>
And I was able to see that non-unique was set to 0 for this key.
To fix the problem, I was able to simply drop the index and recreate it, without adding a uniqueness constraint.
DROP INDEX idx_<tablename> ON <tablename>;
ALTER TABLE <tablename> ADD INDEX idx_<tablename> (<comma-separated columns>);
Whether or not removing the uniqueness constraint is a good idea remains to be seen, but it's also beyond the scope of this question.

"idx_" is a common prefix for index names.
You many have an index that does not allow duplicate values for the column values referenced by that index.

In my case the unique index had duplicate entries even though the column being indexed didn't. I can only think this was caused by a bug. Solution was
Stop the service that writes to the db
Drop the index
Recreate the index
(Do the operation that was previously failing)
Start the service
It's important if you are dropping an recreating an index that nothing can be given an opportunity to insert a duplicate entry while you are doing this. This is why I stopped the service that writes to the db.

Related

MySQL Create Table Statement Strange Errors

I am trying to run some basic CREATE TABLE statements for my Databases course project and am getting some strange errors.
When I create the table Manuf it runs fine, but when I try to create the next table, Order, using the same syntax, it does not work.
Also, when I try to create this table, Items, I get an errno: 150. I believe this has to do with my foreign key creation, but I am not exactly sure. Here is a screenshot of that.
I am fairly new to using MySQL so any advice would be greatly appreciated, thank you.
The error on the Order table is caused by ORDER being a reserved word. You can specify it as `Order` with the backticks, but it's better if you choose a different name altogether.
The error 150 is related to the foreign key. The keys must be absolutely identical - the exact same definition, or the FK will fail with error 150.
Also, there must be an available index with that key definition or one compatible (see Kai Baku's example in the comment on the MySQL manual page). The same fields indexed in a different order will fail.
To begin with, check how those keys are defined in the origin tables. For example:
test1 varchar(50) not null
test2 varchar(50)
will not be compatible. I think that even a different collation is enough to throw FK off kilter (but this I haven't checked. The rest I'm sure of, from my personal bitter unexperience).
UPDATE: I forgot to mention, if you use InnoDB tables and issue the SHOW ENGINE INNODB STATUS, the blurb that comes out will contain a much better explanation of why the FK failed, somewhere about one third from top.

MySQL constraint/trigger to prevent duplicated rows?

Is there a performance difference between using unique constraint and trigger to prevent duplicated rows in MySQL?
Monitor it. But well, the outcome should be obvious.
As the unique index exists specifically to enforce this constraint, it should be the first choice.
By using the trigger you would have to do additional operations to even check if there is the dataset (tablescan vs index lookup, or you set an index without constraint on the column but...), then react to it accordingly. So if there is nothing else you are trying to do (logging the failed attempt maybe), this would be unnecessary steps.

"Table already exists" when changing PK autoincrement in MySQL

I am quite new to MySQL and I have encountered a problem that I find quite puzzling. If I create a table with MySQL Workbench, when I set the PK I can choose it to auto-increment or not, as should be. However, if I change my mind later on, once the table has been created, I cannot alter the auto-increment flag any longer, as MySQL tells me that the "table already exists". That happens even if the table is empty.
The auto-generated SQL is as follows:
ALTER TABLE tablename
CHANGE COLUMN `ID` `ID` INT(11) NOT NULL AUTO_INCREMENT ;
and it fails with the error stated above. I have tried changing the algorithm and lock type, to no avail.
This does not happens in T-SQL or Oracle, for instance, so I fail to see a reason why it should fail in MySQL. Is there any way to fix this without having to drop and re-create the table?
Thanks.
From experience all the GUIs get a bit confused when you start changing primary keys, the number of error messages I've seen from SQL Server...
You don't need to drop the whole table, but it might be easiest to drop and then re-create the offending column.
Also, check out the MySQL dev docs, but I think either ALTER or MODIFY column are the two I'd go for and I'm not sure why the column name is there twice if you're not renaming it.
Ok, I discovered the culprit thanks to dbForge Studio. The same thing happens there, but this time the error is more explicit: I cannot change the auto-increment flag apparently because it is used as a foreign key on another table. I deleted the FK and then I was able to set the auto-increment.
Thank you all who helped me, I have learned some new things thanks to your comments.

Check for the respective data in a specific column and if not detected, then insert. Otherwise update

I need to insert new row into table foo. But before insert those data, I need to check there was already inserted a row for the respective user name. If there has been already inserted, then I need to update the current data with the new data.
I know to do this using PHP if condition. But I love to do this using MySQL functions/statements by just a one line. Please can anyone help me?
For the example, kindly use the following statement. It should be updated.
$in = "insert into foo(username, text) values('user-x', 'user-x-text')";
Mysql_query($in);
When searching for similar questions, I got this post: Similar question with an answer. But I was struggle to use that solution since I don't know, the process occur by that code snippet will get down the server resources like speed etc. Because this script will run about 20 times per user.
Thank you.
I think INSERT ... ON DUPLICATE KEY UPDATE should be able to work
Make username a UNIQUE index, it doesn't have to be a primary key
If I'm not mistaken, DUPLICATE KEY will run only when you have a collision in any of the columns you supply that is either a primary key or unique index. In your case, text column is neither so it will be ignored for collisions.
INSERT... ON DUPLICATE KEY UPDATE works on unique indexes as confirmed by the MySql docs

mysql with duplicate key

I tried searching online for this...I had a row that I inserted into the database. I removed it. The table has a Unique Key on a particular column. When I try to insert a new row with the same value for the unique key, it fails saying duplicate entry. However, there is no duplicate entry since the row is not there! Is there a way to reset this?
I would like the table to accept values that are unique to what is there right now. I tried to remove the unique key constraint from the table to see if that would work, however, when I added it back, it was having the same issue.
Maybe you perform dirty reading? and the deletion did not commit? try use the read commit option, I think it's called isolation level.