简体   繁体   中英

MySQL Unique Constraint based on column value

Let's say I have a table like this:

CREATE TABLE dept (
  id     VARCHAR(255) NOT NULL PRIMARY KEY,
  code   VARCHAR(255) NOT NULL,
  active BIT          NOT NULL,
  ...
);

Problem:

I want to add a unique constraint on code column. But it should be applied only if active is set to true (uniqueness should be checked only among active records). There can be many records with active = false and the same code so I can't use constraint on multiple columns.

What I tried:

I haven't found any references in the documentation proving that such constraint is possible, but I know it is possible in other databases using unique function-based indexes.

Of course I can write a trigger that will check the invariant on every add/update operation, but I hope there is more efficient solution.

I'm using MySQL 5.7.15.

This simply isn't possible in MySQL, I'm afraid.

I have come "close" to solving this in the past by having a uniquely constrained column which is nullable (replacing both the active and code fields). When NULL - it's "inactive", when anything other than NULL - it has to be unique.

But that doesn't precisely solve the problem you're asking. (Perhaps something better can be suggested if you could update your question to include the bigger picture?)

Otherwise read/write to the table through a stored procedure or - as you've suggested yourself - do something inelegant with triggers.

To solve your problem you need use CHECK clause but it MySQL don't support it. From doc:

The CHECK clause is parsed but ignored by all storage engines. See Section 13.1.18, “CREATE TABLE Syntax”. The reason for accepting but ignoring syntax clauses is for compatibility, to make it easier to port code from other SQL servers, and to run applications that create tables with references.

So you can do this only by check data on application level or insert/update rows in this table by stored procedures.

I sorry this does not really a direct answer your question but:

Maybe you are better off with a different table design? The fact that something you want to do is not supported by your RDBMS is always a strong evidence that you are using it wrong.

Have you thought about creating a dept and an dept_history table, dept containing only the active records? That would solve your problem with the unique constraint.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM