powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / "Историчные" поля - как правильно делать?
25 сообщений из 25, страница 1 из 1
"Историчные" поля - как правильно делать?
    #33362361
Фотография Wolfcub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну в общем чем дальше, тем больше путаюсь...
Уж извините за ламерские вопросы...
До этого пытался спрашивать "в общем случае", но в общем все ясно, а на практике...

Нужно вместо обычного списка сотрудников (Таб.ном., Ф,И,О) сделать список, в котором табельный номер и фамилия могут быть "историчными" (или "периодическими", или как еще там...). Причем их изменения должны (могут) задаваться как задним числом, так и до того, как они произойдут по факту.

Что для этого можно сделать:
Создать табл. истории Таб.ном. и табл. истории фамилии.
В них: IDсотрудника(FK), IDзаписи(PK), значение, дата начала действия значения.

Пробовал следующие варианты:
1. просто добавить таблицы и наложить фильтры на даты, отбирая тем самым значения "историчных" полей, действительные на текущий момент.
ПЛЮСЫ: просто, удобно, красиво
МИНУСЫ: тормозит (4 сек.), причем только с одним полем - почти не заметно, а с двумя - сильно;
-кстати, в этом варианте заметно, что сервер кеширует результаты запросов: повторное (при тех же данных в таблицах) заполнение Browse происходит быстрее (почти мгновенно)
-тормоза, как я понимаю, вызваны "перемножением" таблиц (LEFT OUTER или INNER - разницы не заметно), т.е. большим объемом данных

2. использовать для подстановку на место обычного
поля результата вспомогательного запроса по таблице истории, определяющего
действительное на текущий момент значение "историчного" поля
ПЛЮСЫ: чуть быстрее, в запросе отсутствует JOIN
МИНУСЫ: все равно медленно (2 сек).

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

Ссылка http://www.msaccess.ru/Raznoe_BigPrgOriginal.html которую нашел в этом форуме не работает :(

Спасибо!
...
Рейтинг: 0 / 0
"Историчные" поля - как правильно делать?
    #33362409
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Из общих соображений - нужны поля "дата начала значения", "дата конца значения" и, может быть, индекс по id человека и этим двум датам. Тогда поиск по критерию вида id = :id and :date between date_start and date_finish должен идти быстро. Хотя по идее и просто индекса по id должно нормально хватить.
...
Рейтинг: 0 / 0
"Историчные" поля - как правильно делать?
    #33362474
Фотография PVP
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WolfcubМИНУСЫ: тормозит (4 сек.), причем только с одним полем - почти не заметно, а с двумя - сильно;
-кстати, в этом варианте заметно, что сервер кеширует результаты запросов: повторное (при тех же данных в таблицах) заполнение Browse происходит быстрее (почти мгновенно)
-тормоза, как я понимаю, вызваны "перемножением" таблиц (LEFT OUTER или INNER - разницы не заметно), т.е. большим объемом данных
Согласен с softwarer. Тормоза исключительно из-за отсутствия индексов. Включите в индекс все поля, используемые в связке ON и в условии WHERE, и используйте в запросе явный индекс, например join TABLE t with (index(...)) on ... И тогда оба запроса будут проходить быстро и за одинаковое время.

Если жалко памяти для полей типа DateTime в индексах, в базе можно использовать поле smallint для даты, например как номер дня относительно 01.01.05. Немного возни с перекодировкой, зато быстрее выборка в больших базах.
...
Рейтинг: 0 / 0
"Историчные" поля - как правильно делать?
    #33362478
Фотография Wolfcub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо, что в выходной день нашли время ответить :))

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

Пробую такие запросы:

select * from Сотрудники, ФамилияСотрудника, ТабНомерСотрудника
where ...стыковка таблиц по ID Сотрудника...
and ...фильтры по дате-времени действия записей...

(или тоже самое через JOIN)

