Mysql
 sql >> база данни >  >> RDS >> Mysql

Кой йерархичен модел трябва да използвам? Съседство, вложени или изброени?

Обикновено има три вида заявки в йерархиите, които причиняват проблеми:

  1. Върнете всички предци
  2. Връщане на всички потомци
  3. Върнете всички деца (непосредствени потомци).

Ето малка таблица, която показва производителността на различни методи в MySQL :

                        Ancestors  Descendants  Children        Maintainability InnoDB
Adjacency list          Good       Decent       Excellent       Easy            Yes
Nested sets (classic)   Poor       Excellent    Poor/Excellent  Very hard       Yes
Nested sets (spatial)   Excellent  Very good    Poor/Excellent  Very hard       No
Materialized path       Excellent  Very good    Poor/Excellent  Hard            Yes

В children , poor/excellent означава, че отговорът зависи от това дали смесвате метода със списък на съседство, т.е. д. съхраняване на parentID във всеки запис.

За вашата задача са ви необходими и трите заявки:

  1. Всички предци, за да се покаже нещото Земята/Обединеното кралство/Девън
  2. Всички деца за показване на „Дестинации в Европа“ (артикулите)
  3. Всички потомци за показване на „Дестинации в Европа“ (броя)

Бих тръгнал по материализирани пътища, тъй като този вид йерархия рядко се променя (само в случай на война, бунт и т.н.).

Създайте колона varchar, наречена path , индексирайте го и го попълнете със стойността по следния начин:

1:234:6345:45454:

където числата са първични ключове на съответните родители, в правилен ред (1 за Европа, 234 за Обединеното кралство и др.)

Ще ви трябва и таблица, наречена levels за да запазите числата от 1 до 20 (или каквото желаете максимално ниво на влагане).

За да изберете всички предшественици:

SELECT   pa.*
FROM     places p
JOIN     levels l
ON       SUBSTRING_INDEX(p.path, ':', l.level) <> p.path
JOIN     places pa
ON       pa.path = CONCAT(SUBSTRING_INDEX(p.path, ':', l.level), ':') 
WHERE    p.id = @id_of_place_in_devon

За да изберете всички деца и броя на местата в тях:

SELECT  pc.*, COUNT(pp.id)
FROM    places p
JOIN    places pc
ON      pc.parentId = p.id
JOIN    places pp
ON      pp.path BETWEEN pc.path AND CONCAT(pc.path, ':')
        AND pp.id NOT IN
        (
        SELECT  parentId
        FROM    places
        )
WHERE   p.id = @id_of_europe
GROUP BY
        pc.id


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Грешка в MySQL Entity Framework - Посоченият доставчик на магазин не може да бъде намерен в конфигурацията или не е валиден

  2. Как да променя root паролата на MySQL на по подразбиране?

  3. Съвпадение на знака '%' при търсене в MySQL база данни

  4. Как да получа ID на последния актуализиран ред в MySQL?

  5. CakePHP поръчката не работи