MySQL
do MySQL does not allow functions in the keys, only the whole value of the column references. So if you want to restrict by a UNIQUE key, you need another column that shouldwould contain only the year and month for the event. The easiest and most straightforward approach is to reduce the date
value to something like YYYY-MM-01
. If you have used the mysql
are using MySQL 5.7 or newer, you can declare that column 'generated'as generated and define an expression converting the function that reduce day-of-month part to the constant 01 value.
+---------+-----------+------------+------------+
| user | product | date | rdate |
+---------+-----------+------------+------------+
| 1 | 1 | 2018-09-03 | 2018-09-01 |
| 1 | 2 | 2018-09-03 | 2018-09-01 |
| 1 | 2 | 2018-08-28 | 2018-08-01 |
+---------+-----------+------------+------------+
And now you can create the UNIQUE INDEX 'permonth' (user, product, rdate)UNIQUE INDEX permonth (user, product, rdate)
. This is the uniqnessuniqueness established on the physical level.
On the logical level uniqnessuniqueness can be achieved by (at least) two common ways.
First, you can define the triggera BEFORE INSERT
trigger that would perform extended comparison of the dates and decline to insert thea duplicate. But triggers are not a very clean and easy tool because of their implicitness, and my advise is to avoid triggers asif possible.
The more robust way is to wrap the insert statement into thea stored routine and perform call SafeVoteInsert( userID, productID, date )
instead of plain INSERT vote VALUES ...
.