И если есть 1000 сотрудников, для них как минимум 1000 записей о фамилия и 1000 - о таб. номерах, то получаем что сервер оперирует 1000*1000*1000 записями? это у меня в конечном итоге занимает 4 секунды

Был вариант как описано выше только с историей фамилии - все было ОК, тормозов не было. Добавил аналогично историю Таб. номера - тормоза :((

А если добавится история имени сотрудника? еще *1000? а другие изменяюиеся со временем
поля (например, статус сотрудника, место работы, должность)? Это ведь все тоже (УЖЕ!) хранится в таблицах с предложенной структурой! Ой как дойдет дело до расстановки персонала, скажем...
__________________________________________
Есть другой вариант, запросы вида:

select * from Сотрудники,
(select ... from ФамилияСотрудника
where ...стыковка таблиц по ID Сотрудника...
and ...фильтры по дате-времени действия записей...),
(select ... from ТабНомерСотрудника
where ...стыковка таблиц по ID Сотрудника...
and ...фильтры по дате-времени действия записей...)

так вроде уже лучше, но все равно медленно...
___________________________________________
А может быть все-таки работать с историей только по отношению к прошлому?
Не рассматривать случай, когда оператор задает, что у Иванова фамилия изменится послезавтра? Тогда можно будет не строить такие сложные запросы!!!

Насколько это допустимо на практике?
В других информационных системах?
Тут чисто жизненный опыт требуется :)
...
Рейтинг: 0 / 0
"Историчные" поля - как правильно делать?
    #33362481
Фотография Wolfcub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PVP WolfcubМИНУСЫ: тормозит (4 сек.), причем только с одним полем - почти не заметно, а с двумя - сильно;
-тормоза, как я понимаю, вызваны "перемножением" таблиц (LEFT OUTER или INNER - разницы не заметно), т.е. большим объемом данных
Согласен с softwarer. Тормоза исключительно из-за отсутствия индексов. Включите в индекс все поля, используемые в связке ON и в условии WHERE, и используйте в запросе явный индекс, например join TABLE t with (index(...)) on ... И тогда оба запроса будут проходить быстро и за одинаковое время.

Спасибо!
Попробую!
...
Рейтинг: 0 / 0
"Историчные" поля - как правильно делать?
    #33362485
Фотография PVP
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WolfcubВ догонку, на всякий случай.

Обычно не достаточно иметь дату начала и дату окончания действия параметров. Надо еще знать и период, когда эти значения имеют силу. Например, в прошлом месяце (в октябре) бухгалтер был уверен, что льгота у сотрудника была с DateiN по DateiK. Этот период использовался в процедуре расчета подоходного налога. Но в текущем месяце (в ноябре) появились новые справки и стало известно, что период льготы другой - с DatejN по DatejK. Процедура расчета подоходного налога должна использовать DateiN и DateiK, если работа выполняется в отчетном периоде Октябрь, и DatejN по DatejK, если работа в ноябре.

Поэтому в учетных (управляющих) системах требуется иметь в базе данных два периода - отчетный и расчетный. Отчетный используются для выборки параметров, действительных для текущего отчетного периода, а расчетный - периода, для которого выполняется расчет. Расчетные периоды могут уходить как в прошлое, так и в будущее.
...
Рейтинг: 0 / 0
"Историчные" поля - как правильно делать?
    #33362496
Фотография PVP
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WolfcubБыл вариант как описано выше только с историей фамилии - все было ОК, тормозов не было. Добавил аналогично историю Таб. номера - тормоза :((

А если добавится история имени сотрудника? еще *1000? а другие изменяюиеся со временем
поля (например, статус сотрудника, место работы, должность)? Это ведь все тоже (УЖЕ!) хранится в таблицах с предложенной структурой! Ой как дойдет дело до расстановки персонала, скажем...
...
Насколько это допустимо на практике?
В других информационных системах?
Тут чисто жизненный опыт требуется :)
На мой взгляд, перебор в детализации. Не надо делать историю для каждого поля. Обычно существует группа полей, общих по смыслу. Например, общие данные о сотруднике (фио, дата раждения, дата поступления, дата увольнения, паспорт и т.д.), данные о повеременной работе (Где, кем, за сколько), данные о отчеслиниях (ссуды, алименты, квартплата) и т.д. Досточно иметь историю для группы однородных полей.

Физически это выглядит следующим образом. В записи таблицы есть набор полей S01 - S0N, код вида данных (группы набора параметров), период ввода параметров (DW - отчетный период), DateN, DateK - период действия параметров. Одна и таже переменная (поле S01) в разных видах данных (в разных группах) имеет разный смысл.

Посмотреть можно реализацию в любой базе данных БАС , в т.ч. и Зарплаты.
...
Рейтинг: 0 / 0
"Историчные" поля - как правильно делать?
    #33362528
Фотография Wolfcub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Огромное спасибо! Тормоза (после создания индексов) исчезли :))
(кстати with(index()) не пришлось - это нормально? :)

