Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Базы Данных > Удаление зависимых записей


Автор: pushok 10.9.2010, 03:00
Здравствуйте.

Вопрос следующий:

В базе данных в одной таблице одна запись может ссылаться на другую в той же таблице. При этом неизвестно какой длины может получиться цепочка ссылающихся друг на друга записей. Закольцованных записей получиться не может.
Если я удаляю одну из них, то все ссылающиеся на нее должны быть удалены. Это я бы смог сделать. Но если у меня цепочка из N-уровней, а я удаляю запись 1-го уровня, мне нужно удалить все записи на всех N-уровнях.

Имеется:
id - уникальный номер записи
p_id - номер записи на которую ссылается данная (если 0, то не ссылается, т.е. 1й уровень).

Если бы было 2 уровня, и надо удалить запись с id=id1: выбрал бы из таблицы все записи у которых p_id=id1 и удалил бы их

Теоретически можно реализовать это рекурсивной функцией (пока не пробовал).
Возможно есть какие-то более совершенные варианты?

Заранее благодарен за помощь.

Автор: pushok 10.9.2010, 03:48
Вот такая функция получилась:

Код

function delete($id_delete)
 {
 $result_delete=mysql_query('SELECT id FROM '.$prefix.'_days WHERE p_id='.$id_delete);
 for($i=0;$i<mysql_num_rows($result_delete);$i++) { delete(mysql_result($result_delete,$i,'id')); }
 mysql_query('DELETE FROM '.$prefix.'_days WHERE id='.$id_delete);
 }


Работает хорошо. Но получается много запросов к базе данных. Или мне кажется? Нужна консультация "бывалых" = )

Автор: Mavrun 10.9.2010, 07:07
Подписываюсь под вопросом. Подобную проблему решил схожей функцией, но не знаю, насколько это оптимально. 

Автор: skyboy 10.9.2010, 08:36
сколько возможных схем хранения древовидной структуры в реляционной БД? Список смежности(adjancy list), все родители в виде строки через запятую(materialized path) и вложенные множества(nested sets). если у тебя не дерево, а произвольный граф, то у тебя остается только adjancy list. и тут никак, кроме рекурсии, не выйти из положения. кстати, каждый элемент может ссылаться только на один другой элемент или на несколько? если все же на один, то это называется деревом и тогда для хранения можно использовать другую структуру, только adjancy list из названных приводит к использованию рекурсии. остальные позволяют обрабатывать целые ветки за один запрос.
а если отношения элементов не "один-ко-многим", а "многие-ко-многим", т.е. у тебя все-таки граф, то придется оставить adjancy list, но можно повесить триггер на удаление и возложить рекурсивность на плечи СУБД. 


Автор: capitan 10.9.2010, 11:45
Чтобы таких вопросов не возникало, необходимо правильно составить структуру БЗ. Тогда перемещения, удаления и т.д. делаются одним запросом. О чем skyboy и написал выше.

http://www.getinfo.ru/article610.html

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)