Rodrigo Chaparro
Rodrigo Chaparro

Reputation: 55

MySQL unique constraint of two columns only if second column is a specific value

Hi I have a MysQL table in which I save the clients

In one column I save the IP Address,

In other column I set if the client is Active or Not Also I save the name, mail, etc...

If one client left, we just set the Active column to 0, (to keep Payments history and so), when new client arrives we can reassign the same IP

Is there a way to create a UNIQUE constraint to allow just one IP that is ACTIVE ?

example

IP    |   ACTIVE  |   DATE
---------------------------------
102   |      1    |    2017-10-12
103   |      1    |    2017-10-12
103   |      0    |    2017-10-13
103   |      0    |    2017-10-09

So It can be multiples rows with the IP and 0 but only one with the IP and 1

I'm thinking about a trigger before INSERT, UPDATE that do a SELECT and verify if there is no other row with that IP and 1 in ACTIVE

Suggestions?

Upvotes: 4

Views: 1753

Answers (2)

Michael - sqlbot
Michael - sqlbot

Reputation: 178974

Use the values 1 and NULL instead of 1 and 0.

You can then add UNIQUE KEY (ip, active) to the table and only one row per IP combination with a value of 1 will be permitted, but infinite rows with NULL will not violate the unique constraint.

Remember that NULL = NULL is not true, because NULL is not a value. It is a marker signifying the absence of a value. Two absent values cannot be said to be identical, so multiple rows with NULL for the same value of ip will not be considered duplicates, so they can't violate a unique constraint.

Aside: Noting that NULL = NULL is not true, as mentioned above, it is just as important to note that, it is not false, either. Similarly, NULL != NULL is also neither true nor false, because -- by definition -- a lack of a value is not something that can properly be compared to anything, including another lack of a value.

Upvotes: 3

Peter Abolins
Peter Abolins

Reputation: 1539

Alternative 1

Instead of using 0 to indicate not active, why don't you use a negative number? That way, you could maintain uniqueness on the IP / Active pair of columns, and only the record with Active = 1 would be considered active.I am not sure what your logic is in terms of in-activating, but essentially, you would just pick a negative number one smaller than the existing one (or -1 if it is the first one) to update the record with.

Alternative 2

Dispense with the Active column altogether, and create another table to hold IP history. So... in your main table, the uniqueness constraint is on the IP address. In your history table, you can have a uniqueness constraint on the IP address and the date it became historical.

EDIT

Based on the comment by @MichelFeldheim, I would suggest that you include the user email address as part of the uniqueness constraint. Basically meaning that each unique user would be allowed one active IP address. It would also allow more than one active user per IP address (or organization, eg).

Upvotes: 3

Related Questions