Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2009.12.20;
Скачать: [xml.tar.bz2];

Вниз

Удаление большого количества записей firebird 1.5   Найти похожие ветки 

 
PEAKTOP ©   (2009-10-29 05:57) [40]

> Есть ли задачи где query не эффективен или мало эффективен
> по сравнению с table?
>
> P.S. программирование не является приоритетным направлением,
>  есть несколько разработанных локальных БД на paradox...
>  по большей части для души...


В том то и проблема, что в голове Paradox. Paradox является файловой БД, в которой единицей хранения информации является файл таблицы. Оттого и такая философия работы. TTable открывает доступ к файлу через BDE-API, оттого он (компонент) такой быстрый.

Firebird является потомком (1.5) и внуком (> 2.0) InterBase и философия работы с ним совершенно другая. На сервер передаются запросы (команды SELECT) и команды (INSERT/UPDATE/DELETE), а сервер сам уже управляет данными. Т.е. ни одна из API-функций сервера не имеет доступа к данным, они лишь передают команды серверу, а сервер сам управляет физически файлом базы данных. Поэтому базовым компонентом для работы с базами данных Firebird является TIBSQL, т.е. - "простая команда".

Далее - есть класс TIBCustomDataSet, который инкапсулирует пять классов TIBSQL для формирования набора данных, привычного для философии Delphi. Почему именно пять ?
SelectSQL - для команды SELECT, которая возвращает набор данных.
RefreshSQL - почти идентична команде SelectSQL, необходима для того, чтобы перезагрузить с сервера текущую запись набора данных, если она была изменена.
InsertSQL/UpdateSQL/DeleteSQL - для того, чтобы управлять изменениями в наборе данных.

От класса TIBCustomDataSet порождены классы TIBDataSet, TIBTable, TIBQuery, TIBStoredProc. Наиболее полный доступ к возможностям класса TIBCustomDataSet открывает класс TIBDataSet, позволяя управлять всеми пятью командами SQL. Класс TIBQuery - поскромнее, он позволяет управлять только командой SelectSQL. Класс TIBTable вообще маскирует работы команд SQL, эти команды просто автоматически формируются "внутри" класса таким образом, что у тебя возникает иллюзия будто бы компонент действительно физически работает с таблицей. Нет никакой таблицы. ("Нет никакой ложки..." бу-го-га!) Есть пять команд SQL, которые трудятся в фоне и создают для тебя иллюзию.

Для чего его тогда придумали ? Чтобы программистам в далеком 1999 году с появлением Delphi 5 было легче сломать старые стереотипы программирования, чтобы было перевести свои старые приложения с BDE-архитектуры на архитектуру компонентов IBX (и убедиться, что старая философия программирования, основанная на TTable, в IBX никуда не годится).

Поэтому сравнивать производительность двух классов потомков от одного класса предка - не совсем корректно, т.к. можно привести примеры "в любую сторону", в зависимости от желаемого результата и кривизны рук.


 
Inovet ©   (2009-10-29 06:00) [41]

> [39] Dim!S   (29.10.09 05:05)
> Есть ли задачи где query не эффективен или мало эффективен
> по сравнению с table?

внутри TIBTable в отличии от для Парадокса TTable всё равно вся работа ведётся через SQL запросы, есть TIBDataSet.


 
Dim!S   (2009-10-29 06:23) [42]

Спасибо, в принципе понятно...
Думаю при возникновении задачи с использованием сети буду копать только в сторону query...

И всё же (ради любопытства) как удалить кждую n-ю запись с помощью IBQuery?


 
Сергей М. ©   (2009-10-29 08:15) [43]


> Dim!S   (29.10.09 03:02) [33]


Я надеюсь, ты в курсе, что метод Delete после успешного удаления тек.записи автоматически двигает курсор к следующей существующей записи и, если таковой нет (т.е. достигнут конец НД), взводит флаг EOF ?


 
Sergey13 ©   (2009-10-29 09:01) [44]

> [42] Dim!S   (29.10.09 06:23)
> И всё же (ради любопытства) как удалить кждую n-ю запись с помощью IBQuery?

Так
> [34] PEAKTOP ©   (29.10.09 03:40)