У меня своя специфика - пишу клиентов в Clarion 6 ("корпоративный стандарт", однако) - поэтому тормоза работы SQL-драйвера Clarion-a (не прямой ODBC) иногда смешиваются с неэффективностью структуры базы данных, как вот было сейчас.

Еще один момент: в таблице у меня есть и BeginDT и EndDT, но это так сложилось исторически.
Я же сейчас использую только BeginDT - мне кажется, что хранить EndDT - это лишнее, ведь во-первых это некоторая избыточность данных, а во-вторых что будет, если в историю изменения параметров нужно вставить посередине еще одну запись; или, например, есть необходимость скорректировать дату начала действия "исторического" значения

Пожтому приноровился делать так:
BeginDT =
(select top 1 (BeginDT)
from DEmpStatus
where IDEmp = A.IDEm
and BeginDT <= __СЕГОДНЯиСЕЙЧАС__
order by StatusBeginDT desc)

все пока работает :) если есть желание покритировать такой подход - буду только рад
...
Рейтинг: 0 / 0
"Историчные" поля - как правильно делать?
    #33362538
Фотография PVP
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WolfcubОгромное спасибо! Тормоза (после создания индексов) исчезли :))
(кстати with(index()) не пришлось - это нормально? :)
Ничего не могу сказать о Clarion. Если это SQL 2000, то без with(index()) обходится только в том случае, если хорошо налажено Update Statiscs, и то иногда залипает. Я обычно перестраховываюсь.

WolfcubЯ же сейчас использую только BeginDT - мне кажется, что хранить EndDT - это лишнее...Зря. Например бухгалтер вводит данные о начислении пособия по уходу за ребенком, которое началось 15 числа текущего месяца и закончится через три года, то же 15 го числа. Дата окончания известна сейчас. Ее ввод ничего не стоит, т.к. сейчас под рукой документы. А вот через три года надо будет вспомнить, что есть такая декретчица, у которой заканчивается пособие и об этом надо сделать отметку в базе данных. И таких примеров можно привести много.
...
Рейтинг: 0 / 0
"Историчные" поля - как правильно делать?
    #33362558
Фотография Wolfcub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PVP
На мой взгляд, перебор в детализации. Не надо делать историю для каждого поля. Обычно существует группа полей, общих по смыслу. Например, общие данные о сотруднике (фио, дата раждения, дата поступления, дата увольнения, паспорт и т.д.), данные о повеременной работе (Где, кем, за сколько), данные о отчеслиниях (ссуды, алименты, квартплата) и т.д. Досточно иметь историю для группы однородных полей.

Физически это выглядит следующим образом. В записи таблицы есть набор полей S01 - S0N, код вида данных (группы набора параметров), период ввода параметров (DW - отчетный период), DateN, DateK - период действия параметров. Одна и таже переменная (поле S01) в разных видах данных (в разных группах) имеет разный смысл.


