|
|
su.dbms.sql- SU.DBMS.SQL ------------------------------------------------------------------ From : Drema* 2:5020/400 09 Apr 2001 20:32:15 To : All Subject : FW: Дремина хитрость 2 -------------------------------------------------------------------------------- Мда... newmail.ru - хороший сервер, неделю письмо ходило, ходило, так и не дошло...:) Перепосылаю: >From: news [mailto:news@host.talk.ru]On Behalf Of Ilya Zvyagin >>идет __исключительно__ через нормализированные ссылки. >ОК можно еще запросы и структуру ? Ок, попытаюсь... [кстати, хотелось бы услышать ото всех как у них реализована структура серверной части и клиентской, если не сложно - расскажите] БД состоит из ядра (некий набор таблиц и процедур) и пользовательских таблиц и процедур. Само ядро служит для хранения описаний связей между пользовательскими таблицами, а также их специфические свойства, включая типы данных полей. То есть главной целью ядра является описание действий программы интерфейса по отображению той или иной таблицы, а также реализация отношений между ними (1 ко многим). Все пользовательские таблицы нумеруются уникальным номером. Чтобы интерфейсная программа могла отобразить любую таблицу ей достаточно указать номер таблицы. Из этого номера с помощью ядра можно получить полную информацию о таблице и легко составить SQL оператор для выборки из этой таблицы. Зачем это нужно? Главная задача: Реализация элементарных функций [вставки, редактирования, удаления, выборки, сортировки, фильтрации, любых реляционных отношений] ОДИH РАЗ, это касается и клиентской части и серверной части. То есть чтобы обеспечить минимальную функциональность некой задачи, достаточно описать все таблицы ее, указать ихние поля и указать связи между таблицами - все что касается вышеперечисленных элементарных функций УЖЕ написано... и уже этой минимальной функциональности для _многих_ задач вполне достаточно. Структура БД: Таблица, которая содержит список пользовательских таблиц: create table NSI_SPRAVOCHNIK( KEY_NSI_SPRAVOCHNIK int identity, name varchar(), -- Имя физической таблицы nameRus varchar(), -- Имя русское ... -- и тп... ) Первичный ключ этой таблицы и есть номер пользовательской таблицы. Таблица, которая содержит поля пользовательских таблиц: create table NSI_FIELDS( KEY_FIELDS int identity, KEY_NSI_SPRAVOCHNIK int, -- Ссылка на NSI_SPRAVOCHNIK name varchar(), -- Имя физического поля nameRus varchar(), -- Имя русское typeField int, -- Тип поля (0 - int, 1 - varchar, 2 - ссылка, 3 - список, 4- вычисляемое) ... -- number_ref int, -- Hомер ссылочного поля если поле ссылка tableid int, -- номер пользовательской таблицы, на которую ссылка происходит refField, -- SQL выражение ссылочного поля ... SQLoperator, -- SQL оператор если поле вычисляемое, -- то есть этот оператор подставляется автоматически -- при составлении SELECT на клиенте... Причем -- если организована денормализованная ссылка, -- то это значение считается только один раз -- и больше не пересчитывается. ... -- и тп [DisplayFormat, Readonly ... ] ) Hу короче эти две таблицы описывают все пользовательские таблицы. К этим таблицам также привязаны таблицы прав доступа. Каждая пользовательская таблица обязана содержать первичный ключ и имеет следующий формат: create myTable( KEY_NSI int not null, .... -- любое количество других полей ) Ссылка организуется следующим образом: INSERT NSI_SPRAVOCHNIK (name, nameRus ...) VALUES ('myTable', 'Моя таблица', ...) -- допустим код таблицы присвоился 5 INSERT NSI_FIELDS (KEY_NSI_SPRAVOCHNIK, name, nameRus, typeField, TableId, refField ...) VALUES (5, 'Client', 'Клиент', 2, 333, 'name', ...) -- 333 - код таблицы клиентов INSERT NSI_FIELDS (KEY_NSI_SPRAVOCHNIK, name, nameRus, typeField, TableId, refField ...) VALUES (5, 'Person', 'Персонал', 2, 444, 'f+'' ''+substring(i,1,1)+''.''+substring(o,1,1)+''.''', ...) -- 444 - код таблицы персонала create myTable( KEY_NSI int not null, ... Client int null, Person int null, .... -- любое количество других полей ) Hа выборку клиентская программа автоматически на основе информации из ядра генерирует запрос вида: SELECT (SELECT Client.name FROM Client Client WHERE Client.KEY_NSI = NSI.Client) as Client, (SELECT Person.f+' '+substring(Person.i,1,1)+'.'+substring(Person.o,1,1)+'.' FROM Person Person WHERE Person.KEY_NSI = NSI.Person) as Person, ... прочие поля FROM myTable NSI option (fast 30) если осуществляется фильтр, то делается так: SELECT (SELECT Client.name FROM Client Client WHERE Client.KEY_NSI = NSI.Client) as Client, (SELECT Person.f+' '+substring(Person.i,1,1)+'.'+substring(Person.o,1,1)+'.' FROM Person Person WHERE Person.KEY_NSI = NSI.Person) as Person, ... прочие поля FROM myTable NSI WHERE NSI.Person IN (SELECT Person.KEY_NSI FROM Person Person WHERE Person.f like 'Иванов%') option (fast 30) Hу и так далее... Это вариант с нормальной :) ссылкой. Работает вполне хорошо, не жалуюсь - индесы и прочее все в порядке... но иногда отклик сервера на запрос превышает некий максимальный предел, установленный моими заказчиками. Для денормализированного варианта требуется еще одна таблица из ядра: create NSI_LIST_REF( KEY_NSI int not null, NUMBER_REF int not null, VALUE_REF int not null) Первое поле - ПК таблицы Второе - номер ссылочного поля (внутри одной пользовательской таблицы должен быть уникальным) Третье - ПК таблицы, на который ссылается это поле. Вот как выглядит пользовательская таблица: create myTable( KEY_NSI int not null, ... Client varchar(100) null, Person varchar(100) null, .... -- любое количество других полей ) чтобы создать ссылку, нужно вызвать: sp_nsi_change_ref @KEY_NSI = 343434, -- ПК строчки в MyTable @Number_ref = 1, -- порядковый номер ссылки в таблице -- например для Client равно 1, а для Person равно 2 и тд. @value_ref = 454545 -- ПК таблицы куда ссылаемся Эта процедура заносит в поле Client значение ссылки и вставляет строчку в NSI_LIST_REF следующего содержания: INSERT NSI_LIST_REF VALUES (343434,1,454545) Клиентская программа для выборки генерирует следующий SQL: SELECT KEY_NSI, Client, Person, ... FROM MyTable Для "бегания" по ссылкам, применяется следующий метод: SELECT Person.f, Person.i, Person.o, ... FROM MyTable MT, NSI_LIST_REF NLR, Person Person WHERE MT.KEY_NSI = NLR.KEY_NSI AND NLR.NUMBER_REF = 1 AND NLR.VALUE_REF = Person.KEY_NSI Работает мгновенно. >>Меня не интересует общее время выполнения, меня интересует время >>через которое пользователь видит строчки информации у себя на экране. >>Сколько? >Справочники вообще -то можно один раз прочитать и больше не ходить на сервер >вообще. Ты так делаешь? -- 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/648830da5c0f.html, оценка из 5, голосов 10
|