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

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

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

Сообщение debi12345 » 07.06.2007 18:56:59

А как Вы думаете, если пользователь знает, что он что-то делает неправильно, он точно не будет так делать? Smile

Если не дурак ( не дура ) - не будет ( нашим узбечкам один раз сказать достаточно, для них позор выглядеть дурами и глазками хлопать ). Никто не говорит, что нужно позволить "запарывать" БД. Но ошибки ссылочной целостности - это логические ошибки, которые на совести пользователя. Потому что только пользователю известно, что некие сотрудники работают в неком отделе и поэтому не нужно этот отдел удалять. Поэтому если он пытается это делать - нужно ему об этом напоминать - он знает, о чем идет речь. Для этого нужно отлавливать такие попытки и выбрасывать сообщения. Как вы отлавливать собираетесь ? Помолившись, без проверок, позволять тразакцию и при ошибках целостности откатываться по ошибке, с последующим анализом ? Как вы представляет обрануружение типа и места ошибки и анализ ? Лично у меня не настолько крепкие нервы, чтобы при каждом апгрэйде сервера надеяться, что коды и реакция на ошибки не изменились.
К чему это все ? Да к тому, что если проверять на целостность самостятельно (100% надежно, тем более, что обычно на руках есть все данные для проверки без перезапроса к БД ), а не полагясь на сервер БД ( фиг его знает, чего там накодировали ) - то зачем эти FOREIGN_KEY, если они только мешают "отрезать" старые записи, а то и намного хуже - вытащить данные при крэше файловой системы, если бэкап неакутальный ? Чтобы админ в командной консоли сервера не напортачил ? Тогда покажите мне того экстремального админа, который делает серьезные изменения через SQL-команды без стартовой команды "BEGIN". Ау!

Что за ужасные сервера БД и жуткие компоненты доступа к ним Вы использовали

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

Не могу удержаться от развенчания еще одного мифа - что индексы, как правило, ускоряют выборки, но никогде не замедляют. Еще как замедляют - в десятки раз ! Имел "радость" с этим столкунуться.
Если в индексе есть одинаковые значения, равномерно распыленные по огромной таблице, то такой индекс породит интенсивнейший дисковый ввод-выдод ( будут читаться все страницы файла с таблицей ), с тормозами как следствие.
Поэтому индексы следует создавать :
1) для полей, практически не повторяющихся при разрастании таблиц - ID-поля, и текущие даты.
2) для индексирования сложных функций ( функциональные индексы), тут просто деваться некуда - ждешь создания индекса час-два, зато потом радуешься.
И все !

Мешающие индексы (по повторяющимся значениям,..) можно выключать, "загрязняя" условие, чтобы оптимизатор не пытался применить индекс :

WHERE a+0.0 = b

где "+ 0.0" выключит индекс по полю "а".

Вообще, спасибо за полемику :)
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5759
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Сообщение Attid » 07.06.2007 21:37:31

Не могу удержаться от развенчания еще одного мифа - что индексы, как правило, ускоряют выборки,

Вы сами сказали что "как правило" прежде чем что-то делать надо думать головой, а не пробывать на абум.


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

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

Сообщение Attid » 07.06.2007 21:40:34

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


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

Сообщение debi12345 » 08.06.2007 00:36:01

а никто и не говорит что ошибки не надо предотврощать на клиенте, но целостность на уровне БД спасет от лишнего гемороя.
никто не застрахован от ошибки.

BEGIN-LOCK-COMMIT-ROLLBACK.

Насчет FOREIGN_KEY - я верю разработчикам PostgreSQL, которые настоятельно отсоветуют этим "добром" пользоваться. Да и мне эти ключики порядочно крови попили при репликации - когда список новых пользователей стал, в зависимости от времен создания файлов репликации, обрабатываться позже операций этих пользователей. А стояла проверка на имеющийся "КОД ПОЛЬЗОВАТЕЛЯ". То есть данная зависимость вынуждала к жесткому порядку обработки файлов репликации и их своевременной досылке. Вроде все правильно, но конкретно в этой ситуации - нафиг не нужно. Хорошо еще, что в PostgreSQL эти ключи через триггерную функцию сделаны - удалось просто удалить эти триггеры.
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5759
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Сообщение alexs » 08.06.2007 02:34:06

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

ага - а ещё транзакции отменим как класс - будем после каждого чиха их коммитеть (я и стакм встречался)
ссылочная целостность - это одно из главных преимуществ нормального сервера БД - она даёт 100% гарантию что твои данные вне зависимости от того что хочет сделать оператор будут коректными - т.е. такми какими ты хочеш их веидить как разработчик
и тригеры здесь - это дополнительные ограничения