чуть-чуть не понял: поля S01 - S0N - наверное разного типа (даты, числа, наименования)? или все сведено к строкам и потом конвертируется?

и еще один вопросик:
я полгода назад пытался сделать что-то супер-пупер универсальное - хранить все атрибуты объекта в одной таблице:

IDОбъекта
IDАтрибута
ЗначениеАтрибута
ДатаНачалаДействияЗначенияАтрибута
ДатаКонцаДействияЗначенияАтрибута

Целью было: обеспечить раширяемость базы - в том числе за счет свободного добавления новых атрибутов и за счет поддержки "историчности" всех атрибутов. Написал для этого библиотеку классов.

в конце концов уткнулся к то, что обработка запросов безбожно тормозила. Например, чтобы вывести простой список сотрудников нужно было в запросе создать для таблицы несколько алиасов и присоединить их друг к другу.
С добавлением в запрос новых атрибутов (ФИО, дата рождения, таб номер и т.д.) скорость обработки запроса падала катастрофически. Потому бросил...
...
Рейтинг: 0 / 0
"Историчные" поля - как правильно делать?
    #33362561
Фотография Wolfcub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PVP Wolfcub
(кстати with(index()) не пришлось - это нормально? :)
Я обычно перестраховываюсь.
ок, попробую перестраховаться :)

WolfcubЯ же сейчас использую только BeginDT - мне кажется, что хранить EndDT - это лишнее...Зря. Например ....
Пример полезный :)

Но вот если история создается задним числом?
было:
Иванова - c 01.01.2000 по NULL (или 01.01.3000 :)
хотим добавить
Петрова - с 01.01.1977 по 01.01.2000
надо: определить дату начала действия Ивановой (для конца Петровой)

было
Петрова - с 01.01.1977 по 01.01.2000
Иванова - c 01.01.2000 по NULL
хотим добавить
Сидорова - с 01.01.1990 по 01.01.2000
надо: 1. обрезать дату конца действия Петровой
2. определить дату начала действия Ивановой (для конца Сидоровой)

А если надо скорректировать данные:
Петрова - с 01.01.1977 по 01.01.2000
Сидорова - с 01.01.1990 по 01.01.2000
Иванова - c 01.01.2000 по NULL
хотим изменить
Сидорова - с 01.01.1995
нужно:
найти Петрову и исправить у нее дату конца

и так далее... а если мы хотим исправить так:
Сидорова - с 01.01.2005
тогда ой-ой :) Иванову тоже придется обрабатывать

Или я усложняю и такое на практике не требуется?
:))
...
Рейтинг: 0 / 0
"Историчные" поля - как правильно делать?
    #33362575
Фотография PVP
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Wolfcubчуть-чуть не понял: поля S01 - S0N - наверное разного типа (даты, числа, наименования)? или все сведено к строкам и потом конвертируется?Типы полей разные. Например, требуется хотя бы в одной группе поле int - оно вводится в таблицу (путь S01). Если поле такого же типа потребуется в другой группе, то используется S01. Требуется дата - добавляется поле типа "дата". Разумеется существует некоторая избыточность. Например, поле D01 не потребуется в другой группе. Но, если поля добавлять аккуратно, то сильной избыточности не намечается.


Wolfcubв конце концов уткнулся к то, что обработка запросов безбожно тормозила. Например, чтобы вывести простой список сотрудников нужно было в запросе создать для таблицы несколько алиасов и присоединить их друг к другу.
С добавлением в запрос новых атрибутов (ФИО, дата рождения, таб номер и т.д.) скорость обработки запроса падала катастрофически. Потому бросил...Я использую имеено этот подход. Только без конвертации в текст и обратно. Просто допускаю некоторую избыточность в базе данных. Это жертва размера в счет быстродействия и в счет универсальности структуры базы данных. Она в БАС в системной части одинакова для различных задач.
...
Рейтинг: 0 / 0
"Историчные" поля - как правильно делать?
    #33362580
