Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Опять про истоию изменений?
|
|||
|---|---|---|---|
|
#18+
Привет всем. При проектировании базы данных, возник такой вопрос: Есть, к примеру, такая таблица: Id int PK, Call varchar(50), Value int, Value1 decimal, Value2 char(1), Value3 real, Modify_time date, Modify_user varchar(30). Задача состоит в том, что при изменении или удалении записи из таблицы, происходило сохранение предыдущей информации (в другой таблице или таблицах), т. е. ведение истории изменений, для того, чтобы затем можно было увидеть, кто и когда и чего поменял. С одной стороны можно создать одну таблицу, с такой же структурой + некоторые вспомогательные поля, в которую при помощи триггера будет полностью помещаться информация о записи перед изменениями (но в данном случае будет сохраняться избыточные данные, т. к. часто изменяется только одно поле, а не вся запись). Можно помещать в эту таблицу только те поля, значения которых были изменены, но для этого в триггере надо делать проверку на «Было» <> «Стало», что на мой взгляд является длительным процессом. Можно также создать разные таблицы историй в зависимости от типа данных, и записывать в них историю со всех таблиц только для изменяемых полей. (для int-типа одна таблица, для real-типа – другая, и. т. д.) Какую модель выбрать, стоит ли тратить время на выяснение, какие поля были изменены, или просто сохранять всю запись в историю, а потом (по мере необходимости получения информации) выяснять, какое поле было изменено? Как я понял, почитав данный форум, задача классическая, но очень хочется почитать какие-нибудь работы по этому вопросу (где жто можно найти в Internete) , или услышать мнение участников форума. С уважением, Дмитрий Воронин. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2004, 18:38 |
|
||
|
Опять про истоию изменений?
|
|||
|---|---|---|---|
|
#18+
уместны как минимум 4 варианта 1. история изменений цены товара. В отдельной таблице - хранится код товара, цена, Дата действия цены. Выборка актуальной цены через select max(). Удаление - запрещено. 2. Изменение реестра основных фондов. Добавляются поля Дата_начала, Дата_конца, выборка с учетом дат - для расчета амортизаци "задним числом", или в трендовых отчетах, на основе составления актуальной порции данных за каждый учетный период - "на лету". Удаление - запрещено. 3. история изменения штатного расписани. Тут - конкретно, другая таблица, где хранится важнейшая инфо в терминах БЫЛО и СТАЛО. Особенно актуально, если имеет место составной ключ, типа Код сотрудника Код должности Код Подразделения когда всегда важно знать что было до и после. Удаление - запрещено. С одной стороны можно создать одну таблицу, с такой же структурой + некоторые вспомогательные поля, в которую при помощи триггера будет полностью помещаться информация о записи перед изменениями (но в данном случае будет сохраняться избыточные данные, т. к. часто изменяется только одно поле, а не вся запись). 4. Альтернатива - вести свой Журнал Таблиц Полей БД, занать имена Таблиц, Полей -> в триггере, в цикле, тупо проверять - что изменилось, и в LONG -е хранить типа маски... - Операция изменения - Поле1,,,,Поле6,Поле7,,,Поле10 - Value1,,,,Value6,Value7,,,Value10 где кол-во запятых - есть кол_во не измененых полей. После этого, у Вас появится собственный алгоритм для построения "триггерной_реплицации". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2004, 20:27 |
|
||
|
Опять про истоию изменений?
|
|||
|---|---|---|---|
|
#18+
пришел к выводу, что эффективней сохранять всю запись в отдельной таблице копии основной + поле version_ID. Не придется писать выяснение обновленных полей и соответственно при восстановлении версии в качестве основной упрощается ее вставка в основную таблицу з.ы. Конечно, если речь не идет о больших полях. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2004, 20:27 |
|
||
|
Опять про истоию изменений?
|
|||
|---|---|---|---|
|
#18+
при закрытии периода, архивации и т.п. можно удалять все версии документа из БД, оставляя только основную ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.03.2004, 09:40 |
|
||
|
Опять про истоию изменений?
|
|||
|---|---|---|---|
|
#18+
Dmitry Voroninпри закрытии периода, архивации и т.п. можно удалять все версии документа из БД, оставляя только основную Если есть изменения и расчеты задними числами, то не сработает. Например задним числом поменялась ставка аж за полгода назад. Необходимо пересчитать все договора за эти полгода. Если у Вас по изменению всех аттрибутов договоров, участвующих в расчете история не ведется или очищается при закрытии расчетного периода, то расчет будет произведен по значениям, действующим на текущий момент времени и соответствующе выдаст не правильные результаты при пересчитывании прошлых периодов. Это хорошо, когда весь расчет = ставка*значение, а вот чего нибудь посложнее: расчет зп, расчет коммунальных плателей, расчет потребления электроэнергии пром. абонентами и т.д., это целая песня, где фактически на все приходиться вести хранение истории. У меня например в расчете зп ЕСН вообще по двум измерениям ведется: для авансовых платежей в течении года он расчитывается по месяцу начисления (т.е. берется со всех сумм начислений, вошедших в расчетный месяц, в том числе и результатов сторнирования прошлых закрытых периодов), а в конце года он формируется по месяцу выдачи (т.е. пересчитывается так, как если бы в расчетном году изменений задними числами не было и начисления велись без сторно, по месяцам). Так что если у Вас таких расчетов нет (и слава богу), то лучше просто перебрасывать историю в отдельные таблицы и так не заморачиваться. Если что то такое есть, то лучше подумать о варианте номер 1, предложенным UK0IAI . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.03.2004, 10:27 |
|
||
|
Опять про истоию изменений?
|
|||
|---|---|---|---|
|
#18+
Против задних чисел часто помогает сторно. ;-))) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.03.2004, 11:08 |
|
||
|
Опять про истоию изменений?
|
|||
|---|---|---|---|
|
#18+
в форуме оракла регулярно обсуждалось\r \r /topic/82837\r \r например, здесь ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.03.2004, 10:40 |
|
||
|
Опять про истоию изменений?
|
|||
|---|---|---|---|
|
#18+
ASCRUSЕсли есть изменения и расчеты задними числами, то не сработает. Например задним числом поменялась ставка аж за полгода назад. Необходимо пересчитать все договора за эти полгода. А на мой взгляд это разные вещи. История изменения цен должна храниться полностью. В принципе изменения сводятся к двум вариантам: 1. Изменение ошибочно введенных данных, 2. Изменение значения при изменении условий. Я где-то в договарах даже спрашиваю при изменении причину и сажаю в ее хистори. К сожалению на юзверей надежды не какой :( они все равно могут поставить, что угодно. Но то что касается изменений цен, ставок и т.п. я их храню полностью, а остальные изменения время от времени чищу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2004, 12:42 |
|
||
|
Опять про истоию изменений?
|
|||
|---|---|---|---|
|
#18+
Собственно, по-моему существуют всего 3 возможных модели ведения истории (обощенные данные, предположительно описываемая сущность включает в себя несколько таблиц): - на каждую таблицу актуальных (текущих) данных параллельно заводится таблица истории. Соответсвенно, при выборках опред. к какому периоду относится, из какой таблицы брать. - почти также, но история ведется вместе с текущими данными. Выборка производится по датам с ID записей и пр. - история полей. Единая таблица примерной структуры имя_поля=значение, дата (остальное не рассматриваем), в которую записываются любые поля. Самый красивый, но и самый сложный и - м.б. неэффективный вариант. Ну а на практике, все это можно комбинировать. Отдельным вопросом стоит "будущая история". Напр. изменили мы некий атрибут 25-м апреля (будущего), а затем заново изменили 14 апреля, а потом удалили его вообще 19-го... Тут такой простор мыслей открывается.... Nobody faults but mine... (LZ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2004, 18:57 |
|
||
|
Опять про истоию изменений?
|
|||
|---|---|---|---|
|
#18+
авторА на мой взгляд это разные вещи. История изменения цен должна храниться полностью. А какой смысл хранить историю полностью ? Я в своей модели хранения истории могу гарантировать, что за любой расчетый период я могу получить входящую информацию, соотвествующую тому расчетному периоду и которая будет основой для расчетной информации. Что там юзер менял в течении месяца меня не волнует, самое главное, что было использовано при расчетах. Это и есть состояние истории де-факто, которое фиксируется при закрытии расчетного месяца и в будующем больше изменится не может. Другое дело, что юзер может провести изменения задним числом, однако это опять же будет на самом деле не изменение значения входящей информации за прошлый расчетный период, а добавление в историю новой версии по закрытой информации. Ну а если юзер ошибочно ввел что то, потом рассчитал и закрыл расчетный месяц, так это извините его проблемы чисто в бухгалтерском понятии. Будет в следующем месяце менять эту информацию задним числом, чтобы программа автоматом сторнировала ему эту разницу ошибки. авторНу а на практике, все это можно комбинировать. Отдельным вопросом стоит "будущая история". Напр. изменили мы некий атрибут 25-м апреля (будущего), а затем заново изменили 14 апреля, а потом удалили его вообще 19-го... Тут такой простор мыслей открывается.... У меня с будующим все просто. Так как есть 2 даты на информацию - дата нач.действия (SaveDate) и дата расчетного месяца (CalcDate), то хранится следующим образом: допустим текущий расчетный месяц @@CurCalcDate = Апрель 2004 добавляем информация за тек. расч. месяц: CalcDate=2004.04.01 SaveDate=2004.04.01 изменяем информацию задним числом за март 2004: CalcDate=2004.03.01 SaveDate=2004.04.01 добавляем информацию будующим числом на май 2004: CalcDate-2004.05.01 SaveDate=2004.05.01 Получается, что SaveDate при записи в БД вычисляется по следующей формуле: CASE WHEN SaveDate <= @@CurCalcDate THEN @@CurCalcDate ELSE CalcDate END в итоге при вводе информации за текущий или предыдущий расчетные периоды дата нач. действия этой информации всегда будет равна текущему расчетному месяцу, при вводе за будующие числа будет равна дате самого расчетного месяца. Соответствующе пока будующее не станет настоящим, данные эти будут висеть в воздухе, нигде не участвовать и свободно изменяться юзером. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2004, 23:31 |
|
||
|
Опять про истоию изменений?
|
|||
|---|---|---|---|
|
#18+
авторНу а если юзер ошибочно ввел что то, потом рассчитал и закрыл расчетный месяц, так это извините его проблемы чисто в бухгалтерском понятии. У одной кладовщицы исчезали накладные !!! Мне говорили что это программа моя сбоит. И так было, пока я их носом не ткнул в протокол изменения базы. Она оказывается в запале работы сама их удаляла, и на запрос подтверждения удаления не читая, но уверенно нажимала "Да" :)) История юзерам, наверное, действительно не нужна. Она нужна администратору/программисту IMHO Жизнь коротка - потерпи немного :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2004, 09:45 |
|
||
|
Опять про истоию изменений?
|
|||
|---|---|---|---|
|
#18+
ASCRUSА какой смысл хранить историю полностью ? .... Что там юзер менял в течении месяца меня не волнует, самое главное, что было использовано при расчетах.Другое дело, что юзер может провести изменения задним числом, однако это опять же будет на самом деле не изменение значения входящей информации за прошлый расчетный период, а добавление в историю новой версии по закрытой информации. А если расчетный период тот же, а цены менялись несколько раз и изменяется запись с предыдущими ценами, тут хочешь не хочешь, а хранить историю будешь. Плюс к этому по истории изменения цен можно получить динамику изменения. Marat_LИстория юзерам, наверное, действительно не нужна. Она нужна администратору/программисту Полностью согласен. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2004, 10:02 |
|
||
|
Опять про истоию изменений?
|
|||
|---|---|---|---|
|
#18+
простой пример про историю изменений Задача - расчет амортизации в разрезе центров ответственности (ЦО) Заводим справочник ОС - и... готово. НО, 1. ОС числятся за центрами ответственностями в лице Сотрудников. Ладно, обошли трабл - юзая термин должность...привязывая ОС не к Сотруднику (очень переменная величина) - а к Должности.. Но мелкие ОС-ы имеют свойство...тусоваться, "стол" дескать перенесли из одного кабинета в другой. А мы любим трендовые отчеты...делать задним числом...надо значит на каждый учетный период восстановить картину распределения ОС по центрам ответственности - с учетом конкретного состояния Базы Распределения на каждый учетный период. База распределения - простой список, например пользователей ксерокса, где всего две колонки - Код Должности, Норматив, согласно которой производится распределение суммы амортизации ксерокса на разные ЦО. НО, в разное время, у ксерокса, может быть разное кол-во пользователей из разных подразделений. Сразу попали на хистори изменеий ... И пошло и поехало... структура ЦО может меняться, структура Баз Распределения может меняться, структура ОС может меняться...единственное утешает, что алгоритм работы с переменной НСИ в принципе един. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2004, 12:38 |
|
||
|
Опять про истоию изменений?
|
|||
|---|---|---|---|
|
#18+
Посмотри, например, как реализовано в IBExpert, открой реадактор таблиц, закладка Logging ("Протокол" - в русской версии). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2004, 13:53 |
|
||
|
Опять про истоию изменений?
|
|||
|---|---|---|---|
|
#18+
авторА если расчетный период тот же, а цены менялись несколько раз и изменяется запись с предыдущими ценами, тут хочешь не хочешь, а хранить историю будешь. Плюс к этому по истории изменения цен можно получить динамику изменения. Давайте определимся с терминологией, иначе сейчас запутаемся :) Говоря история я имею ввиду историю изменения (в том числе и задним числом) аттрибутов обьекта, которые являются статическим зафиксированным значением в неком периоде и уже не могут изменяться (версии значений). Сама длина этого периода определяется конкретной задачей. Например, если цена продукции изменяется раз в месяц, то сколько бы ее юзера не меняли в течении месяца, в конце концов в истории будет одна цена, вернее ее последняя версия. Если цена продукции может изменятся каждый день, то значит мы будем хранить ее историю за каждый день изменений. Опять же в зависимости от ТЗ мы будем определять, когда юзеру доступно изменение информации, а когда он уже должен добавить ее новую версию. Например, в расчете зп есть понятие расчетного периода размером в месяц. Однако ставки могут изменяться хоть каждый день. Получается что юзер имеет право изменять значение ставки хоть на каждый день месяца. Сколько дней он распишет, столько записей по этой ставке и будет. Однако, если он захочет задним числом изменить ставку с 15 числа прошлого закрытого месяца, то в интерфейсе именно так он и сделает. Однако на самом деле в БД будет добавлена новая версия по этой ставке, с указанием что с 15 числа прошлого месяца значение ставки теперь такое, однако запись будет помечена, что проведена она текущим месяцем. Это я и называю историей (версионностью значений данных) - каждые аттрибуты обьекта, взятые во времени всегда являются дефакто и не противоречат остальным данным системы за период их действия. То есть, если я запущу расчет зп за прошлый месяц с точки зрения данных прошлого месяца, то мне и будет все посчитано так, как было в прошлом месяце, цифра в цифру. Если же расчет будет запущен с точки зрения данных текущего месяца, то у меня получатся другие результаты. Разница между результатами и есть сторно, причем опять же в архиве закрытых периодов за прошлый период расчетные данные изменяться не будут, разница сторно пойдет в текущий месяц, с пометкой, что она содержит данные за прошлый расчетный месяц. В случае же выяснения обстоятельств неправильного ввода информации я это называю логированием данных (протоколом). Это совсем другая песня из другой оперы - такие вещи я выношу отдельно. В итоге с моей точки зрения все получается правильно - в таблицах входящей информации лежит только актуальная для БД информация, там где надо с поддержкой истории изменения ее значений, эта информация задействуется в бизнес-логике проекта и фактически может считаться статичной для всех закрытых периодов. В протоколе же лежат все зверства юзеров, его информация не влияет на логику приложения, а служит только для отслеживания действий юзеров. Протокол отражает данные только за указанный некий близжайший период времени и чистится (я считаю его вполне культурно вообще выносить в отдельную БД). Если же начинать историю и протокол изменения хранить в одном месте, то мне кажется, программист и СУБД просто умрут, так как будет очень проблематично выделить, где реальные данные по изменению истории, а где просто Марья Ивановна, которая 10 раз зачем то изменила одну и ту же запись. Сорри, если написал сумбурно, очень сложно описывать проблемы и решения, связанные с проектировкой БД, до сих пор у меня криво получается, никак не научусь :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2004, 14:52 |
|
||
|
Опять про истоию изменений?
|
|||
|---|---|---|---|
|
#18+
Тут самое-самое вообще - на пальцах показывать: Берем историю изменения курса доллара Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Сразу понятно что допускается единственное значение в 1 дне. Можно вычислить MAX,MIN и AVG за период, причем в периоде могут А значение на конкретный день должно вычисляться как Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2004, 15:42 |
|
||
|
Опять про истоию изменений?
|
|||
|---|---|---|---|
|
#18+
да, и еще один индекс построить надо, чтоб быстро работало CREATE UNIQUE INDEX TTTTT ON dict.Curses (Main DESC,CURRENCY DESC,DT DESC) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2004, 15:50 |
|
||
|
Опять про истоию изменений?
|
|||
|---|---|---|---|
|
#18+
2 gardenman Сразу понятно что допускается единственное значение в 1 дне. Может в DB2 это и понятно, а если бы это был MS SQL то Код: plaintext не значит, что в dt нельзя засунуть 1/1/2001 12:34, например ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.04.2004, 10:40 |
|
||
|
Опять про истоию изменений?
|
|||
|---|---|---|---|
|
#18+
Кстати)) для инфы)) Sybase в версии 12.5.1 уже ввел новые типы данных: DATE и TIME, чистая дата и чистое время...) Рано или поздно и Мелкософт тоже самое сделает) Вообще когда я столкнулся с T-SQL я поразился убогости работы с датами. то что даты можно только с 1720 года иметь, и то что время вечно путается рядом с датой.. А работа с timestamp - вообще жуть...((( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.04.2004, 11:20 |
|
||
|
|

start [/forum/topic.php?fid=32&fpage=170&tid=1546552]: |
0ms |
get settings: |
10ms |
get forum list: |
13ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
36ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
73ms |
get tp. blocked users: |
1ms |
| others: | 282ms |
| total: | 430ms |

| 0 / 0 |