теперь о тригерах - если у тебя нормальная задача - обычные документы, которые добавляет человек (я не говорь о задачах протоколирования - когда автоматы добавляют записи - например сохранение данных от какого либа датчика) - то время работы трегера бесконечно мало по сравнению с тем с какой скоростью обрабатывает документы человек (если это не так - то это первый признак не оптимизированной структуры БД - БД должна быть как минимум в 3НФ)
Я на тригерах даже умудряюсь промежуточную статистику собирать для ускорения аналитики
и грамотно раставив тригера уже не надо заботиться о том что если ты в добавляеш в одну таблицу запись она коректно отобразится во всех связанных. Конечно - если у тебя простая структура где нет взаимосвязей - то тут и разговаривать не очем - но тогда возникает вопрос - а зачем там сервер БД.

debi12345 писал(а): каскадированные операции - уж увольте

пример - при вставке данных в одну таблицу они должны быть отображены в нескольких ешё таблицах в различных разрезах
без использования тригеров вам необходимо это либо делать на стороне клиента - (а оно вам это там надо?) либо писать SP
причём, когда мест откуда вставляется эта запись >1 - вам надо помнить все взаимосвязи и постоянно дублировать код - тригера решают эту проблему как класс.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4060
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Сообщение debi12345 » 08.06.2007 08:16:58

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

О чем спорим - если триггеры для одного того же используем ? "Промежуточная статистика" - хорошо и лаконично сказано, а я тут на пальцах измышляюсь :)

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

Сообщение Сергей Смирнов » 08.06.2007 10:36:53

debi12345 писал(а):Насчет FOREIGN_KEY - я верю разработчикам PostgreSQL, которые настоятельно отсоветуют этим "добром" пользоваться.
А я не верю таким разработчикам, либо это было сказано в какие-то древние времена и с тех пор PostgreSQL сильно повзрослел (да и разработчики тоже), либо в каком-то определённом, сильно экзотическом, контексте. В общем, ткните плиз в то место, где они это говорят.
Аватара пользователя
Сергей Смирнов
энтузиаст
 
Сообщения: 595
Зарегистрирован: 28.04.2005 13:23:25
Откуда: Москва

Сообщение debi12345 » 08.06.2007 12:12:07

В общем, ткните плиз в то место, где они это говорят.

Не помню, где на это наткнулся в период своих заблуждений - тоже тогда удивился.
А навскидку не нашел.

А я не верю таким разработчикам, либо это было сказано в какие-то древние времена и с тех пор PostgreSQL сильно повзрослел (да и разработчики тоже), либо в каком-то определённом, сильно экзотическом, контексте.

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

Сообщение Attid » 08.06.2007 13:31:58

Предварительно удалив триггеры, эти ключи обслуживавшие.

вот в этом и была ошибка.

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

Сообщение debi12345 » 08.06.2007 16:48:10

вот в этом и была ошибка.

У меня PostgreSQL. Выходит, что в старых типа 7.2 версиях эти ключи через тригеры были сделаны. Сужу по тому, что дампах БД в определениях таблиц нет никаких FOREIGN-ключей (использованных в синтаксисе CREATE TABLE ), но зато есть куча триггеров.
При создании таблицы пишется "CRETE TABLE will create implicit triggers(s) for forign key check". Также ограничение - другая таблица обязана иметь поле, декалрированное как "PRIMARY KEY" ( как обычно и делается ).

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

Сообщение Attid » 08.06.2007 22:02:59

debi12345
Вы утверждали что это зло везде,
в самом топике сервер тоже не указывался.
надесь теперь Вы поймете что советы которые
являются спецефичными для какой то БД
нельзя давать всем без разберательств.

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

Сообщение alexs » 09.06.2007 02:29:17

debi12345 писал(а):сли в индексе есть одинаковые значения, равномерно распыленные по огромной таблице, то такой индекс породит интенсивнейший дисковый ввод-выдод ( будут читаться все страницы файла с таблицей ), с тормозами как следствие.

1. в нормальном сервере БД чтение индекса не вызывает чтение данных
2. Индекс не должен содержать ограниченнный набор повторяющихся значений (например - нет смысла строить индекс по логическим полям) - ну это хорошо Кузьменко освятил в своих статьях.
3. Индексы не должны быть избыточными - я, например, строю индексы только тогда - когда уже нет другого пути - всегда стараюсь использовать уже существующие индексы.

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

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

Сообщение debi12345 » 09.06.2007 12:41:53

1. в нормальном сервере БД чтение индекса не вызывает чтение данных

Имено вызывает - поэтому, при условии охвата большей части таблицы, может привести к тормозам. Смысл индекса - минимизировать дисковый ввод-вывод через быстрое определение места в файле, где хранится нужная (уже неиндексная ) информация. Чтобы головки HDD не перебирали весь файл, а сразу бежали в нужное место.
Поэтому индекс хранит :