Фотография PVP
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WolfcubНо вот если история создается задним числом?
было: ...

...тогда ой-ой :) Иванову тоже придется обрабатывать
Или я усложняю и такое на практике не требуется?
:))Я бы еще раз обратил внимание на существование двух разных смыслов в периодах. Давайте условно назовем их отчетный и расчетный. Отчетный - это где вы находитесь во времени, выполняея некоторую операцию. Расчетный - для какого диапазона времени действительны в настоящий момент данные.

Далее вопрос о точности задания периодов. В учетных и управленческих системах точность отчетного периода обычно ограничивается месяцем. Точность расчетного - днем.

Следуя такой логике, задача вычисления пересечения не только является лишней, но она и не правильна по самой постановке. Во первых, Сидорова с Петровой нельзя смешивать. Во вторых, информация о Сидорове, которая была в базе в сентябре, в общем случае может отличаться от той, которая стала в октябре. Нельзя в октябре уничтожать значение DateN, которое использовалось в сентябре. История должна хранить две записи: одну для сентября с DateN и DateK, и другую для октября со своими DateN и DateK.
...
Рейтинг: 0 / 0
"Историчные" поля - как правильно делать?
    #33362634
Фотография Wolfcub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PVP:
про подход с одной таблицей: одна таблица для хранения всех атрибутов вообще или только истории изменения всех атрибутов?

спрашиваю вот почему - я делал все с одной таблицей (более того - был вариант с одной таблицей ВООБЩЕ ДЛЯ ВСЕХ типов объектов).

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

И тогда огромное количество уже разработанных стандартных средств "визуализации" (шаблоны в Clarion или компоненты в Delphi-Builder) не использует большую часть своих функций!!!

про периоды:
я примерно представляю что Вы имеете в виду под разными периодами, но
мой пример с разными фамилиями ОДНОГО и ТОГО ЖЕ человека более простой.
Объект: конкретный человек
Атрибут: фамилия
Значения: фамилия человека в разные периоды его жизни

И эти фамилии сквозные для всего времени существования объекта и не зависят от каких-то еще периодов!

Ваш пример со справками для подоходнего налога - ведь это же ДВЕ разные справки, насколько я понял :) В обоих указан период льготы. Логика расчета налога может, работая с расчетным периодом, просто проанализировать все справки и сроки действия льгот, попадающие в этот период.
Хотя я может быть не совсем понял :))
Если не трудно - можно еще примерчик, касающийся отчетных и расчетных периодов?

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

Спасибо за подробные ответы!


...
Рейтинг: 0 / 0
"Историчные" поля - как правильно делать?
    #33362796
Фотография PVP
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WolfcubВот например изменение условий работы сотрудника (другой оклад, другие надбавки) - известны границы периода в пределах которого действительны эти условия работы. Какой еще период может быть необходимо рассматривать? :))Рассмотрим два отчетных периода - сентябрь и октябрь. В сентябре в базу системы было занесено, что у Иванова была льгота по подоходному налогу 50% , которая началась 15 июля и должна, закончится 25 ноября. Начисляя в сентябре деньги за отпуск, переходящий на октябрь, бухгалтер берет подоходный налог из октябрьских денег, учитывая льготу.

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

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

А что будет, если поверх старой записи о периоде льготы записать новую? Во-первых теряется информация для перерасчетов. Во-вторых, нет возврата в предыдущие периоды, т.к. в этом случае расчет в сентябре даст уже другой результат. А это не есть хорошо.
...
Рейтинг: 0 / 0
"Историчные" поля - как правильно делать?
    #33362806
Фотография Wolfcub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Про периоды в принципе понял, только вот...

Объект - конкретная справка для конкретного сотрудника
данные об справке:
1. дата создания справки (внесения в систему, начала действия)
2. даты начала
3. дата конца периода действия льготы
4. размер льготы и т.д.

