管理RDBMS表中记录位置的最有效方法是什么

时间:2018-11-20 13:01:51

标签: mysql sql rdbms

假设我们在一个表中有记录,我们希望能够对它们进行排序(然后重新排序)。

表格可能看起来像这样,见下文

                      id   Pos Level   parentId
Europe                18     1    0    null
    Germany            9     2    1    18
        Berlin         2     3    2    9
        Frankfurt     20     4    2    9
        Stuttgart     23     5    2    9
    France            29     6    1    18
        Paris         26     7    2    29
        Lyon          13     8    2    29
Americas              11     9    0    null
    USA               27    10    1    11
        New York      22    11    2    27
            Manhattan 19    12    3    22
            Brooklyn   7    13    3    22
        Los Angeles   25    14    2    27
    Mexico             6    15    1    11
    Canada             4    16    1    11
        Montreal      21    17    2    4
        Vancouver      3    18    2    4
Asia                   8    19    0    null
    China             14    20    1    8
        Beijing       17    21    2    14
        Shenzhen      30    22    2    14
        Shanghai      28    23    2    14
    Japan             16    24    1    8
        Tokyo          1    25    2    16
            Shinjuku  15    26    3    1
Oceania               24    27    0    null
    Autralia           5    28    1    24
        Sydney        10    29    2    5
Africa  

          12    30    0    null

其中id是唯一ID(可以是任意ID),position元素在列表中的位置,level深度级别和parentId父ID(如果存在)

通常,我需要以下方法:

/**
  @param sourceId: id of the element to be moved
  @params targetId: id of the element which position needs to be overtaken
  @param aboveOrBelow: defines whether the old element (target) will be placed above or below the source element
  @return if successful, new position of the source element, if unsuccessful: message explaining why unsuccessful
*/
def move(sourceId: Long, targetId: Long, aboveOrBelow: Boolean = true):Either[Long, String]

最有效的方法是什么?或者我缺少什么? (My)SQL中是否已经有用于此类操作的内置机制?

约束: -可能被允许重新排序的最终用户不一定会看到所有记录(例如,仅asian条记录) -可以添加和删除记录

===编辑=== 我考虑了评论中的建议,重新编写了结构:

                      id   pos   parentId
Europe                18    1    null
    Germany            9    1    18
        Berlin         2    1    9
        Frankfurt     20    2    9
        Stuttgart     23    3    9
    France            29    2    18
        Paris         26    1    29
        Lyon          13    2    29
Americas              11    2    null
    USA               27    1    11
        New York      22    1    27
            Manhattan 19    1    22
            Brooklyn   7    2    22
        Los Angeles   25    2    27
    Mexico             6    3    11
    Canada             4    4    11
        Montreal      21    1    4
        Vancouver      3    2    4
Asia                   8    3    null
    China             14    1    8
        Beijing       17    1    14
        Shenzhen      30    2    14
        Shanghai      28    3    14
    Japan             16    2    8
        Tokyo          1    1    16
            Shinjuku  15    1    1
Oceania               24    4    null
    Autralia           5    1    24
        Sydney        10    1    5
Africa                12    5    null

1 个答案:

答案 0 :(得分:1)

为构建树结构,我将使用如下递归cte。并将其构建为视图

with recursive cte(place_name,id,parent_id,level)
  as (select place_name,id,parent_id,1 as level
        from countries_hierarchy
       where parent_id is null
       union all
       select concat(lpad(' ',a.level+1,' ')
                    ,b.place_name
                    )
              ,b.id
              ,b.parent_id
              ,a.level+1
         from cte a
         join countries_hierarchy b
           on a.id=b.parent_id
       )
select * from cte 

https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=334820e4e01cf8749c5abcaa447963a0