удаление связанных записей в БД

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

удаление связанных записей в БД

Сообщение NewUser » 05.06.2007 14:53:53

в таблице 1 сотрудники - поля
id
name
otdel
dolgn

2 таблица - должности
id
name

3 таблица - отдел
id
name

таблица 1, связана с 2 и 3 по otdel и dolgn
теперь если я удалю запись из 2 или 3 таблицы 1 обратится к несуществующей записи, каким образом решается такая зада?

если выбирать
1.otdel=2.id AND 1.dolgn=3.id
то сотрудник у которого попадает должность под удаленную виден не будет
NewUser
новенький
 
Сообщения: 97
Зарегистрирован: 08.05.2007 13:28:40

Сообщение v-t-l » 05.06.2007 21:25:17

Используй LEFT JOIN
v-t-l
энтузиаст
 
Сообщения: 734
Зарегистрирован: 13.05.2007 16:27:22
Откуда: Belarus

Сообщение SAK » 05.06.2007 22:34:36

Вообще-то исходя из логики для данного случая, надо бы запретить удаление записей из 2-й и 3-й таблиц, если они используются в 1-й. А то получается сотрудник без должности - нелогично.
SAK
постоялец
 
Сообщения: 158
Зарегистрирован: 18.02.2006 00:45:14
Откуда: Тим

Сообщение Михаил » 06.06.2007 08:57:09

создай триггер чтобы выполнялся до удаления записей из 2-й и 3-й таблицы...... можешь либо удалить эти поля из 1-й таблицы, либо как-нибудь их пометить

Код: Выделить всё
CREATE TRIGGER delete2  FOR 2
BEFORE DELETE AS
BEGIN
  DELETE FROM 1 WHERE DOLGN=OLD.id;
END

CREATE TRIGGER delete3  FOR 3
BEFORE DELETE AS
BEGIN
  DELETE FROM 1 WHERE otdel=OLD.id;
END
Аватара пользователя
Михаил
новенький
 
Сообщения: 13
Зарегистрирован: 31.10.2006 14:27:31

Сообщение NewUser » 06.06.2007 10:06:09

при таких условиях я не смогу обращаться к сотрудникам, у которых удалены должности или отделы. получается один вариант - не удалять их, а если удалять, то с уверенностью, что запись нигде не используется
NewUser
новенький
 
Сообщения: 97
Зарегистрирован: 08.05.2007 13:28:40

Сообщение debi12345 » 06.06.2007 10:38:12

А в чем проблема ?

Всегда нужно знать, что происходит и не должно быть никаких "сюрпризов" для пользователей, для этого нужно :

1) отказаться от использования триггеров (что Вам предложено ) и каскадированного удаления ( на что Вы намекаете )
2) проверять наличие ссылок на другие таблицы и уведомлять об этом пользователя !
3) если пользователь все же подтверждает удаление - запомнить ID мастер-аблицы, затем открыть транзакцию, удалить в подчиненных таблицах ссылки на этот ID, потом удалить в мастер-таблице, и подтвердить транзакцию.

Необоснованное (как здесь) использование триггеров плохо еще и тем, что :

1) замедляет работу сервера (даже если на мизер - но зачем это нужно ? )

2) создает проблемы с обслуживанием БД типа "отбросить устаревшие" (потребуется временное удаление этих триггеров, потом пересоздание )

ПС:

А для просмотра записей с удаленными ссылками наряду с оставшимися ссылками - да, LEFT/RIGHT OUTER JOIN. Именно OUTER.
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5759
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Сообщение Attid » 06.06.2007 11:55:40

debi12345

1) отказаться от использования триггеров

тригеров не надо боятся они хорошие.

замедляет работу сервера

тригер будет скомпелированый и выполнит работу бустрее чем куча отдельных запросов.

(потребуется временное удаление этих триггеров, потом пересоздание )

во первых их можно просто деактивировать
во вторых предусматривать такие вещи заранее.

NewUser
каскадированное удаление это вообще большое зло если не уметь им пользоваться , соответственно вам советую отказаться.

и нечего без надобности перекрестные ссылки делать.
Аватара пользователя
Attid
долгожитель
 
Сообщения: 2585
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E

Сообщение debi12345 » 06.06.2007 12:19:58

