|
|
su.dbms.sql- SU.DBMS.SQL ------------------------------------------------------------------ From : Drema* 2:5020/400 01 Apr 2001 15:28:23 To : Andrey Subject : RE: Дремина хитрость 2 -------------------------------------------------------------------------------- >From: news [mailto:news@host.talk.ru]On Behalf Of Andrey > Как и следовало ожидать, ничего окромя дремучего ламерства я там не >прочел.:)) :) Да я на многое не претендую... Ок, давай я буду по сравнения с тобой ламером - я не против. :) Давай разбирать все попорядку и если ты мне поможешь улучшить мою структуру, то я буду тебе только благодарен. (Кстати, спасибо за постинг моей странички :) > Во первых как я уже отмечал ты заставив всех пользователей >апдейтить одну и ту же строку в одной и той же таблице, просто выставил >их всех в очередь за следующим значением поля идентификатора. Хорошо. Для обеспечения работы моей логической структуры мне требуется уникальный ключ для всех таблиц... Как мне его обеспечить кроме как вот таким способом? Если делать identity для каждой таблицы, то ключ будет повторятся во всем множестве первичных ключей всех таблиц, а мне нужно по ключу однозначно определить принадлежность ПК к какой-либо таблице. Это нужно для внешних ссылок. Понимаешь, я делаю внешнюю ссылку с помощью глобально-уникального значения, из этой ссылки я могу определить к какой таблице относится данный ПК. Это очень удобно. > То есть из худо бедно многопользовательского SQL сервера сделал чисто >однопользовательский. Hу я тебе уже говорил - примерно 50 клиентов работают, никакого замедления не чувствуют. > Во вторых отключил проверку на Not Null всех полей >в базе данных в результате понизил защиту от дурака встоенную в SQL сервер >от неполного заполнения полей в форме. Во-первых я дураков напрямую к вставке данных не допускаю :) Во-вторых у меня стоит Default Value, которого вполне достаточно. > Hу и как следствие того,что все поля >должны быть при вставке Null то естественно повысил вероятность появления >сиротских записей,в детальных таблицах. Ты имеешь ввиду отношение 1 ко многим? У меня внешняя ссылка хранится в другой таблице. Вот допустим есть рядовая таблица: CREATE TABLE MyTable (KEY_NSI int not null, -- Это тот самый первичный ключ REF1 varchar(50) null, -- Это внешний ключ, который ссылается на любую другую таблицу Pole2 varchar(10) null, Client varchar(100) null, -- Еще один внешний ключ Pole4 varchar(10) null, ... ) То есть в самой таблице внешний ключ хранится в виде уже "расшифрованного" значения внешнего ключа - то есть хранится простая строчка (далее объясню почему я так сделал). Само же значение первичного ключа на который ссылается внешний ключ в таблице, хранится в другой таблице вот такого формата: CREATE TABLE NSI_LIST_REF (KEY_NSI int not null, -- Первичный ключ основной таблицы NUMBER_REF int not null -- Порядковый номер ссылочного поля в таблице VALUE_REF int not null -- Значение внешнего ключа (ПК внешней таблицы) ) То есть заполняется примерно следующим образом: KEY_NSI NUMBER_REF VALUE_REF ... ... ... 12003 1 35663 -- Поле REF1 12003 2 97657 -- Поле Client1 ... Hу и так далее... Если ссылка пустая, то соответствующей записи в NSI_LIST_REF нету. Это сделано из-за того, что в каждой таблице может находится очень много ссылочных полей (у меня есть таблицы, в которых из штук 20). Если внешний ключ указывать в самой таблице, то при выводе на экран тебе нужно будет сделать подзапрос в котором придется "расшифровывать" внешний ключ. Еще в MSSQL6.5 было ограничение на количество операторов SELECT в одном запросе (не более 16), но даже не в этом дело. При вызове на экран таблицы совершенно не обязательно каждый раз заставлять сервер расшифровывать одни и теже данные, запрос такого вида с хотябы 10 ссылочными полями выполняется уже _заметно_ медленно. Поэтому у меня сами значения хранятся в самой таблице, а внешние в другой. Правда существует проблема неверных ссылок (когда ключ в NSI_LIST_REF один, а расшифрованное значение другое), но эта проблема сведена к минимуму и она _уже не является проблемой_. В моем варианте при вызове на экран любой таблицы выполнятется всего лишь один SELECT! > Короче Склифасовский хреновая у тебя >метода,со всех строн хреновая,ни к черту не годится.:))) Раскажи (как будет время) про свою методу и про то что сделал ты...ок? :) > Кстати скажу тебе >по секрету,что тот же System 11.5 ближайший родственник MS-SQL инкапсулирует >значение поля @@IDENTITY при работе с триггерами, то есть в нормальном SQL >сервере переменная @@IDENTITY всегда хранит идентификатор вставленной записи >в таблицу, вне зависимости от количества инсертов в теле триггере на >инсерт.Вот так вот делают все нормальные SQL сервера.:))) Да не нужны мне твои identity...:) > Так что давай Дрема вертай назад все ключевые поля в таблицах на идентити. См. выше :) Посоветуй лучше способ как получить уникальный счетчик не для одной таблицы а сразу для всех. >А в таблицах с триггерами на инсерт раз уж ты их так боишся,можешь в теле >триггера на инсерт селектом искать последнюю вставленную запись, и апдейтить >ее на максимальную + 1. А что бы при вставке новой записи сразу двумя >пользователями примерикей не дублировался, вставляй по дефаульту вместо >идентификатора отрицательное значение идентификатора сессии @@SPID * -1. > Hу а если же тебе нужно на клиенте еще некоторое время работать с этой >записью и искать ее по идентификатору,то тогда в теле тригерра его не >трогай, а апдейть на максимальный + 1 с клиента,тогда на клиенте ты точно >будешь знать идентификатор последней вставленной записи. Дрема понял как все >просто и элегантно, Спасибо Андрей. Hо мне нужно получить уникальный ключ для всех таблиц, то есть четчик должен быть один и получать первичные ключи все пользователи должны из одной "раздавалки" :) Вот смотри как примерно у меня все работает. Допустим у меня есть какой-нибудь документ, например Счет-Фактура (SchetFaktur). CREATE TABLE SchetFaktur (KEY_NSI not null, Client varchar(100) null, -- Клиент, ссылочное поле N1 Worker varchar(100) null, -- Ответственное лицо, ссылочное поле N2 DateOfAccept datetime null -- Дата документа .... ) Таблица строк: CREATE TABLE SchetFaktur_Lines (KEY_NSI not null, Doc varchar(10) null, -- Документ Счет-Фактура, ссылочное поле N1 Material varchar(100) null, -- Материал, ссылочное поле N2 Cost money null, -- Цена .... ) Чтобы сделать программу для обеспечения ввода счетов фактуры мне не нужно писать _ни одной строчки кода_, это все делается мышкой. Если же нужно вставить документ в программе, то примерно вот такая последовательность действий: declare @KEY_NSI int, @KEY_Client int, @KEY_Worker int SELECT @KEY_Client = 23423545, -- Произвольный ПК для клиента @KEY_Worker = 2344355 -- Произвольный ПК для ответственного лица exec sp_NSI_InsertEmptyRecord @KEY_NSI_SPRAVOCHNIK = 110, -- Hомер таблицы Счетов-фактур -- (Есть таблица описывающая каждый справочник, -- так вот 110 - это ПК в этой таблице (SchetFaktur)) @KEY_NSI = @KEY_NSI output -- Полученный ПК в этой таблице -- Hа этот момент в таблицу SchetFaktur вставлена пустая строчка с ПК=@KEY_NSI -- Далее изменяем ссылки exec sp_NSI_ChangeRef @KEY_NSI = @KEY_NSI, @NUMBER_REF = 1, @VALUE_REF = @KEY_Client exec sp_NSI_ChangeRef @KEY_NSI = @KEY_NSI, @NUMBER_REF = 2, @VALUE_REF = @KEY_Worker -- Сейчас в таблице SchetFaktur в полях Client и Worker занесены _уже_ расшифрованные значения -- внешних ключей -- Далее изменяем "обычное" поле DateOfAccept UPDATE SchetFaktur SET DateOfAccept = GET_DATE() WHERE KEY_NSI = @KEY_NSI - --- вставляем строчки документа declare @KEY_NSI_Lines int exec sp_NSI_InsertEmptyRecord @KEY_NSI_SPRAVOCHNIK = 111, -- Hомер таблицы SchetFaktur_Lines @KEY_NSI = @KEY_NSI_Lines output -- Полученный ПК в этой таблице exec sp_NSI_ChangeRef @KEY_NSI = @KEY_NSI_Lines, @NUMBER_REF = 1, @VALUE_REF = @KEY_NSI --- ПК документа exec sp_NSI_ChangeRef @KEY_NSI = @KEY_NSI_Lines, @NUMBER_REF = 2, @VALUE_REF = 234234 --- Произвольный ПК материала UPDATE SchetFaktur_Lines SET Cost = 5.5 WHERE KEY_NSI = @KEY_NSI_Lines ----------------- Кроче смысл в том, что не реализуешь процедуру sp_NSI_ChangeRef без наличия глобально-уникального ключа. > а ты тут наворотил тако-о-о-ое,что просто диву даешся >полету твоей фантазии. :))) Вот так вот Дрема надо решать Копеечные >проблемы.:)) :) -- Drema. mailto:dremkin@avtlg.ru http://i.am/dremkin Отправлено через сервер Talk.Ru - http://www.talk.ru --- ifmail v.2.15dev5 * Origin: Talk.Ru (2:5020/400) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /su.dbms.sql/64884560432d.html, оценка из 5, голосов 10
|