Вы правы - заполнение нулями каждого идентификатора узла позволит вам довольно просто отсортировать все дерево. Однако вы должны сделать так, чтобы ширина отступа соответствовала верхнему пределу цифр поля ID, как вы указали в последнем примере. Например, если вы используете поле int unsigned
для своего идентификатора, самое высокое значение будет 4 294 967 295. Это десять цифр, это означает, что набор записей из вашего последнего примера может выглядеть следующим образом:
uid | name | tree_id
9999 | Tar | 0000000001.0000009999
10000 | Tor | 0000000001.0000010000
Пока вы знаете, что в будущем вам не понадобится менять поле идентификатора на bigint unsigned
, это продолжит работу, хотя это может быть связано с большими объемами данных в зависимости от размера ваших таблиц. Вы можете сократить два байта на каждый идентификатор узла, сохранив значения в шестнадцатеричном формате, которые все равно будут правильно отсортированы при сортировке строк:
uid | name | tree_id
9999 | Tar | 00000001.0000270F
10000 | Tor | 00000001.00002710
Я могу себе представить, что это приведет к настоящей головной боли при попытке обновить пути (обрезка узлов и т. Д.).
Вы также можете создавать дополнительные поля для сортировки, например ::
uid | name | tree_id | name_sort
9999 | Tar | 00000001.0000270F | Ali.Tar
10000 | Tor | 00000001.00002710 | Ali.Tor
Однако существуют ограничения, изложенные ответом этого парня на аналогичный материализованный вопрос сортировки путей . Поле name
должно быть заполнено до заданной длины (к счастью, в вашем примере каждое имя имеет длину в три символа), и оно заняло бы много места.
В заключение, учитывая вышеперечисленные проблемы, я обнаружил, что наиболее универсальный способ сделать сортировку, подобную этой, - это просто сделать это в логике вашего приложения - скажем, с помощью рекурсивной функции, которая создает вложенный массив, сортируя потомки каждого узла.