Ну не знаю..
За последний год поудалял почти все триггеры - и вздохнул широкой грудью. Оставил только триггеры для автоматического пересчета итогов ( пару навороченных функций по несколько сот строк кода каждая ) и для замены черновых записей-залушек, то есть операций, недоступных пользователям.
Вообще, даже авторы серверов БД убеждают - "используйте триггеры только при крайней необходимости".
Ну и самая большая ошибка начинающих - использование ссылочой целостности и FOREIGN_KEY ( внутренне реализуемых на триггерах ). Это такой потенциальный геморрой !

тригер будет скомпелированый и выполнит работу бустрее чем куча отдельных запросов.

Зато хук на этот триггер проверяется на каждой операции с записями. Посмотрите исходники любого сервера БД.
А отдельные запросы отрабатывают строго по необходимости.

Да, еще, спрятанные триггерные операции могут выключать индексирование, или наоборот - включать там , где оно вызывает тормоза. Можно в скорости в десятки раз проиграть. И задолбаешься искать, в чем причина - сколько таких историй в Сети !
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5759
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Сообщение alexs » 07.06.2007 12:08:32

Очень смелы и спорные утверждения
на мой взягляд - тригеры - это ОЧЕНЬ удобное средство
но как и любой инструмент ими надо уметь пользоваться

debi12345 писал(а):Зато хук на этот триггер проверяется на каждой операции с записями


Ну не на каждой операции -а только на ттой к типу который принадлежит тригер

debi12345 писал(а):Ну и самая большая ошибка начинающих - использование ссылочой целостности и FOREIGN_KEY

вы сказал не верно - надо так:

Ну и самая большая ошибка начинающих - НЕ использование ссылочой целостности и FOREIGN_KEY

я столько огрёб с чужими данными в которых защит по уелостности не было - что это для меня очень важно
пусть приложение будет чуть медленне (но обычно и замедлений нет) - но данные ВСЕГДа будут именно теми, которые ты ожидаеш

И вобще - обычно проблемы появляются при полном не жалении правильно спректировать БД - принци сначал напишем - а потом подумем как оно работает
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4060
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Сообщение debi12345 » 07.06.2007 12:28:36

Ну не на каждой операции -а только на той к типу который принадлежит тригер

А этого мало ?

я столько огрёб с чужими данными в которых защит по уелостности не было - что это для меня очень важно
пусть приложение будет чуть медленне (но обычно и замедлений нет) - но данные ВСЕГДа будут именно теми, которые ты ожидаеш

Ссылочную целостность нужно гарантировать пользовательскими программами, а вне-программный (низкоуровневый ) доступ к БД, который представляет угрозу в отсутствие крайне капризных механизмов типа FOREIGN_KEY - закрыть разграничением полномочий ( которое и так необходимо ).

Ну и самая большая ошибка начинающих - НЕ использование ссылочой целостности и FOREIGN_KEY

Эта целостность создает наитупейшие триггеры - этим все сказано. Которые еще и не всегда можно отключить - например, в старых версиях PostgreSQL.

на мой взягляд - тригеры - это ОЧЕНЬ удобное средство
но как и любой инструмент ими надо уметь пользоваться

Еще какое удобное! Например, благодаря им удалось избежать постоянного запуска 30-минутного итогового запроса с "GROUP BY", вместо этого триггерная функция рассчитывает и пишет эти итоги в спецтаблицу непосредственно в момент репликации. Данный отход ( ведение таблицы итогов вместо актуального их расчета через SQL-группировку ) от нормального реляционного подхода к проектированию БД дал экономию времени в сотни раз. А вы говорите - "грамотное проектирование". Иногда "неграмотное" дает суперэффект!

Но "ссылочная целостность" и каскадированные операции - уж увольте !
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5759
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Сообщение Attid » 07.06.2007 14:30:17

Ссылочную целостность нужно гарантировать пользовательскими программами,

в многопользовательском варианте это просто невозможно сделать.
через глабли конечно можно все, но зачем?

Эта целостность создает наитупейшие триггеры - этим все сказано. Которые еще и не всегда можно отключить - например, в старых версиях PostgreSQL.

ошибки бывают у всех даже у серверов БД =)
механизм может и похож на тригерный, но работает вне транзакций.

пишет эти итоги в спецтаблицу

