Каков наиболее эффективный способ управления положением записи в таблице RDBMS?

0

скажем, у нас есть записи в таблице, и мы хотели бы иметь возможность упорядочить (и изменить их порядок).

таблица может выглядеть примерно так, см. ниже

                      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 - это уникальный идентификатор (может быть любым), position позиции элемента в списке, level глубины уровня и родительский идентификатор parentId (если существует)

Обычно я хотел бы следующий метод:

/**
  @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
    вам действительно нужен столбец уровня? Это неявно, глядя на родителей (ы). И, возможно, «pos» должно быть только в элементах, которые имеют одного и того же непосредственного родителя - их позиция в целом неизбежно определяется их родителем, в конце концов. Я думаю, что это сделает вашу структуру данных более эффективной и, вероятно, сделает ваши запросы менее сложными для реализации. Это также более точно соответствует сценарию, который вы упомянули, когда человек, выполняющий переупорядочение, может видеть только подмножество данных.
  • 0
    Я думаю, что вам нужно уточнить, является ли это специфичным для MySQL или любой СУБД. В Oracle, например, есть «connect by», а другие используют CTE (общие табличные выражения), но MySQL действительно не имеет аналога. Лучше всего использовать временную таблицу для хранения переупорядочения, а затем либо удалять и повторно вставлять, либо обновлять существующие строки после того, как ваши операции завершены. Еще одна вещь: какую версию MySQL вы используете? Плакат ниже верен, если MySQL 8 или выше.
Теги:
rdbms

1 ответ

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню