Background
I have an application in which users can send reviews for a product. Users can also edit previously submitted reviews or submit another for the same product.
I implement an auto save function that saves form data every X seconds. If the page is accidentally closed, the user can restore this "draft".
This is a simplified version of my table:
CREATE TABLE `review_autosave_data` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `review_id` int(11) unsigned DEFAULT NULL, `product_id` int(11) unsigned NOT NULL, `user_id` int(11) unsigned NOT NULL, `review` blob, `name` varchar(100) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `unique_index` (`product_id`, `user_id`), KEY `fk_review_autosave_data_review_id (`review_id`), KEY `fk_review_autosave_data_product_id (`product_id`), KEY `fk_review_autosave_data_user_id (`user_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
Keep in mind that only drafts are stored in this table, not actual reviews . If we are editing a review, review_id will point to that review. If we create a new review, this field will be NULL .
What works
This is my request to insert a new draft:
INSERT INTO review_autosave_data (review_id, product_id, user_id, review) VALUES (25, 50, 1, "lorem ipsum") ON DUPLICATE KEY UPDATE review = "lorem ipsum";
This is great for inserting new draft reviews. Indexes forbid the insertion of a new row in which product_id and user_id combinations already exist.
What does not work
My problem is to insert drafts for existing reviews, where review_id should point to an existing review, because ideally the index here should be a combination of product_id , user_id and review_id . Unfortunately, in my case the following applies:
UNIQUE index allows multiple NULL values for columns that may contain NULL
As long as there are questions and answers about the above quote, I'm not necessarily interested in getting a zero value as part of a unique index, but rather finding a workaround.
I think I could first make a selection request to check if the above combination exists, and if the main request is not continued. But I would like to get all this in one request, if possible. Ideas?
Thanks.