Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Firebird, Interbase > Нагрузка на сеть при использовании Inter Base


Автор: akolit 7.3.2008, 11:41
Эту тему я бы хотел посветить проблеммам правильной работы с сетью.
Вот к примеру!
Есть справочник (с добавлением, удалением и редактированием), и возникает проблемма!
Например два клиента открыли один справочник!
1-й удалил запись "Ставрополь", а 2-й щёлкнул на "Ставрополь" и нажал добавить(в таблицу). Суть проблеммы в том что данные в НД небыли обнавленны и получается что целостность данных нарушенна! (выбран "Ставрополь", но ведт его удалили из справочника!).
Для того чтобы избежать этой проблеммы я написал функцию

String znach;
bool flag=0;

znach="Таблица Справочника"->FieldByName("NAME")->AsString; // сохр. выбранную запись

"Таблица Справочника"->"Транзакция таблици Справочника"->Commit(); // закр. нд
"Таблица Справочника"->Active=true; // откр. нд
while (!"Таблица Справочника"->Eof) //сканируем нд
{
if ("Таблица Справочника"->FieldByName("NAME")->AsString==znach) //ищем сохр-ю запись
flag=1; //найденна
"Таблица Справочника"->Next();
}//while
if(!flag) //если не найденна
MessageBox(Handle,"Запись была удаленна др. пользователем","Ошибка!", MB_OK);
}

(вообще можно использовать поиск по нд, но суть не в этом, ведь всёравно будет сканироваться вся нд).
Суть функции в том, что при попытки выбрать из справочника и добавить запись кудато, программа закрывает нд (commit - подтверждение транзакции), затем открывает и проходит по всем уже новым записям (если было удаление др. клиентом то теперь видно), и если не находит данную, то выдаёт ошибку, после которой пользователь в справочнике видит обнавлённые данные.
Ну так вот у меня вопрос! На сколько это приемлимо с точки зрения нагрузки на сеть? Можно ли так делать? Надоли делать по другому? Как делаете вы?
Зарание спасибо!

Автор: Deniz 7.3.2008, 13:06
Цитата(akolit @  7.3.2008,  14:41 Найти цитируемый пост)
и получается что целостность данных нарушена!
целостность надо поддерживать на уровне БД, т.е. например,
 - нельзя удалить запись из справочника если в других таблицах есть записи с таким кодом.
 - нельзя добавить запись в таблицу с кодом, которого нет в справочнике
 - и т.д.
В обоих случаях получаем Exception, и корректно даем пользователю понять что произошло.
Это в двух словах, а еще есть куча материала на эту тему.

Автор: Akella 7.3.2008, 22:00
я в своих приложениях всегда справочники от простых смертных прячу или права даю только админам, мало того, справочники - такая вещь, что редактируются весьма редко, а поэтому лучше задуматься о проблемах более насущных

Добавлено через 1 минуту и 25 секунд
Цитата(akolit @  7.3.2008,  11:41 Найти цитируемый пост)
1-й удалил запись "Ставрополь",

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

Автор: akolit 8.3.2008, 11:28
ТС! Вы не поняли суть! Мы мутим что при редактировании или удалении записи из справочника, прога сканирует все записи таблицы с этой записью и изменяет на введённый вариант! Для этого будет использоваться функция как та которую я написал при открытии этой темы. Мне просто интересно, так можно делать? то что прога будет шибуршить по всей базе, от начала и до конца?

Автор: Fortop 8.3.2008, 19:12
Цитата(akolit @  8.3.2008,  11:28 Найти цитируемый пост)
Мне просто интересно, так можно делать? то что прога будет шибуршить по всей базе, от начала и до конца? 

А зачем чему-то вообще шебуршить?

У тебя в справочнике должен использоваться ID записи, а "Ставрополь" и прочая информация может свободно редактироваться (выборки будут извлекать нужную информацию из справочника пользуясь ID, который останется тем же самым).

Вот при удалении - да. Возможны нюансы.

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

А периодически всего лишь чистить мусор в таблицах (что вполне может выполнять админ)

Автор: Akella 10.3.2008, 21:24
Почему  клиент должен "шабуршить"? А что, сервер не может? Ты должен только сказать серверу, что хочешь выполнить такую-то процедуру.... и всё

Автор: akolit 12.3.2008, 09:46
Akella! Кажись понял тебя, видимо надо тригер на удаление написать!

Fortop Спасибо! Токо у меня тода проблемма как по ID справочника, которое записывается в главную таблицу выдать в главной таблице например поле город из справочника? Это типо подстановачное поле как я понял.......

Добавлено через 1 минуту и 19 секунд
Если сервером, то какой код SQL?

Автор: Akella 12.3.2008, 12:20
Цитата(akolit @  12.3.2008,  09:46 Найти цитируемый пост)
как по ID справочника, которое записывается в главную таблицу выдать в главной таблице например поле город

читай про соединения, JOIN`ы спасут отца русской демократии smile 

Добавлено @ 12:23
Код

select t1.id, t1.text, n.name from treklama t1
left JOIN
tnapr n on (n.id = t1.id_napr)


tnapr - справочник
treklama основная таблица, в которой хранится поле id_napr (т.е. как бы ссылка на поле id из tnapr)

Автор: Fortop 12.3.2008, 19:05
Цитата(akolit @  12.3.2008,  09:46 Найти цитируемый пост)
Fortop Спасибо! Токо у меня тода проблемма как по ID справочника, которое записывается в главную таблицу выдать в главной таблице например поле город из справочника? Это типо подстановачное поле как я понял.......

Можно как предложил Akella Join использовать
а можно подзапросы. Судя по тому что показывает IB Expert - особой разницы нет.

Код

select 
    treklama.id, 
    treklama.text, 
    (select n.name from tnapr where treklama.id_napr = tnapr.id) as ktoto
from  treklama


Добавлено через 7 минут и 43 секунды
Да, и обратный запрос о котором я говорил. Т.е. если из справочника что-то ты удалил, а в treklama есть записи с удаленным ID

То в этот запрос она не попадет.
Код

select 
    tnapr.name,
    (select treklama.id from treklama where tnapr.id = treklama.id_napr) as id_treklama,
    (select treklama.text from treklama where tnapr.id = treklama.id_napr) as text_treklama
from tnapr

Автор: Akella 13.3.2008, 09:30
Цитата(Fortop @  12.3.2008,  19:05 Найти цитируемый пост)
Т.е. если из справочника что-то ты удалил, а в treklama есть записи с удаленным ID

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

Автор: Akella 13.3.2008, 15:11
если не будешь делать ссылочную целостность, то не забудь сделать индексы для полей ГЛАВНОЙ таблицы, которые ссылаются на ID справочников

Автор: Deniz 13.3.2008, 15:37
Цитата(Akella @  13.3.2008,  18:11 Найти цитируемый пост)
если не будешь делать ссылочную целостность
не надо такое советовать, там же потом такоооой бардак будет. Это же мина замедленного действия. Даже если попытаться все это реализовать на триггерах.

Автор: Akella 13.3.2008, 21:22
я не советую, я предостерегаю smile 

Автор: akolit 15.3.2008, 23:36
Спасыбо! Ну а мы в общем пока зделали так, что главная таблица содержит поле связанное с индесом справочника, а в BUILDERE замутили new fild, и выбрали тип подстановочное и там усё настроили (что оно должно из справочника брать поле name из из записи с нужным id )

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