patternsqlMinor
MySQL unique index only if column has specific value
Viewed 0 times
uniquecolumnvaluehasmysqlspecificindexonly
Problem
I have a table where I use a boolean column
However, if the user wants to add an item with a slug that is the same as the slug of a deleted record, it should be allowed. I tried doing this with a UNIQUE index on
So actually I need a constraint which is only applied for the records with
I've seen the question Custom unique column constraint, only enforced if one column has a specific value, however, it only applies to PostgreSQL and I'm on MySQL. Is there a way in MySQL to do this, or a nice workaround?
I thought of making
However, this would mean the interfacing software (written in PHP) would have to check what it could put in the
Anyway, is there a pure MySQL way to do this?
Note: of course, such a scheme will have difficulties when the user requests to restore a previously deleted item when its slug is already assigned to a new record. This will have to be done in the interfacing code in any case.
deleted to signify whether a specific record has been 'deleted' by the user (meaning, it appears in the trash list instead of the normal list). These items all have slugs which should be unique. However, if the user wants to add an item with a slug that is the same as the slug of a deleted record, it should be allowed. I tried doing this with a UNIQUE index on
deleted and slug, however, this gives a problem if this item would get deleted: there should then be two items in the trash list with the same slug, which would give a constraint violation.So actually I need a constraint which is only applied for the records with
deleted=0I've seen the question Custom unique column constraint, only enforced if one column has a specific value, however, it only applies to PostgreSQL and I'm on MySQL. Is there a way in MySQL to do this, or a nice workaround?
I thought of making
deleted an integer instead of a boolean, where 0 would signify not deleted and any other number deleted. Then deleted items with the same slugs could have a different value in the deleted column.However, this would mean the interfacing software (written in PHP) would have to check what it could put in the
deleted column if a constraint violation occurs, and of course I'd prefer a pure MySQL solution. If I'm going to write this in the PHP code anyway, I'd rather change the slug value, for example, to prepend the id of the record to the slug when an item has been deleted - or, create a second table for the deleted records, where no such constraint exists.Anyway, is there a pure MySQL way to do this?
Note: of course, such a scheme will have difficulties when the user requests to restore a previously deleted item when its slug is already assigned to a new record. This will have to be done in the interfacing code in any case.
Solution
I had a similar question, and have a way to make it work, so if you don't mind the kludge, here it is:
Since MySQL allows multiple NULL values on a unique index, you can use
You would then create a composite unique index on [slug, deleted].
The table would look like this:
If using non-NULL to signify "not deleted" seems a bit iffy, so if you can, you could reverse the values and change the column name to "available" or something? :
Hope that helps
Since MySQL allows multiple NULL values on a unique index, you can use
NULL to indicate "deleted" and non-NULL value (42?) to indicated "not deleted". You would then create a composite unique index on [slug, deleted].
The table would look like this:
slug deleted
abcd 42 # This record is marked as not-deleted
abcd NULL # This record is marked as deleted
abcd NULL # This record is marked as deleted
xyz 42
xyz NULLIf using non-NULL to signify "not deleted" seems a bit iffy, so if you can, you could reverse the values and change the column name to "available" or something? :
slug available
abcd 42 # This record is marked as available
abcd NULL # This record is marked as not-available
abcd NULL # This record is marked as not-available
xyz 42
xyz NULLHope that helps
Code Snippets
slug deleted
abcd 42 # This record is marked as not-deleted
abcd NULL # This record is marked as deleted
abcd NULL # This record is marked as deleted
xyz 42
xyz NULLslug available
abcd 42 # This record is marked as available
abcd NULL # This record is marked as not-available
abcd NULL # This record is marked as not-available
xyz 42
xyz NULLContext
StackExchange Database Administrators Q#85966, answer score: 4
Revisions (0)
No revisions yet.