Tripton
Tripton

Reputation: 43

Mysql - Preventing duplicate entries of combined columns with Unique Index

I have an issue with duplicate entries in a database and due to the nature of the problem the easiest way to fix it would be to remove current duplicate rows and prevent further duplicates from being added .

Here is the table structure :

| a     | b      |  c | 

 user    url1      token1
 photo   url1      token2
 action  action1   token3 
 user    url1      token4   
 photo   url1      token5
 action  action2   token6 

I want to prevent duplicate entries only when 2 columns are duplicated, in this case a and b .

So here we have user | url1 and photo | url1 duplicated twice.

I want to prevent any further duplicates from being added when both columns match another row at same time but the queries I found so far will consider each column separately and preventing any further duplicates to be added to any of them .

Can I achieve this with a mysql query using unique index ?

I tried using the following code :

Using ALTER TABLE `targets` ADD UNIQUE (
`a` ,
`b`
);

Upvotes: 1

Views: 2090

Answers (3)

Tripton
Tripton

Reputation: 43

Thanks for the replies guys, but I found the solution in the meantime and it was much simpler !

It's called unique composite key and it allows to do exactly what I wanted :

ALTER TABLE targets ADD UNIQUE KEY `uidx` (a, b, c);

Problem fixed :)

Upvotes: 1

FanoFN
FanoFN

Reputation: 7114

Your question:"Can I achieve this with a mysql query using unique index ?"

Answer is 100% yes.

There are two ways of creating index:

1. CREATE UNIQUE INDEX index_name
ON table_name (column1, column2, ...);

2. ALTER TABLE table_name 
ADD UNIQUE index_name (column1, column2, ...);

However, this will only work if your table doesn't have existing duplicate data. Otherwise you'll receive an error message like this:

Query: CREATE UNIQUE INDEX index_name ON targets (a, b)

Error Code: 1062
Duplicate entry 'photo-url1' for key 'index_name'

Therefore, you need to:

  1. create a new empty table similar to your targets table.
  2. create unique index.
  3. INSERT IGNORE data from the old table.
  4. Rename targets to targets_old and targets_new to targets.

Example:

CREATE TABLE targets_new LIKE targets;

CREATE UNIQUE INDEX index_name
ON targets_new (a, b);

INSERT IGNORE INTO targets_new SELECT * FROM targets;

RENAME TABLE targets TO targets_old;
RENAME TABLE targets_new TO targets;

Upvotes: 1

Winston L
Winston L

Reputation: 61

i don't think you can specify a unique doublet property.

edit : mention by Salmon : An index specification of the form (key_part1, key_part2, ...) creates an index with multiple key parts

https://dev.mysql.com/doc/refman/8.0/en/create-index.html#create-index-unique

you could try :

SELECT * FROM database1.table1 WHERE a='user' AND b='url1';

if got return a number of rows then don't add to the database.

this way you can fully control what goes into the database instead of letting the table automatically ignore the fail condition.

Upvotes: 0

Related Questions