даже код тебе дал. Тебе надо обдумать и модифицировать только фразу WHERE (TB1.FIELD = ...) AND (TB1.FIELD2 = ...). Но для того что бы это сделать надо понять что тебе надо. А ты это упорно скрываешь, как партизан. Чем твое "прореживание" лучше чем например "удалить все данные с датой, меньшей чем начало текущего квартала" например? Как обеспечивается порядок записей в твоей ТТабле?


 
RWolf ©   (2009-10-29 10:04) [45]


> И всё же (ради любопытства) как удалить кждую n-ю запись
> с помощью IBQuery?

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


 
Dim!S   (2009-10-29 10:11) [46]

"если таковой нет (т.е. достигнут конец НД), взводит флаг EOF" вот про это не знал... :(
Чем твое "прореживание" лучше оно не лучше, оно ДРУГОЕ, а если необходимо чтобы записи остались и до начала текущего квартала?
Порядок записей по ID (автоинкремент).

P.S. прореживать будем по условию (придумаем чего-нибудь), но вариант с удалением каждой кроме N записи интересен гипотетически...


 
Anatoly Podgoretsky ©   (2009-10-29 10:33) [47]


> На 12(!) посте была попытка намекнуть на то, что пора бы
> уже открыть для себя SQL-оператор DELETE, но все присутствующие
> ее упорно игнорируют и продолжают рассматривать варианты
> с шести и семиугольными колесами...

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


 
Dim!S   (2009-10-29 10:50) [48]

Меня разделывать? за что??? :)

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

Ок, путь понятен, осталось снарядиться и можно двигаться по нему...

Всем большое спасибо.


 
RWolf ©   (2009-10-29 11:17) [49]


> а разве записи в таблице идут не в порядке в каком они добавлены
> (без испоьзования сортировки, естественно)?

нет, никаких предположений о порядке хранения записей делать нельзя.


 
Сергей М. ©   (2009-10-29 11:26) [50]


> разве записи в таблице идут не в порядке в каком они добавлены


Нет, не идут.
И не обязаны идти.
Куда их сервер соизволит разместить - там они и будут жить.


 
Anatoly Podgoretsky ©   (2009-10-29 11:33) [51]


> Меня разделывать? за что??? :)

Да не тебя.


 
Dim!S   (2009-10-29 17:19) [52]

Удаление через IBQuery работает на порядок быстрее IBTable... заинтересовался... :)

Простой запрос удаляет ненужные записи из таблицы, а вот как усложнить условие не знаю пока...
Что-то типа этого:
DELETE xx FROM T1
WHERE xx=(
 select T1.F1
 from T1, T2
 where
 (cast(T1.F2 as integer) between 50 and 90) AND
 (T1.F3=T2.F1) AND
 (T2.F3=100)

T1.F3 - внешний ключ на T2
T2.F1 - ключевое поле второй таблицы

или надо использовать хранимые процедуры? Но в БД я их интегрировать, скорее всего, не смогу (запаролена БД)...


 
Сергей М. ©   (2009-10-29 20:28) [53]


> Dim!S   (29.10.09 17:19) [52]


Так это уже совсем другая грядка и совсем другие морковки)


 
RWolf ©   (2009-10-30 01:33) [54]


> Что-то типа этого:

да, что-то вроде.
только WHERE xx IN (...) .


 
Dim!S   (2009-10-30 07:37) [55]

