Question

I have a table for detecting views of articles - it should have one unique row for each article_id&&NULL&&IP when noone is logged in and unique row for each article_id&&loggedInUser&&IP.
So I thought that when noone is logged in I will just add a NULL instead of user_id. But MySQL suprised me - when I've added UNIQUE KEY like article_id&&user_id&&IP it worked fine for logged in users, but if no user logged in it started to add rows like (e.g.):

article_id   |   user_id   |   IP
   5               NULL      192.168.3.50
   5               NULL      192.168.3.50
   5               NULL      192.168.3.50
   5               NULL      192.168.3.50

This doesnt seem much unique - I know it is caused by NULL but how to solve this? Should I just rely on the fact that no user will have user_id "0"?

Thanks.

Was it helpful?

Solution

This is intentional and is documented:-

http://dev.mysql.com/doc/refman/5.0/en/create-index.html

A UNIQUE index creates a constraint such that all values in the index must be distinct. An error occurs if you try to add a new row with a key value that matches an existing row. This constraint does not apply to NULL values except for the BDB storage engine. For other engines, a UNIQUE index permits multiple NULL values for columns that can contain NULL. If you specify a prefix value for a column in a UNIQUE index, the column values must be unique within the prefix.

While you could use a user id of 0 I would be concerned that you might have 0 used elsewhere when you do not want a record found. For example I often just convert any input id field to an integer and if someone has tried to hack around and enter a string this might well be converted to 0. In such a case I wouldn't really want the zero to be meaningful.

I would possibly be tempted to set up a 'none' userid to use in this situation.

OTHER TIPS

Your current solution is going to grow huge very quickly and provide very little benefit. If it were me I would just rely on analytics to handle this sort of data. If you really want this it can be done very easily by adding one more field to your table for a count. When you are about to add a row to this look for one which already exists. If one does then instead of adding a new record just update the current record and increment the count instead. This will provide the exact same information in much less space.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top