Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enforce unique values across two tables

Tags:

indexing

mysql

Is it possible to enforce uniqueness across two tables in MySQL?

I have two tables, both describing users. The users in these tables were for two different systems previously, however now we're merging our authentication systems and I need to make sure that there are unique usernames across these two tables. (it's too much work to put them all into one table right now).

like image 438
nickf Avatar asked Jan 03 '09 07:01

nickf


People also ask

Can a same constraint be used in 2 tables?

Yes you can do this from this example i didn't test it, but it should work.

Can we apply unique key constraint on multiple columns?

Both the UNIQUE and PRIMARY KEY constraints provide a guarantee for uniqueness for a column or set of columns. A PRIMARY KEY constraint automatically has a UNIQUE constraint. However, you can have many UNIQUE constraints per table, but only one PRIMARY KEY constraint per table.

Can 2 tables reference each other?

When you create two tables that are related to each other, they are often related by a column in one table referencing the primary key of the other table - that column is called the "foreign key".

Can a table have 2 unique indexes?

Provided that the data in each column is unique, you can create both a unique clustered index and multiple unique nonclustered indexes on the same table. Unique indexes ensure the data integrity of the defined columns.


2 Answers

You can't declare a UNIQUE constraint across multiple tables, and MySQL does not support CHECK constraints at all. But you can design a trigger to search for the matching value in the other table. Here's a test SQL script:

DROP TABLE IF EXISTS foo;
CREATE TABLE FOO (username VARCHAR(10) NOT NULL);

DROP TABLE IF EXISTS bar;
CREATE TABLE BAR (username VARCHAR(10) NOT NULL);

DROP TRIGGER IF EXISTS unique_foo;
DROP TRIGGER IF EXISTS unique_bar;

DELIMITER //

CREATE TRIGGER unique_foo BEFORE INSERT ON foo
FOR EACH ROW BEGIN
  DECLARE c INT;
  SELECT COUNT(*) INTO c FROM bar WHERE username = NEW.username;
  IF (c > 0) THEN
    -- abort insert, because foo.username should be NOT NULL
    SET NEW.username = NULL;
  END IF;
END//

CREATE TRIGGER unique_bar BEFORE INSERT ON bar
FOR EACH ROW BEGIN
  DECLARE c INT;
  SELECT COUNT(*) INTO c FROM foo WHERE username = NEW.username;
  IF (c > 0) THEN
    -- abort insert, because bar.username should be NOT NULL
    SET NEW.username = NULL;
  END IF;
END//

DELIMITER ;

INSERT INTO foo VALUES ('bill');  -- OK

INSERT INTO bar VALUES ('bill');  -- Column 'username' cannot be null

You also need similar triggers ON UPDATE for each table, but you shouldn't need any triggers ON DELETE.

like image 198
Bill Karwin Avatar answered Oct 14 '22 20:10

Bill Karwin


the best way to do this is to declare another table with the unique columns, and have the multiple tables reference these tables

like image 38
Mnyikka Avatar answered Oct 14 '22 19:10

Mnyikka