2

I keep finding myself writing queries to avoid inserting when there are duplicates - things like

select * from foobar where bar=barbar and foo=foofoo

and then checking in PHP with mysql_num_rows() to see if the number of results is > 0 to determine whether to go forward with my insert.

EDIT: for instance, let's say a user wants to send an invitation to another user. I want to make sure that in my invitations table, I don't add another entry with the same pair invited_id AND game_id. so this requires some sort of check.

this feels inefficient (and slightly dirty). is there a better way?

2
  • can you pls. elaborate further so I am able to give you proper answer. Commented Nov 25, 2011 at 9:50
  • 2
    The obvious answer is a unique index on columns foo, bar - have you considered that? Commented Nov 25, 2011 at 9:53

3 Answers 3

5

What about unique index?

A UNIQUE index creates a constraint such that all values in the index must be distinct. An error occurs if you try to add a new row with a key value that matches an existing row. For all engines, a UNIQUE index permits multiple NULL values for columns that can contain NULL.

http://dev.mysql.com/doc/refman/5.1/en/create-table.html

EDIT:

A column list of the form (col1,col2,...) creates a multiple-column index. Index values are formed by concatenating the values of the given columns.

http://dev.mysql.com/doc/refman/5.0/en/create-index.html

Sign up to request clarification or add additional context in comments.

2 Comments

right but it is on two or more rows. I don't want it to fail on either column getting a duplicate value, only when BOTH do
A unique index on the two columns requires that the combination of the two is unique. so "foo,foo" , "foo,bar" , "bar,foo" and "bar,bar" would all co-exist.
2

In this case, create a unique index on (bar, foo), so that the insert fails on duplicated value. You just need to handle the exception in php. This way, the code is cleaner and faster.

2 Comments

right but it is on two or more rows. I don't want it to fail on either column getting a duplicate value, only when BOTH do
That's exactly the case. If the unique index is on column set (bar, foo), then the insert fails if the combination of values (bar value, foo value) is a duplicate, but not when bar alone or foo alone is a duplicate.
1

Just use a UNIQUE key on the columns and the INSERT IGNORE statement to insert new rows (duplicate rows are IGNORED).

Beware that the UNIQUE key may not exceed a 1000 bytes, meaning that the potential number of bytes contained in the fields foo and bar together may not exceed a 1000 bytes. If this creates a problem, just MD5 the CONCATENATED values into its own column at insert time, like (in PHP) md5($foo.$bar), and set the unique key to that column.

CREATE TABLE  `test_unique` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `foo` varchar(45) default NULL,
  `bar` varchar(45) default NULL,
  PRIMARY KEY  (`id`),
  UNIQUE INDEX `Unique` (`foo`,`bar`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

INSERT IGNORE INTO `test_unique` VALUES
(1, 'foo1', 'bar1'),
(2, 'foo2', 'bar2');

INSERT IGNORE INTO `test_unique` VALUES
(2, 'foo2', 'bar2');

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.