По-моему здесь "историчности" атрибутов как таковой и нет - просто есть насколько объектов, для правильного учета которых необходимо знать дату, когда они были созданы (внесены с систему, начали действовать).
То есть ИМХО "историчность" здесь - период жизни _самого_объекта_, а не актуальности значений его атрибутов.

А вот если бы мы рассматривали все данные о льготах сотрудника как ОДИН ЕДИНСТВЕННЫЙ объект, то тогда бы у него ВСЕ поля были бы "историческими" и " дата создания справки " определяла бы как раз историю изменения атрибутов этого объекта.
Хотя в принципе - это "те же яйца, только сбоку" :))

___________
а по поводу вопроса про универсальную структуру БД - или здесь на форуме это уже обсуждалось? тогда я пойду почитаю :))
...
Рейтинг: 0 / 0
"Историчные" поля - как правильно делать?
    #33362916
Фотография Wolfcub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PVP WolfcubВот например изменение условий работы сотрудника (другой оклад, другие надбавки) - известны границы периода в пределах которого действительны эти условия работы. Какой еще период может быть необходимо рассматривать? :))Рассмотрим два отчетных периода - сентябрь и октябрь. В сентябре в базу системы было занесено, что у Иванова была льгота по подоходному налогу 50% , которая началась 15 июля и должна, закончится 25 ноября. Начисляя в сентябре деньги за отпуск, переходящий на октябрь, бухгалтер берет подоходный налог из октябрьских денег, учитывая льготу.

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

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

А что будет, если поверх старой записи о периоде льготы записать новую? Во-первых теряется информация для перерасчетов. Во-вторых, нет возврата в предыдущие периоды, т.к. в этом случае расчет в сентябре даст уже другой результат. А это не есть хорошо.
...
Рейтинг: 0 / 0
"Историчные" поля - как правильно делать?
    #33362919
Фотография Wolfcub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Извиняюсь за предыдущий пост - ошибся кнопками :))
...
Рейтинг: 0 / 0
"Историчные" поля - как правильно делать?
    #33363111
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WolfcubЯ же сейчас использую только BeginDT - мне кажется, что хранить EndDT - это лишнее, ведь во-первых это некоторая избыточность данных,
Специфика реляционных движков в том, что они эффективно работают с разными полями одной записи и гораздо менее эффективно соединяют поля разных записей. Впрочем, это характерно и для других идеологий БД.

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

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

Wolfcub Пожтому приноровился делать так:
Тогда тормоза таких запросов становятся неудивительными.
...
Рейтинг: 0 / 0
"Историчные" поля - как правильно делать?
    #33363405
ModelR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
"Историчные" поля - как правильно делать?
    #33363705
Фотография Wolfcub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ModelR Здесь

ХА!!!
Да по этой ссылке (и еще по одной) мы приходим к Вашему же посту:
Re: Как построить изменение справочников?
.....
Запросы конечно будут сложнее типа

SELECT ....., NSchet, Schet_Number
FROM .....
LEFT JOIN spSchet_history ON spSchet_history.SchetID=Docum.SchetID
and spSchet_history.Date =
(select max(h.Date) from spSchet_history h where
h.SchetID=Docum.SchetID and h.Date <=Docum.Date)
WHERE ...

так я такой же вариант предлагал :))
только sofеwarer его раскритикковал и я в принципе с ним согласен :))

принцип хранения истории мне ясен - мне сейчас важно определиться:
ВАРИАНТ А: хранить ОБЕ границы временного периода
или
ВАРИАНТ В: только ЛЕВУЮ (раннюю) чисто из следующих соображений:

1. скорость обработки сложных запросов
2. сложность программирования триггеров для управления ПРАВОЙ (вспомогательной) границей временного периода

может быть я предъявляю слишком высокие требования к универсальности структуры, но мне хотелось бы реализовать поддержку след. возможных действий пользователя:
1. штатное изменение значения после того как оно произошло
2. изменение значения, которое произойдет в будущем
3. редактирование истории изменений:
- удаление записей из истории
- добавление - в том числе и в середину
- корректировка даты начала - в том числе с изменением порядка следования записей!!!