может лучше былоб сделать функцию которая положит итоги в эту таблицу и запускать её после реплики?? хотя это все зависит от структуры и сервера.

"неграмотное" дает суперэффект!

Зачем же вы это в слух говорите, тут же дети ходят, им и так правила не писаны тк они еще решат что они ошибочны.
я бы не утверждал что это не грамотно, иногда нет другого выбора.
помнится были процедуры для отчетов запускаемые на ночь, чтоб на не загруженых серерах все пересчиталось и утром у начальства уже работали с пол тычка.
Аватара пользователя
Attid
долгожитель
 
Сообщения: 2585
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E

Сообщение NewUser » 07.06.2007 16:00:25

Ссылочную целостность нужно гарантировать пользовательскими программами, а вне-программный (низкоуровневый ) доступ к БД, который представляет угрозу в отсутствие крайне капризных механизмов типа FOREIGN_KEY - закрыть разграничением полномочий ( которое и так необходимо ).


я так понимаю что тогда их можно вовсе не создавать?
NewUser
новенький
 
Сообщения: 97
Зарегистрирован: 08.05.2007 13:28:40

Сообщение debi12345 » 07.06.2007 16:37:22

я так понимаю что тогда их можно вовсе не создавать?

Чем меньше ограничений в структуре БД - тем лучше. Уж поверьте ! Лучше эти ограничения ввести на более высоком уровне - в пользовательской программе. Пользователь всегда должен знать, когда он что-то делает неправильно !
Тем более что все равно БД-компоненты не умеют гарантированно правильно извещать о типах ошибок при работе с БД ( например - ошибка нарушения ссылочной целостности ), коды и тексты ошибок меняются,... - поэтому среагировать на такую ошибку проблематично.
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5759
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Сообщение debi12345 » 07.06.2007 16:55:21

в многопользовательском варианте это просто невозможно сделать.
через глабли конечно можно все, но зачем?

Ну уж прям-таки грабли:

1) механизм BEGIN/LOCK ../COMMIT
2) однократная выборка ( "дотрагивание" ) новых ID через SEQUENCE

И отсутствие конфликтов гарантировано.

может лучше было б сделать функцию которая положит итоги в эту таблицу и запускать её после реплики?? хотя это все зависит от структуры и сервера.

Фишка этого подхода в том, что при репликации идут интенсивные вставки записей ( медленная операция, так как - запись на файловую систему ), на фоне которой чуток затянутый SELEСT-запрос, инициируемый триггером, и вызываемый по факту и делающий точечный пересчет (потому что имеет всю информацию "на руках" ) - погоды не делает. Обычным же путем приходилось пересчитывать все скопом, "не-точечно" - что отнимало огромное время и поэтому не позволяло запускать это отчет несколько раз в день.

Зачем же вы это в слух говорите, тут же дети ходят, им и так правила не писаны тк они еще решат что они ошибочны.
я бы не утверждал что это не грамотно, иногда нет другого выбора.

Это я к тому, что догматизм бывает вреден - особенно в столь творческой профессии. Многие БД-админы грешат параноидальной приверженностью к "нормализации" БД.
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5759
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Сообщение Сергей Смирнов » 07.06.2007 17:03:01

debi12345 писал(а):Чем меньше ограничений в структуре БД - тем лучше. Уж поверьте ! Лучше эти ограничения ввести на более высоком уровне - в пользовательской программе. Пользователь всегда должен знать, когда он что-то делает неправильно !
А как Вы думаете, если пользователь знает, что он что-то делает неправильно, он точно не будет так делать? :)

debi12345 писал(а):Тем более что все равно БД-компоненты не умеют гарантированно правильно извещать о типах ошибок при работе с БД ( например - ошибка нарушения ссылочной целостности ), коды и тексты ошибок меняются,... - поэтому среагировать на такую ошибку проблематично.
Что за ужасные сервера БД и жуткие компоненты доступа к ним Вы использовали?

ЗЫ: Не учите детей плохому. Ссылочная целостность - это благо и единственный гарантированно надёжный способ предотвратить проблемы с данными. Каскадные операции - да, опасная штука сомнительной применимости для большинства задач.
Аватара пользователя
Сергей Смирнов
энтузиаст
 
Сообщения: 595
Зарегистрирован: 28.04.2005 13:23:25
Откуда: Москва

След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 31

Рейтинг@Mail.ru