Updating display order of multiple MySQL rows in one or very few queries

前端 未结 11 1233
迷失自我
迷失自我 2021-02-01 07:43

I have a table with say 20 rows each with a number for display order (1-20).

SELECT * FROM `mytable` ORDER BY `display_order` DESC;

From an adm

11条回答
  •  闹比i
    闹比i (楼主)
    2021-02-01 07:55

    If you need to drag you rows, this is a good implementation for a linked list.

    Having your rows ordered with a linked list means that you will update at most 3 rows at a time -- even if you move the whole block (as long as it's contiguous).

    Create a table of your rows like this:

    CREATE TABLE t_list (
            id INT NOT NULL PRIMARY KEY,
            parent INT NOT NULL,
            value VARCHAR(50) NOT NULL,
            /* Don't forget to create an index on PARENT */
            KEY ix_list_parent ON (parent)
    )
    
    id   parent  value
    
    1    0       Value1
    2    3       Value2
    3    4       Value3
    4    1       Value4
    

    and use this MySQL query to select the rows in order:

    SELECT  @r := (
            SELECT  id
            FROM    t_list
            WHERE   parent = @r
            ) AS id
    FROM    (
            SELECT  @r := 0
            ) vars,
            t_list
    

    This will traverse your linked list and return the ordered items:

    id   parent  value
    
    1    0       Value1
    4    1       Value4
    3    4       Value3
    2    3       Value2
    

    To move a row, you'll need to update the parent of the row, the parent of its current child, and the parent of the row you're inserting before.

    See this series of articles in my blog on how to do it efficiently in MySQL:

    • Sorting lists - how to select ordered items from a linked list
    • Sorting lists: moving items - how to move a single item
    • Sorting lists: adding items - how to insert a single item
    • Sorting lists: deleting items - how to delete a single item
    • Sorting lists: moving blocks - how to move a contiguous block
    • Sorting lists: deleting blocks - how to delete a contiguous block

    There are lots of articles because there are some issues with row locking which should be handled slightly differently for each case.

提交回复
热议问题