Ну всё гуру, хватит глумиться,я попробовал,осознал поправил что надо.CyberMax писал(а):Поддержу Merlin'а. Почти с самого начала работы с БД тоже полностью отказался от естественных ключей для ПК и ВК. И серверу проще интеджеры пережевывать, и база наглядней и прочая... В книжках по БД теорию пишут, которая, как известно, от практики отличается.
Одна таблица или две?
Да брось ты. Глумятся над нечитателями доки. Если человек чего не понял - дружески посмеиваются, не без этого. Учти только, что замена естественного композита в ПК-ФК на один искусственный инт вообще-то может быть чревата, если по логике предметной области и реализации интерфейса допустимы апдейты естественных полей связи. Можно, но осторожно и только если одновременный доступ таких функций к связанным записям в разных транзакциях исключён.
Это вполне понятно, я учёл это поэтому поправил только то что нужно . А тема пока остаётся открытой... Немного переформулирую вопрос: LOG (или история) разных событий. Есть некоторый объект с набором характеритик (состояний),в моём случае это запись в таблице ITEMOBJ... с уникальным ID и другими полями таблицы описывающими этот экземпляр,есть справочник событий (о нем я попозже спрошу ). Есть табличка HISTOBJ.. очень похожая на ITEMOBJ... но с дополнительными полями КТО,КОГДА ЗАЧЕМ,ПОЧЕМУ и ЧТО сделал. Как грамотно сделать лог действий юзера???? Мой вариант: после выполнения какого то действия апдейтить новыми значениями в ITEMOBJ нужные поля и вставлять в HISTOBJ КТО,КОГДА...это действие сделал и какие новые значения он внес. Следственно остальные поля таблицы HISTOBJ... останутся пустыми(NULL),так как размножать все значеия ITEMOBJ в HISTOBJ получится громостко,хотя тоже имеет смысл- можно узнать всё состояние на лубой момент времени.kdv писал(а):чего уж подробней. извечная проблема естественных ключей - если они меняются, все ссылки на такой ключ также должны меняться. то есть каскадный update во всей красе.
а с искуственными ключами каскадный update не нужен, ибо ЕК менять нет смысла, и живет он от insert до delete без изменений.
Есть ли предложения по грамотному ведению истории???
Простейший пример. Транспортная партия (грузовик с товаром)
в варианте 2 сервер не будет сопротивляться изменению ID товара (исправление ошибки регистрации например) без предварительного снятия (возврата на склад) резервов. Что чревато - если в приложении есть ошибки по обслуживанию такой функции, то может получиться так, что резерв в составе ТП будет стоять совсем не на тот товар, который данному покупателю был нужен. Также можно и ошибиться при "ручной" правке данных в аварийных режимах мимо приложения. Так что если такие апдейты полей связи, замещаемых искусственным ключом "для простоты" предполагаются постановкой, то лучше (надёжнее) придерживаться всё-таки более трудоёмкого в писании запросов классического варианта 1.
Добавлю - все ключи здесь "искусственные", то есть синтетические инты, в обоих вариантах. Естественные во всей красе имхо блажь. Это к вопросу о дальнейшей "искусствизации" с целью борьбы с длиной композитных искусственных по природе, но естественных по структуре связи ключей и где она допустима, а где нет.
Код: Выделить всё
Заголовок
ID Primary
Атрибуты
Товарный состав
ID Primary
ID_ТП Foreign Заголовок и первый сегмент Unique
ID_Товара Foreign товары и второй сегмент Unique
Количество
Состав порезервно
(одна товарная позиция для нескольких получателей)
Вариант 1
Трёхсегментный Primary и ФК на товарный состав по Unique
ID_ТП
ID_Товара
ID_Получателя
Количество
Вариант 2
Двухсегментный Primary и ссылка на товарный состав по Primary
ID_Товарного состава
ID_Получателя
Количество
Добавлю - все ключи здесь "искусственные", то есть синтетические инты, в обоих вариантах. Естественные во всей красе имхо блажь. Это к вопросу о дальнейшей "искусствизации" с целью борьбы с длиной композитных искусственных по природе, но естественных по структуре связи ключей и где она допустима, а где нет.
оч. тонкий момент. особенно в смысле "узнать". Например, при изменении реквизитов фирмы что делать со старыми договорами? Для них должны быть старые реквизиты, или новые? История изменений нужна зачем - для оперативных расчетов (типа курс валюты на дату), или просто для логирования действий пользователей?можно узнать всё состояние на любой момент времени.
В обычных системах это разруливается на уровне конкретной сущности или доп-сущности специально для "истории".
У тебя же нечто вроде объектного слоя, как я понял. Здесь может быть туча вариантов - у меня в системе было сделано "версионирование". То есть старый документ мог остаться на своем месте, новые ссылки шли на новый.
Есть решения, когда изменения кидают в xml, и хранят в blob (есть статья на сайте). Но в любом случае мне кажется, что лепить сами изменения в таблицу лога "событий" - нехорошо. Особенно если у разных объектов разные атрибуты (и их число произвольное).
Хорошо пользователям Lotus Notes - там документ имеет GUID, и изменения пишутся только по измененным столбцам. Вот...
Если без версий объектов, то (упрощённо опять же) можно так:
Код: Выделить всё
/* Пользователи */
create table OBJ_USERS(
ID integer not null primary key,
Name varchar(100)
);
/* Собственно объекты */
create table OBJECTS(
ID integer not null primary key,
Name varchar(100)
);
/* Свойства объектов (может быть разное кол-во) */
create table OBJ_ITEMS(
ID integer not null primary key,
ParentID integer not null foreign -> OBJECTS.ID,
Name varchar(100)
);
/* Справочник событий */
create table OBJ_EVENTS(
ID integer not null primary key,
/* ParentID тут нужен только в случае если события не "общие" а зависят от объекта */
ParentID integer not null foreign -> OBJECTS.ID,
Name varchar(100)
);
/* Собственно история */
create table OBJ_HISTORY(
DateRec date not null,
ObjectID integer not null foreign -> OBJECTS.ID,
EventID integer not null foreign -> OBJ_EVENTS.ID,
UserID integer not null foreign -> OBJ_USERS.ID
);
Последний раз редактировалось WildSery 01 сен 2006, 13:21, всего редактировалось 1 раз.
Это сложный вопрос, думаю что нужны новые реквизиты,но с другой стороны окажется невозможным поднять старые договора,думаю, что буду делать лог договоров вместе с реквизитами.kdv писал(а): Например, при изменении реквизитов фирмы что делать со старыми договорами? Для них должны быть старые реквизиты, или новые?
История нужна для сбора статистики,т.е. для логирования действий и входных данных с которыми выполняется действие,при этом результаты(выходные данные) действия можно получить в любой момент взяв сохранённые в истории данные и выполнив над ним действие,которое тоже как известно лежит в логе.kdv писал(а): История изменений нужна зачем - для оперативных расчетов (типа курс валюты на дату), или просто для логирования действий пользователей?
В точкуkdv писал(а): У тебя же нечто вроде объектного слоя, как я понял.
"версионирование" есть,как для объектов,так и для действий. А хранение изменнений в BLOB,не очень то удобно для сбора статистики.kdv писал(а): у меня в системе было сделано "версионирование". То есть старый документ мог остаться на своем месте, новые ссылки шли на новый.
Есть решения, когда изменения кидают в xml, и хранят в blob (есть статья на сайте). Но в любом случае мне кажется, что лепить сами изменения в таблицу лога "событий" - нехорошо. Особенно если у разных объектов разные атрибуты (и их число произвольное).
Близко... только есть некоторые особенности.Есть экземпляры однотипных объектов включённые в группу.Группа описывается как в программе так и в бд по большей части независимо от других групп (либо с сылками на какие-то состояния экземпляра другой группы), следственно и способ хранения разных групп - в разных таблицах,а вот действия являются общими,т.е. группа имеет только ссылку на ID разрешённых дйствий и "не знает" как это действие повлияет на его состояние...WildSeryv писал(а): Если без версий объектов, то (упрощённо опять же) можно так:
Если заинтересовало,то могу поподробнее расписать что к чему. Мне было бы инересно узнать про другие реализации ООП+RDBMS.