1 п. в реализации вообще примитивный
2 п. простой как для варианта А , так и В

3 п. для варианта А - влечет усложнение структуры запросов и снижение скорости их обработки
для варианта В - упрощение и повышение скорости, но ценой более сложных алгоритмов для управления дополнительной ПРАВОЙ границей периода

:))
а так я во всем согласен
спасибо за участие в обсуждении
...
Рейтинг: 0 / 0
"Историчные" поля - как правильно делать?
    #33364008
ModelR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Wolfcub
так я такой же вариант предлагал :))
только sofеwarer его раскритикковал и я в принципе с ним согласен :))
И я согласен: цена триггеров хранения правой границы незначительна по сравнению с выигрышем в запросах. Более того, триггеры неизбежны, если оперировать не событиями изменения значения, а временными интервалами.

Например:
было 2 интервала
Петрова - с 01.01.1977 по 01.01.2000
Иванова - c 01.01.2000 по NULL
добавляем 1 интервал
Сидорова с 01.01.1979 по 01.01.1998
получаем 4 интервала
Петрова - с 01.01.1977 по 01.01.1979
Сидорова с 01.01.1979 по 01.01.1998
Петрова - с 01.01.1998 по 01.01.2000
Иванова - c 01.01.2000 по NULL
...
Рейтинг: 0 / 0
"Историчные" поля - как правильно делать?
    #33368424
Фотография 4d_monster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
плюс вместо NULL использовать "конец всех времён", что то вроде 31.12.9999
и тогда не потребуется доп условий

IMHO, Mon$te®
...
Рейтинг: 0 / 0
"Историчные" поля - как правильно делать?
    #33368699
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
4d_monsterплюс вместо NULL использовать "конец всех времён", что то вроде 31.12.9999
Можно. Но у меня есть большая нелюбовь к "магическим числам". Плюс, с ними иногда возникают изрядно дурацкие проблемы, например какой-нибудь YY-формат в неудачном месте.

4d_monsterи тогда не потребуется доп условий
Тогда потребуются доп. усилия в интерфейсе - например, при выводе затирать это магическое число или писать вместо него "наст. время".

А доп. условия.. Не скажу за Access, но лично меня

Код: plaintext
and :date between date_start and coalesce ( date_finish, :date +  1  )

не особо напрягает.
...
Рейтинг: 0 / 0
"Историчные" поля - как правильно делать?
    #33467201
Фотография Wolfcub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Опять о наболевшем...
Wolfcub
принцип хранения истории мне ясен - мне сейчас важно определиться:
ВАРИАНТ А: хранить ОБЕ границы временного периода или
ВАРИАНТ В: только ЛЕВУЮ (раннюю) чисто из следующих соображений:
A. скорость обработки сложных запросов
B. сложность программирования триггеров для управления ПРАВОЙ (вспомогательной) границей временного периода

может быть я предъявляю слишком высокие требования к универсальности структуры, но мне хотелось бы реализовать поддержку след. возможных действий пользователя:
1. штатное изменение значения после того как оно произошло
2. изменение значения, которое произойдет в будущем
3. редактирование истории изменений:
- удаление записей из истории
- добавление - в том числе и в середину
- корректировка даты начала - в том числе с изменением порядка следования записей!!!

1 п. в реализации вообще примитивный
2 п. простой как для варианта А , так и В
3 п. для варианта А - влечет усложнение структуры запросов и снижение скорости их обработки
для варианта В - упрощение и повышение скорости, но ценой более сложных алгоритмов для управления дополнительной ПРАВОЙ границей периода


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

Хочу спросить - этого будет достаточно, или нужно еще что-то предусмотреть?

С новым годом и спасибо!
...
Рейтинг: 0 / 0
25 сообщений из 25, страница 1 из 1
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / "Историчные" поля - как правильно делать?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]