index_value/file_page_num

По найденому индексу идет чтение уже неиндексного значения нужного поля с найденной страницы файла данных. Если индекс распылен по всей таблице - будут читаться все страницы файла, с вытекающей беготней головок HDD, совсем не обязательно упорядоченной. Если БД реально большая - это очень медленно. А если попадешь на сортировку или групировку по такому индесу ( то есть нужно прочитать все страницы, на которые индекс ссылается, перед сортировкой ) - то гарантия тормозов 100%. Ессно, булевы поля - самый худший вариант для индексации.
Но тот же PostgreSQL , для полей с часто-повторяющимися значениями, имеет безиндексные способы оптимизации запросов - вроде "hash join", на удивление эффективные в плане оптимизации обращений к диску. Разница в скорости вылоления запросов через неверно выбранный индекс и через безындексный "hash join" достигает десятков раз !


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

Ну да - альтернатива. Либо избавляешься от геморроя - но повышается вероятность ошибок. Либо перестраховываешься.
Но если бы страховка была 100%. Например FOREIGN_KEY на защитит от вставки от имени левого оператора, если этот оператор есть во внешней таблице. Самая дерьмовая ошибка - обнаруживаемая слишком поздно.

Один неоспоримый плюс FOREIGN_KEY - по скрипту созданяи БД видишь связи между таблицами.


надесь теперь Вы поймете что советы которые
являются спецефичными для какой то БД
нельзя давать всем без разберательств.

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

Сообщение alexs » 10.06.2007 00:14:11

debi12345 писал(а):Имено вызывает - поэтому, при условии охвата большей части таблицы, может привести к тормозам

Теорию построения индексов я знаю :)
ты не путай обращение к индексу для поиска и отбора данных и физический фетч найденных данных - нормльный сервер бд стремится использоватьь индексы на основе анализа твоего условия ограничения на выборку - и если ему это удаётся то физически оне обратиться только к тем данным что попали в условие. т.е. у тебя в таблице 100000 записей, по условиям через индекс выбирается 10 записей - сервер сделает к данным 10 обращений - чтобы отдать тебе найденное. к индексам он тоже не ко всем обратится (количество обращений к индексным данным в среднем считается по логарифму - но тут уже зависит от организации самого индекса)

debi12345 писал(а):По найденому индексу идет чтение уже неиндексного значения нужного поля с найденной страницы файла данных. Если индекс распылен по всей таблице - будут читаться все страницы файла


ты сам себе противоречиш - дял чтения индекса не надо читать весь файл данных, и даже (если индексы выделены в отдельный файл) не весь файл индекса - в индексных узлах хранится обычно связка (упрощённо) на превыдущий узел, последующий узел, корневой и т.д.
debi12345 писал(а):Например FOREIGN_KEY не защитит от вставки от имени левого оператора

на каком стращилище ты работаеш? нормальные сервера такое не позволяю
даже если в момент ввода данных ты отключаеш ссылочную целостность (например для ускорения ввода) - то при включении оной тебе вывалится страшная ошибка о нарушении диапазона допустимых значений и всё - либо исправляй данные либо не лезь куда не следует.

debi12345 писал(а):Просто хочу, чтобы человек задумался и не попался на некоторые мифы

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

Сообщение debi12345 » 10.06.2007 01:13:04

Теорию построения индексов я знаю Smile

Не пойму - о чем спорим. Ясен перец, что смысл индекса - в минимизации ввода-вывода. Плюс, сужение диапазона за счет идексации повышает вероятность попадания в кэш, то есть вообще без обращения к диску.
Но одно нужно четко понимать - значение индекса не есть само индексируемое поле ( хотя может быть таким в простейших случаях).

по условиям через индекс выбирается 10 записей - сервер сделает к данным 10 обращений - чтобы отдать тебе найденное.

Если эти 10 записей рассредоточены по всему файлу - тоже тормоза неслабые, тут даже сужение диапазона не слишком помогает. Не такая уж большая разница по скорости для HDD - последовательно выбрать 100000 записей, или по несколько в штук в начале и в конце. Потому что самое большое замедление ( десятки миллисекунд ) - это время позиционирования головок к случайной дорожке.

Ох, помню, - много нового узнал, потратив пару дней на просмотр и настройку планов запросов через "EXPLAIN ANALIZE". Понял, каким же был тупицей, создавая индексы по кодам операторов, по кодам оффисов, по кодам услуг и товаров,... - то есть по тем значениям, которые вводятся изо-дня в день.
Кончилось все удалением 80% индесов, и прибавлением нулевых значений для выключения индексов в некоторых запросах.

на каком стращилище ты работаеш? нормальные сервера такое не позволяю

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

Пред.След.

Вернуться в Lazarus

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

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

Рейтинг@Mail.ru