21

Re: Дерево в mysql

caballero написав:
savelikan написав:

Привіт усім!
Мені потрібно створити деревоподібну структуру таблиці в SQL.

Замість  дурниць  про  триггери  та  інші  речі  які  не  мають  відношення  до  деревоподібних  структур  куримо   Nested Sets  або  Materialized Path.   
  Якщо  мова  про промисловий  сервер  БД  а  не  Mysql  то  там  як  правило  є  спеціалізовані оператори  типу WITH   тому  там  можна  користуватися  і  примітивними структурами таблиць   я к   у вашому  прикладі.

Де можна детальніше про це прочитати?


А ще питання по тому прикладу, який я навів. Щоб побудувати повний адрес, необхідно зробити запит в циклі, поки address не буде NULL
Чи є інші варіанти?

22

Re: Дерево в mysql

savelikan написав:

А ще питання по тому прикладу, який я навів. Щоб побудувати повний адрес, необхідно зробити запит в циклі, поки address не буде NULL
Чи є інші варіанти?

Про що мова?

23

Re: Дерево в mysql

ktretyak написав:
savelikan написав:

А ще питання по тому прикладу, який я навів. Щоб побудувати повний адрес, необхідно зробити запит в циклі, поки address не буде NULL
Чи є інші варіанти?

Про що мова?

    CREATE TABLE IF NOT EXISTS `pages` (
    `pages_id` int(11) NOT NULL AUTO_INCREMENT,
    `pages_address` int(11) NULL,
    `pages_type` int(11) NOT NULL,
    `pages_user` int(11) NOT NULL,
    `pages_date` int(11) NOT NULL,
    `pages_update` int(11) NOT NULL,
    `pages_title` varchar(200) NOT NULL,
    `pages_text` text NOT NULL,
    PRIMARY KEY (`pages_id`),
    CONSTRAINT `fk_address` FOREIGN KEY `fk_address` (`pages_address`)
    REFERENCES `pages` (`pages_id`)
    ON DELETE CASCADE
    ) ENGINE=InnoDB;

Ось так зберігається деревоподібна структура в БД
І я шукаю можливість одержати повну адресу запису. Наприклад,

INSERT INTO `pages` (`pages_id`, `pages_address`, `pages_type`, `pages_title`, `pages_text`) VALUES
(1, NULL, 0, 'Медицина', ''),
(2, 1, 0, 'Хірургія', ''),
(3, 2, 0, 'Оперативна хірургія', ''),
(4, 3, 0, 'Назва статті', '');

Як ожержати адресу запису "Назва статті" у вигляді:
Медицина -> Хірургія -> Оперативна хірургія

24

Re: Дерево в mysql

savelikan написав:
ktretyak написав:
savelikan написав:

А ще питання по тому прикладу, який я навів. Щоб побудувати повний адрес, необхідно зробити запит в циклі, поки address не буде NULL
Чи є інші варіанти?

Про що мова?

    CREATE TABLE IF NOT EXISTS `pages` (
    `pages_id` int(11) NOT NULL AUTO_INCREMENT,
    `pages_address` int(11) NULL,
    `pages_type` int(11) NOT NULL,
    `pages_user` int(11) NOT NULL,
    `pages_date` int(11) NOT NULL,
    `pages_update` int(11) NOT NULL,
    `pages_title` varchar(200) NOT NULL,
    `pages_text` text NOT NULL,
    PRIMARY KEY (`pages_id`),
    CONSTRAINT `fk_address` FOREIGN KEY `fk_address` (`pages_address`)
    REFERENCES `pages` (`pages_id`)
    ON DELETE CASCADE
    ) ENGINE=InnoDB;

Ось так зберігається деревоподібна структура в БД
І я шукаю можливість одержати повну адресу запису. Наприклад,

INSERT INTO `pages` (`pages_id`, `pages_address`, `pages_type`, `pages_title`, `pages_text`) VALUES
(1, NULL, 0, 'Медицина', ''),
(2, 1, 0, 'Хірургія', ''),
(3, 2, 0, 'Оперативна хірургія', ''),
(4, 3, 0, 'Назва статті', '');

Як ожержати адресу запису "Назва статті" у вигляді:
Медицина -> Хірургія -> Оперативна хірургія

Ні, це називається каша, інколи вінігрет, але точно не деревоподібна структура.

Розділіть по-людські, тобто замість однієї збірної таблиці створіть декілька. У тому вигляді, в якому ви її створили, таблиця pages не підходить для зберігання фрагментів однієї сторінки. Тут же явно вказано, що PRIMARY KEY (`pages_id`), тобто тут зберігаються різні сторінки, але видаляються в залежності від поля pages_address...

25

Re: Дерево в mysql

ktretyak написав:

Розділіть по-людські, тобто замість однієї збірної таблиці створіть декілька. У тому вигляді, в якому ви її створили, таблиця pages не підходить для зберігання фрагментів однієї сторінки. Тут же явно вказано, що PRIMARY KEY (`pages_id`), тобто тут зберігаються різні сторінки, але видаляються в залежності від поля pages_address...

Ну і добре, коли видаляєш запис, всі "дочірні" видаляються автоматично. І про цей метод пишуть в літературі як "Метод Смежных вершин (Ajacency List)"

26

Re: Дерево в mysql

Ну от і пограйтесь із цим добром, раз вам воно подобається.

27

Re: Дерево в mysql

ktretyak написав:

Ну от і пограйтесь із цим добром, раз вам воно подобається.

А який варіант пропонуєте Ви? де можна подивитися приклади його роботи?

28

Re: Дерево в mysql

Якщо вам потрібно бачити "Медицина -> Хірургія -> Оперативна хірургія", то створіть відповідно три таблиці. Перша таблиця "Медицина" найголовніша: видалення запису з неї видаляє всі записи з таблиць Хірургія та Оперативна хірургія.
Від другої таблиці Хірургія залежить лише таблиця Оперативна хірургія. Тобто видалення запису з Хірургія автоматично видаляє запис з Оперативна хірургія.


Для створення цих таблиць використовуйте ваш приклад, але в директиві REFERENCES посилайтесь на різні таблиці, а не на таблицю, яку створюєте...

29

Re: Дерево в mysql

ktretyak написав:

Якщо вам потрібно бачити "Медицина -> Хірургія -> Оперативна хірургія", то створіть відповідно три таблиці. Перша таблиця "Медицина" найголовніша: видалення запису з неї видаляє всі записи з таблиць Хірургія та Оперативна хірургія.
Від другої таблиці Хірургія залежить лише таблиця Оперативна хірургія. Тобто видалення запису з Хірургія автоматично видаляє запис з Оперативна хірургія.


Для створення цих таблиць використовуйте ваш приклад, але в директиві REFERENCES посилайтесь на різні таблиці, а не на таблицю, яку створюєте...

То мені прийдеться робити по одному запиту в кожну таблицю, щоб одержати такий шлях?
Якщо глибина дерева буде,наприклад, до 10 - 10 таблиць створювати?

30

Re: Дерево в mysql

savelikan написав:

То мені прийдеться робити по одному запиту в кожну таблицю, щоб одержати такий шлях?
Якщо глибина дерева буде,наприклад, до 10 - 10 таблиць створювати?

Так.

31

Re: Дерево в mysql

ktretyak написав:
savelikan написав:

То мені прийдеться робити по одному запиту в кожну таблицю, щоб одержати такий шлях?
Якщо глибина дерева буде,наприклад, до 10 - 10 таблиць створювати?

Так.

А одим запитом можна це все зробити?
Бо ынакше продуктивність буде низька