Именение запроса
DELETE xx FROM T1
WHERE xx=(
select T1.F1
from T1, T2
where
(cast(T1.F2 as integer) between 50 and 90) AND
(T1.F3=T2.F1) AND
(T2.F3=100)

на
DELETE xx FROM T1
WHERE xx in (
select T1.F1
from T1, T2
where
(cast(T1.F2 as integer) between 50 and 90) AND
(T1.F3=T2.F1) AND
(T2.F3=100)

приводит к сообщению об ошибке Between. Может надо переменную xx описать? Как это сделать?
Спасибо.


 
Dim!S   (2009-10-30 07:55) [56]

Пробую в IBExpert 4.5 (самая свежая с сайта)


 
sniknik ©   (2009-10-30 08:01) [57]

> Может надо переменную xx описать? Как это сделать?
поменял вопрос, но не поменял стиль... по статье, ты опять не говоришь "мне надо сделать X", а начинаешь с того, что "как  делать Y?" которое уже следствие твоих умозаключений как делается X, а делать Y бессмысленно, описывать переменную xx глупо, по всем признакам она у тебя уже должна быть, и должна быть не переменной а полем таблицы T1, иначе весь запрос теряет смысл (а то что ты делаешь мы не видим, ты не сказал, мы видим только бессмысленный запрос который к тому же дает неизвестную (не показанную тобой) ошибку).
и что на это можно сказать "Как это сделать?" единственный остающийся рабочий вариант как это делается - приглашается ПРОГРАММИСТ, и говорится ему "напишите программу". вариант самому у ТЕБЯ не получится.


 
Dim!S   (2009-10-30 08:18) [58]

что непонятно?
удалить надо из таблицы T1 записи по определённому условию. НЕ каждую n-ю!

Есть несколько таблиц. В таблице T1 есть поля связанные со справочными по внешнему ключу.

Пример:
TOrders
ID
ShopID
ClientID

TShops
ID
Name

TClients
ID
FIO

Необходимо из TOrder удалить записи конкретного магазина и конкретного клиента. Как сделать это чере запрос не знаю.


 
Dim!S   (2009-10-30 08:19) [59]

в предыдушем посте: T1 заменить на TOrders


 
Sergey13 ©   (2009-10-30 08:53) [60]

> [58] Dim!S   (30.10.09 08:18)

Судя по названиям таблиц ты пишешь какой то DB-вирус или иную вредилку. "Прореживать" таблицу заказов - это знаете ли на статью со ссылкой может потянуть. Причем далеко не интернетовские.


 
Dim!S   (2009-10-30 11:08) [61]

>Sergey13
Я знаю на что может потянуть прореживание заказов ;)
но! почему вы опираетесь на мой пример :) право? смешно... :) кто Вам сказал что будет прореживаться БД торговли или иной сферы?
Я не настолько наивен чтобы лезть в инет с просьбой: помогите почистить торговую базу :) И не связываюсь с "мутными" способами заработка...

Уважаемые форумчане!
Давайте по существу вопроса, пожалуйста...


 
Sergey13 ©   (2009-10-30 11:20) [62]

> [61] Dim!S   (30.10.09 11:08)
> но! почему вы опираетесь на мой пример

А на что опираться? Только на свой телепатор. Больше не на что. Ты же молчишь как партизан.
Зачем вообще тебе нужно удалять записи из и так небольшой таблицы? Тем более по так и не сформулированному тобой условию. Место на диске экономить что ли? Так места на диске после просто удаления записей не прибавится.


 
Anatoly Podgoretsky ©   (2009-10-30 12:32) [63]

> Dim!S  (30.10.2009 11:08:01)  [61]

> И не связываюсь с "мутными" способами заработка...

Все так говорят.


 
sniknik ©   (2009-10-30 13:12) [64]

> что непонятно?
> удалить надо из таблицы T1 записи по определённому условию. НЕ каждую n-ю!
"определённому условию" непонятно.

> Необходимо из TOrder удалить записи конкретного магазина и конкретного клиента. Как сделать это чере запрос не знаю.
а вот это уже конкретное условие... (похоже на Х)
DELETE FROM TOrders WHERE ShopID = (SELECT ID FROM TShops WHERE Name = "конкретный магазин") AND ClientID = (SELECT ID FROM TClients WHERE Name = "конкретный клиент")


 
sniknik ©   (2009-10-30 13:18) [65]

> помогите почистить торговую базу :)
а почему нет? я неоднократно чистил торговые базы... мне их специально присылали. вполне нормальное занятие, если чистить от мусора, или старый период, или... любой критерий заказчика, но не "каждую пятую" при том что порядка нет, это глупо, а вот от дублей, хотя это почти как "каждую вторую" нормально (а если дублей 5 то еще более похоже но не одно и тоже).


 
Dim!S   (2009-10-30 15:28) [66]

Условия выборки для удаления прояснились :)

Меня сначала ввели в заблуждение... На самом деле так:
Фирма разделилась, клиенты тоже поделились, хозяева хотят разделить базу и оставить в "своей" базе проводки только по "своим" клиентам...

Извините, за ввод в заблуждение...

P.S. "Все так говорят." - ну так я не утверждаю что я "белый и пушистый", но пусть в меня кинет камень Честый Человек. Только барон Мюнхгаунзен тоже был честным человеком ;). А с реально мутными делами я не связываюсь... - дороже выйдет...


 
Dim!S   (2009-10-30 15:30) [67]

Забыл...
>sniknik Большое спасибо...

Думаю "плотненько" заняться FireBird. Пора переходить к клиент-серверным платформам :)

