views:

807

answers:

4

In postgres we have a constraint defined that essentially allows us to limit the number of entries in a table with a certain value to one. We created this constraint:

create unique index list$default$uk on list_group(visitor_uid) where list_type = 'default';

Which means that the unique constraint is only applied when the list_type='default' so that there can only be one 'default' list per visitor in the table.

It looks like MySql doesn't support the additional where on the unique constraint. Is there another way to support this in the database schema for MySQL?

+1  A: 

MYSQL doesn't support such types of constraints.

You should use stored procudures for inserting data instead, so you can do some checking and validation.

Why don't you define your default as such that it must have 1 as primary key? This way a normal unique constraint on the pk would be enough already.

If nothing fits to you, you could also consider changing your data model.

codymanix
A: 

Actually it exists. Most contraints depend on the table Engine. I think InnoDB supports this.

To do it, you have to add a UNIQUE index with the unique combination:

ALTER TABLE visitor ADD UNIQUE unique_default_visitor( visitor_uid, list_type );
streetpc
yeah - not quite. The problem with what you have there is that each list_group would have to have a unique list_type for each visitor. We don't want that. What we are trying to accomplish is to only allow each visitor to have a single list group with list_type='default'. The for other list_types it doesn't matter if there are duplicates.
harmanjd
ho, right. Then I don't know a way to do this in MySQL, since CHECK constaint aren't supported by storage engines yet: http://forums.mysql.com/read.php?136,152474,240479#msg-240479. But, like codymanix said, I'd rather modify the data structure if enforcing this rule in the DB is essential.
streetpc
A: 

I supposed you'd have to write a trigger to check for it.

rfusca
A: 

I never use MySQL but maybe you can create an index like this:

CREATE UNIQUE INDEX list$default$uk ON list_group ((CASE WHEN list_type='default' THEN NULL ELSE visitor_uid END));

Explanation: A unique index should not care about NULL values. Therefore, make sure the index expression returns NULL for every row where list_type <> 'default'.

Martin Torhage
Looks similar to what we did for oracle (with a decode). But this is what I got when trying it: mysql> CREATE UNIQUE INDEX list$default$uk ON list_group ((CASE WHEN list_type='default' THEN NULL ELSE visitor_uid END)); ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(CASE WHEN list_type='default' THEN NULL ELSE visitor_uid END))' at line 1 mysql>
harmanjd