Mysql – How to auto assign ordinal ranking in thesql with as minimal queries for new rows

MySQLperformanceperformance-tuning

+----+---------+---------+-----------------+
| id | view_id | user_id | ordinal_ranking |
+----+---------+---------+-----------------+
|  1 |      10 |       1 |               1 |
|  2 |      10 |       2 |               1 |
|  3 |      11 |       1 |               2 |
|  4 |      11 |       2 |               2 |
+----+---------+---------+-----------------+

So suppose I want to insert new rows for view_id 12 and for both user_id 1 and 2, these 2 new rows should have ordinal ranking of 3.

How do I do that with minimal number of queries?

Bear in mind, I have many users who may all have different number of views assigned.

Another corollary to the problem is when I need to delete a particular view, say view 10, all the users affected should have the ordinal ranking re-ordered.

How do I do that also with minimal number of queries?

EDIT

A comment was made about the number of views per user. I would like to add that you may safely assume that there is a users table and one column stores the number of views for each user record.

I am also okay if the ordinal ranking is zero-based, ie the ranking is 0, 1, 2, 3, etc

I also prefer not to use stored procedures.

EDIT2:

+----+---------+---------+
| id | name | view_count |
+----+---------+---------+
|  1 |     Sal |       2 |
|  2 |     Sam |       2 |
+----+---------+---------+

Is the users table

the ordinal_ranking merely reflects the personal choice of a user with regards to the views she can view.

E.g. user 1 Sal likes to have view 10 to be ranked higher than view 11.

Best Answer

If you are content with adding and deleting a view_id per user_id, here is what I see

Adding View 12 To User 10

I see three queries

  • Insert new view into user with BogusRank
  • Move all rank down below NewRank
  • Change BogusRank to New Rank for new view

Here is the proposed code

SET @view_id = 12;
SET @user_id = 10;
SET @newrank = 3;
SET @defrank = 999999999;
INSERT INTO userviewranks
(view_id,user_id,ordinal_ranking)
VALUES (@view_id,@user_id,@defrank);
UPDATE userviewranks SET ordinal_ranking = ordinal_ranking + 1
WHERE view_id = @view_id AND user_id = @user_id AND ordinal_ranking >= @newrank;
UPDATE userviewranks SET ordinal_ranking = @newrank
WHERE view_id = @view_id AND user_id = @user_id AND ordinal_ranking = @defrank;

Deleting View 12 From User 10

I see three queries

  • Retrieve Row With View to Delete
  • Move All View Up in Rank
  • Delete Row with Old View

Here is the proposed code

SET @view_id = 12;
SET @user_id = 10;
SELECT id,ordinal_ranking INTO @id_to_zap,@rank_to_zap FROM userviewranks
WHERE view_id = @view_id AND user_id = @user_id;
UPDATE userviewranks SET ordinal_ranking = ordinal_ranking - 1
WHERE view_id = @view_id AND user_id = @user_id AND ordinal_ranking > @rank_to_zap;
DELETE FROM userviewranks WHERE id = @id_to_zap;