P.S. - программирование - не основной мой вид деятельности, но очень интересно...


 
Sergey13 ©   (2009-10-30 15:45) [68]

> [66] Dim!S   (30.10.09 15:28)
> Фирма разделилась, клиенты тоже поделились, хозяева хотят
> разделить базу и оставить в "своей" базе проводки только
> по "своим" клиентам...

Настроить (возможно временно, потом отключить) каскадное удаление по внешним ключам и удалить "не своих" клиентов. Просто в справочнике клиентов. Без всякого дополнительного программирования.


 
Dim!S   (2009-10-30 15:52) [69]

Это идея, но, боюсь, пока сложновато будет разобраться в этом... Если кинете скелет или поподробнее объясните, то займусь этим вариантом...


 
Anatoly Podgoretsky ©   (2009-10-30 16:18) [70]

> Sergey13  (30.10.2009 15:45:08)  [68]

Это если база построена правильно и есть признак свой/чужой (ну это исправимо), но вот что они будут делать, если клиент будет относиться к обеим фирмам и разделить проводки будет непросто.


 
Sergey13 ©   (2009-10-30 16:31) [71]

> [69] Dim!S   (30.10.09 15:52)

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

> [70] Anatoly Podgoretsky ©   (30.10.09 16:18)

Как по мне - я бы вообще ничего не удалял. Мне бы без разницы - ну есть клиент в справочнике, ну есть у него проводки за ПРОШЛЫЕ времена - это никому вроде как не мешает.


 
Anatoly Podgoretsky ©   (2009-10-30 16:35) [72]

> Sergey13  (30.10.2009 16:31:11)  [71]

> но жутко мощная - можно одним запросом всю БД грохнуть.

Надо только ключевой точке ударить, например по OrganisationID с настроеным каскадом.


 
Anatoly Podgoretsky ©   (2009-10-30 16:37) [73]

> Sergey13  (30.10.2009 16:31:11)  [71]

> иначе отвалится запрос с ошибкой.

Хуже, останутся потеряные записи без связей - жуткое дело.


 
Sergey13 ©   (2009-10-30 16:53) [74]

> [73] Anatoly Podgoretsky ©   (30.10.09 16:37)

Это если есть "умозрительные" FK поддерживаемые из клиента. Да, безхозные записи - штука та еще.


 
Anatoly Podgoretsky ©   (2009-10-30 16:57) [75]

Если делать не удаление, а копирование в две базы с учетом бизнес логики, то задача имеет решение, но не всегда бизнес логика доступна или понятно, но по крайней мере это путь без последствий.


 
Dim!S   (2009-10-30 16:57) [76]

Да уж.. записи без связей это тот ещё мусор... и ГЛЮКИ!

Запрос под нужные критерии доработал, условия усложнил, добавил дополнительные критерии... :) Вроде работает, буду тестировать тщательно

Запрос на удаление сотен тысяч записей работает очень шустро..., конечно доп условия замедлили, но IBTable просто помирал на более простом условии...

P.S. база не очень сложная по структуре... несколько лет назад разработана... вроде косяков по ключам нет, но бэкапов наделал с помощью gbak ;)


 
Anatoly Podgoretsky ©   (2009-10-30 16:59) [77]

Продумай вариант с копирование.


 
Sergey13 ©   (2009-10-30 16:59) [78]

> [76] Dim!S   (30.10.09 16:57)
> но бэкапов наделал с помощью gbak ;)

Проверял бекапы то? А то неподнимаемый бекап - это посильнее безхозных записей будет. 8-)


 
Dim!S   (2009-10-30 17:09) [79]

проверю ОБЯЗАТЕЛЬНО, неподнимаемый бэкап - это куча седых волос и ... ;)

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



Страницы: 1 2 вся ветка

Форум: "Начинающим";
Текущий архив: 2009.12.20;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.64 MB
Время: 0.006 c
11-1163789456
SKA1997
2006-11-17 21:50
2009.12.20
Форма прозрачная для кликов


1-1229369606
Zilog
2008-12-15 22:33
2009.12.20
TListView - где это событие найти?


2-1257213337
sideX
2009-11-03 04:55
2009.12.20
2 вопроса по TWebBrowser


2-1257241538
EH
2009-11-03 12:45
2009.12.20
Поиск и замена в Excel


2-1257079212
petaywww
2009-11-01 15:40
2009.12.20
С помощью каких компонентов легче и правильней реализовать данную





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский