|
|
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
Ну в общем чем дальше, тем больше путаюсь... Уж извините за ламерские вопросы... До этого пытался спрашивать "в общем случае", но в общем все ясно, а на практике... Нужно вместо обычного списка сотрудников (Таб.ном., Ф,И,О) сделать список, в котором табельный номер и фамилия могут быть "историчными" (или "периодическими", или как еще там...). Причем их изменения должны (могут) задаваться как задним числом, так и до того, как они произойдут по факту. Что для этого можно сделать: Создать табл. истории Таб.ном. и табл. истории фамилии. В них: IDсотрудника(FK), IDзаписи(PK), значение, дата начала действия значения. Пробовал следующие варианты: 1. просто добавить таблицы и наложить фильтры на даты, отбирая тем самым значения "историчных" полей, действительные на текущий момент. ПЛЮСЫ: просто, удобно, красиво МИНУСЫ: тормозит (4 сек.), причем только с одним полем - почти не заметно, а с двумя - сильно; -кстати, в этом варианте заметно, что сервер кеширует результаты запросов: повторное (при тех же данных в таблицах) заполнение Browse происходит быстрее (почти мгновенно) -тормоза, как я понимаю, вызваны "перемножением" таблиц (LEFT OUTER или INNER - разницы не заметно), т.е. большим объемом данных 2. использовать для подстановку на место обычного поля результата вспомогательного запроса по таблице истории, определяющего действительное на текущий момент значение "историчного" поля ПЛЮСЫ: чуть быстрее, в запросе отсутствует JOIN МИНУСЫ: все равно медленно (2 сек). Не могли бы вы покритиковать то, на чем я остановился и предложить (намекнуть) более эффективный подход? Мне кажется, задачи такого рода возникают очень часто, как правильно решать их? Может быть есть какие-то статьи по этому поводу? Ссылка http://www.msaccess.ru/Raznoe_BigPrgOriginal.html которую нашел в этом форуме не работает :( Спасибо! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.11.2005, 09:05 |
|
||
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
Из общих соображений - нужны поля "дата начала значения", "дата конца значения" и, может быть, индекс по id человека и этим двум датам. Тогда поиск по критерию вида id = :id and :date between date_start and date_finish должен идти быстро. Хотя по идее и просто индекса по id должно нормально хватить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.11.2005, 11:49 |
|
||
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
WolfcubМИНУСЫ: тормозит (4 сек.), причем только с одним полем - почти не заметно, а с двумя - сильно; -кстати, в этом варианте заметно, что сервер кеширует результаты запросов: повторное (при тех же данных в таблицах) заполнение Browse происходит быстрее (почти мгновенно) -тормоза, как я понимаю, вызваны "перемножением" таблиц (LEFT OUTER или INNER - разницы не заметно), т.е. большим объемом данных Согласен с softwarer. Тормоза исключительно из-за отсутствия индексов. Включите в индекс все поля, используемые в связке ON и в условии WHERE, и используйте в запросе явный индекс, например join TABLE t with (index(...)) on ... И тогда оба запроса будут проходить быстро и за одинаковое время. Если жалко памяти для полей типа DateTime в индексах, в базе можно использовать поле smallint для даты, например как номер дня относительно 01.01.05. Немного возни с перекодировкой, зато быстрее выборка в больших базах. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.11.2005, 13:50 |
|
||
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
Спасибо, что в выходной день нашли время ответить :)) Да структура базы уже много месяцев такая, но пока все обходилось историей только фамилии. а теперь надо сделать еще и историю табельного номера Пробую такие запросы: 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 ...фильтры по дате-времени действия записей...) так вроде уже лучше, но все равно медленно... ___________________________________________ А может быть все-таки работать с историей только по отношению к прошлому? Не рассматривать случай, когда оператор задает, что у Иванова фамилия изменится послезавтра? Тогда можно будет не строить такие сложные запросы!!! Насколько это допустимо на практике? В других информационных системах? Тут чисто жизненный опыт требуется :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.11.2005, 13:55 |
|
||
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
PVP WolfcubМИНУСЫ: тормозит (4 сек.), причем только с одним полем - почти не заметно, а с двумя - сильно; -тормоза, как я понимаю, вызваны "перемножением" таблиц (LEFT OUTER или INNER - разницы не заметно), т.е. большим объемом данных Согласен с softwarer. Тормоза исключительно из-за отсутствия индексов. Включите в индекс все поля, используемые в связке ON и в условии WHERE, и используйте в запросе явный индекс, например join TABLE t with (index(...)) on ... И тогда оба запроса будут проходить быстро и за одинаковое время. Спасибо! Попробую! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.11.2005, 13:57 |
|
||
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
WolfcubВ догонку, на всякий случай. Обычно не достаточно иметь дату начала и дату окончания действия параметров. Надо еще знать и период, когда эти значения имеют силу. Например, в прошлом месяце (в октябре) бухгалтер был уверен, что льгота у сотрудника была с DateiN по DateiK. Этот период использовался в процедуре расчета подоходного налога. Но в текущем месяце (в ноябре) появились новые справки и стало известно, что период льготы другой - с DatejN по DatejK. Процедура расчета подоходного налога должна использовать DateiN и DateiK, если работа выполняется в отчетном периоде Октябрь, и DatejN по DatejK, если работа в ноябре. Поэтому в учетных (управляющих) системах требуется иметь в базе данных два периода - отчетный и расчетный. Отчетный используются для выборки параметров, действительных для текущего отчетного периода, а расчетный - периода, для которого выполняется расчет. Расчетные периоды могут уходить как в прошлое, так и в будущее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.11.2005, 14:01 |
|
||
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
WolfcubБыл вариант как описано выше только с историей фамилии - все было ОК, тормозов не было. Добавил аналогично историю Таб. номера - тормоза :(( А если добавится история имени сотрудника? еще *1000? а другие изменяюиеся со временем поля (например, статус сотрудника, место работы, должность)? Это ведь все тоже (УЖЕ!) хранится в таблицах с предложенной структурой! Ой как дойдет дело до расстановки персонала, скажем... ... Насколько это допустимо на практике? В других информационных системах? Тут чисто жизненный опыт требуется :) На мой взгляд, перебор в детализации. Не надо делать историю для каждого поля. Обычно существует группа полей, общих по смыслу. Например, общие данные о сотруднике (фио, дата раждения, дата поступления, дата увольнения, паспорт и т.д.), данные о повеременной работе (Где, кем, за сколько), данные о отчеслиниях (ссуды, алименты, квартплата) и т.д. Досточно иметь историю для группы однородных полей. Физически это выглядит следующим образом. В записи таблицы есть набор полей S01 - S0N, код вида данных (группы набора параметров), период ввода параметров (DW - отчетный период), DateN, DateK - период действия параметров. Одна и таже переменная (поле S01) в разных видах данных (в разных группах) имеет разный смысл. Посмотреть можно реализацию в любой базе данных БАС , в т.ч. и Зарплаты. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.11.2005, 14:15 |
|
||
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
Огромное спасибо! Тормоза (после создания индексов) исчезли :)) (кстати 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) все пока работает :) если есть желание покритировать такой подход - буду только рад ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.11.2005, 14:55 |
|
||
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
WolfcubОгромное спасибо! Тормоза (после создания индексов) исчезли :)) (кстати with(index()) не пришлось - это нормально? :) Ничего не могу сказать о Clarion. Если это SQL 2000, то без with(index()) обходится только в том случае, если хорошо налажено Update Statiscs, и то иногда залипает. Я обычно перестраховываюсь. WolfcubЯ же сейчас использую только BeginDT - мне кажется, что хранить EndDT - это лишнее...Зря. Например бухгалтер вводит данные о начислении пособия по уходу за ребенком, которое началось 15 числа текущего месяца и закончится через три года, то же 15 го числа. Дата окончания известна сейчас. Ее ввод ничего не стоит, т.к. сейчас под рукой документы. А вот через три года надо будет вспомнить, что есть такая декретчица, у которой заканчивается пособие и об этом надо сделать отметку в базе данных. И таких примеров можно привести много. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.11.2005, 15:13 |
|
||
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
PVP На мой взгляд, перебор в детализации. Не надо делать историю для каждого поля. Обычно существует группа полей, общих по смыслу. Например, общие данные о сотруднике (фио, дата раждения, дата поступления, дата увольнения, паспорт и т.д.), данные о повеременной работе (Где, кем, за сколько), данные о отчеслиниях (ссуды, алименты, квартплата) и т.д. Досточно иметь историю для группы однородных полей. Физически это выглядит следующим образом. В записи таблицы есть набор полей S01 - S0N, код вида данных (группы набора параметров), период ввода параметров (DW - отчетный период), DateN, DateK - период действия параметров. Одна и таже переменная (поле S01) в разных видах данных (в разных группах) имеет разный смысл. чуть-чуть не понял: поля S01 - S0N - наверное разного типа (даты, числа, наименования)? или все сведено к строкам и потом конвертируется? и еще один вопросик: я полгода назад пытался сделать что-то супер-пупер универсальное - хранить все атрибуты объекта в одной таблице: IDОбъекта IDАтрибута ЗначениеАтрибута ДатаНачалаДействияЗначенияАтрибута ДатаКонцаДействияЗначенияАтрибута Целью было: обеспечить раширяемость базы - в том числе за счет свободного добавления новых атрибутов и за счет поддержки "историчности" всех атрибутов. Написал для этого библиотеку классов. в конце концов уткнулся к то, что обработка запросов безбожно тормозила. Например, чтобы вывести простой список сотрудников нужно было в запросе создать для таблицы несколько алиасов и присоединить их друг к другу. С добавлением в запрос новых атрибутов (ФИО, дата рождения, таб номер и т.д.) скорость обработки запроса падала катастрофически. Потому бросил... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.11.2005, 15:46 |
|
||
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
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 тогда ой-ой :) Иванову тоже придется обрабатывать Или я усложняю и такое на практике не требуется? :)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.11.2005, 16:04 |
|
||
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
Wolfcubчуть-чуть не понял: поля S01 - S0N - наверное разного типа (даты, числа, наименования)? или все сведено к строкам и потом конвертируется?Типы полей разные. Например, требуется хотя бы в одной группе поле int - оно вводится в таблицу (путь S01). Если поле такого же типа потребуется в другой группе, то используется S01. Требуется дата - добавляется поле типа "дата". Разумеется существует некоторая избыточность. Например, поле D01 не потребуется в другой группе. Но, если поля добавлять аккуратно, то сильной избыточности не намечается. Wolfcubв конце концов уткнулся к то, что обработка запросов безбожно тормозила. Например, чтобы вывести простой список сотрудников нужно было в запросе создать для таблицы несколько алиасов и присоединить их друг к другу. С добавлением в запрос новых атрибутов (ФИО, дата рождения, таб номер и т.д.) скорость обработки запроса падала катастрофически. Потому бросил...Я использую имеено этот подход. Только без конвертации в текст и обратно. Просто допускаю некоторую избыточность в базе данных. Это жертва размера в счет быстродействия и в счет универсальности структуры базы данных. Она в БАС в системной части одинакова для различных задач. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.11.2005, 16:27 |
|
||
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
WolfcubНо вот если история создается задним числом? было: ... ...тогда ой-ой :) Иванову тоже придется обрабатывать Или я усложняю и такое на практике не требуется? :))Я бы еще раз обратил внимание на существование двух разных смыслов в периодах. Давайте условно назовем их отчетный и расчетный. Отчетный - это где вы находитесь во времени, выполняея некоторую операцию. Расчетный - для какого диапазона времени действительны в настоящий момент данные. Далее вопрос о точности задания периодов. В учетных и управленческих системах точность отчетного периода обычно ограничивается месяцем. Точность расчетного - днем. Следуя такой логике, задача вычисления пересечения не только является лишней, но она и не правильна по самой постановке. Во первых, Сидорова с Петровой нельзя смешивать. Во вторых, информация о Сидорове, которая была в базе в сентябре, в общем случае может отличаться от той, которая стала в октябре. Нельзя в октябре уничтожать значение DateN, которое использовалось в сентябре. История должна хранить две записи: одну для сентября с DateN и DateK, и другую для октября со своими DateN и DateK. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.11.2005, 16:39 |
|
||
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
PVP: про подход с одной таблицей: одна таблица для хранения всех атрибутов вообще или только истории изменения всех атрибутов? спрашиваю вот почему - я делал все с одной таблицей (более того - был вариант с одной таблицей ВООБЩЕ ДЛЯ ВСЕХ типов объектов). но при такой структуре полностью теряется возможность использовать ограничения ссылочной целостности между атрибутами объектов! (то есть они конечно реализуемы, но насколько это сложно сделать я даже представить опасаюсь :)) И тогда огромное количество уже разработанных стандартных средств "визуализации" (шаблоны в Clarion или компоненты в Delphi-Builder) не использует большую часть своих функций!!! про периоды: я примерно представляю что Вы имеете в виду под разными периодами, но мой пример с разными фамилиями ОДНОГО и ТОГО ЖЕ человека более простой. Объект: конкретный человек Атрибут: фамилия Значения: фамилия человека в разные периоды его жизни И эти фамилии сквозные для всего времени существования объекта и не зависят от каких-то еще периодов! Ваш пример со справками для подоходнего налога - ведь это же ДВЕ разные справки, насколько я понял :) В обоих указан период льготы. Логика расчета налога может, работая с расчетным периодом, просто проанализировать все справки и сроки действия льгот, попадающие в этот период. Хотя я может быть не совсем понял :)) Если не трудно - можно еще примерчик, касающийся отчетных и расчетных периодов? Вот например изменение условий работы сотрудника (другой оклад, другие надбавки) - известны границы периода в пределах которого действительны эти условия работы. Какой еще период может быть необходимо рассматривать? :)) Спасибо за подробные ответы! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.11.2005, 18:52 |
|
||
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
WolfcubВот например изменение условий работы сотрудника (другой оклад, другие надбавки) - известны границы периода в пределах которого действительны эти условия работы. Какой еще период может быть необходимо рассматривать? :))Рассмотрим два отчетных периода - сентябрь и октябрь. В сентябре в базу системы было занесено, что у Иванова была льгота по подоходному налогу 50% , которая началась 15 июля и должна, закончится 25 ноября. Начисляя в сентябре деньги за отпуск, переходящий на октябрь, бухгалтер берет подоходный налог из октябрьских денег, учитывая льготу. Но пришел октябрь, появилась новая справка, из которой следует, что льгота на самом деле была с 15 мая и заканчивается 15 сентября. Эти данные занесли в систему. Октябрьский расчет зарплаты, во-первых, не учитывает льготу в октябрьской зарплате и, во-вторых, делает перерасчет для уже начисленного подоходного за октябрь, а возможно и за май, и сентябрь (т.е. те отчетные периоды, а которых льгота использовалась не правильно). Если, при этом вернуться по каким-либо причинам в отчетный период сентябрь, то система в результате расчета сентябрьской зарплаты выдаст старый результат, т.е. тот который был. Она его не испортит. А что будет, если поверх старой записи о периоде льготы записать новую? Во-первых теряется информация для перерасчетов. Во-вторых, нет возврата в предыдущие периоды, т.к. в этом случае расчет в сентябре даст уже другой результат. А это не есть хорошо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.11.2005, 12:20 |
|
||
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
Про периоды в принципе понял, только вот... Объект - конкретная справка для конкретного сотрудника данные об справке: 1. дата создания справки (внесения в систему, начала действия) 2. даты начала 3. дата конца периода действия льготы 4. размер льготы и т.д. По-моему здесь "историчности" атрибутов как таковой и нет - просто есть насколько объектов, для правильного учета которых необходимо знать дату, когда они были созданы (внесены с систему, начали действовать). То есть ИМХО "историчность" здесь - период жизни _самого_объекта_, а не актуальности значений его атрибутов. А вот если бы мы рассматривали все данные о льготах сотрудника как ОДИН ЕДИНСТВЕННЫЙ объект, то тогда бы у него ВСЕ поля были бы "историческими" и " дата создания справки " определяла бы как раз историю изменения атрибутов этого объекта. Хотя в принципе - это "те же яйца, только сбоку" :)) ___________ а по поводу вопроса про универсальную структуру БД - или здесь на форуме это уже обсуждалось? тогда я пойду почитаю :)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.11.2005, 13:22 |
|
||
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
PVP WolfcubВот например изменение условий работы сотрудника (другой оклад, другие надбавки) - известны границы периода в пределах которого действительны эти условия работы. Какой еще период может быть необходимо рассматривать? :))Рассмотрим два отчетных периода - сентябрь и октябрь. В сентябре в базу системы было занесено, что у Иванова была льгота по подоходному налогу 50% , которая началась 15 июля и должна, закончится 25 ноября. Начисляя в сентябре деньги за отпуск, переходящий на октябрь, бухгалтер берет подоходный налог из октябрьских денег, учитывая льготу. Но пришел октябрь, появилась новая справка, из которой следует, что льгота на самом деле была с 15 мая и заканчивается 15 сентября. Эти данные занесли в систему. Октябрьский расчет зарплаты, во-первых, не учитывает льготу в октябрьской зарплате и, во-вторых, делает перерасчет для уже начисленного подоходного за октябрь, а возможно и за май, и сентябрь (т.е. те отчетные периоды, а которых льгота использовалась не правильно). Если, при этом вернуться по каким-либо причинам в отчетный период сентябрь, то система в результате расчета сентябрьской зарплаты выдаст старый результат, т.е. тот который был. Она его не испортит. А что будет, если поверх старой записи о периоде льготы записать новую? Во-первых теряется информация для перерасчетов. Во-вторых, нет возврата в предыдущие периоды, т.к. в этом случае расчет в сентябре даст уже другой результат. А это не есть хорошо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.11.2005, 17:23 |
|
||
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
Извиняюсь за предыдущий пост - ошибся кнопками :)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.11.2005, 17:25 |
|
||
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
WolfcubЯ же сейчас использую только BeginDT - мне кажется, что хранить EndDT - это лишнее, ведь во-первых это некоторая избыточность данных, Специфика реляционных движков в том, что они эффективно работают с разными полями одной записи и гораздо менее эффективно соединяют поля разных записей. Впрочем, это характерно и для других идеологий БД. Да, это избыточность, но настолько практически удобная, что теория нормализации даже не пытается избавиться от нее. Wolfcub а во-вторых что будет, если в историю изменения параметров нужно вставить посередине еще одну запись Да в общем никаких проблем. Добавить пару строк в процедуру вставки гораздо удобнее, чем писать в десятке-другом мест дополнительный подзапрос. Wolfcub Пожтому приноровился делать так: Тогда тормоза таких запросов становятся неудивительными. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.11.2005, 23:00 |
|
||
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.11.2005, 10:03 |
|
||
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
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 п. для варианта А - влечет усложнение структуры запросов и снижение скорости их обработки для варианта В - упрощение и повышение скорости, но ценой более сложных алгоритмов для управления дополнительной ПРАВОЙ границей периода :)) а так я во всем согласен спасибо за участие в обсуждении ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.11.2005, 12:07 |
|
||
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
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 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.11.2005, 13:40 |
|
||
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
плюс вместо NULL использовать "конец всех времён", что то вроде 31.12.9999 и тогда не потребуется доп условий IMHO, Mon$te® ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.11.2005, 11:28 |
|
||
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
4d_monsterплюс вместо NULL использовать "конец всех времён", что то вроде 31.12.9999 Можно. Но у меня есть большая нелюбовь к "магическим числам". Плюс, с ними иногда возникают изрядно дурацкие проблемы, например какой-нибудь YY-формат в неудачном месте. 4d_monsterи тогда не потребуется доп условий Тогда потребуются доп. усилия в интерфейсе - например, при выводе затирать это магическое число или писать вместо него "наст. время". А доп. условия.. Не скажу за Access, но лично меня Код: plaintext не особо напрягает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.11.2005, 12:56 |
|
||
|
"Историчные" поля - как правильно делать?
|
|||
|---|---|---|---|
|
#18+
Опять о наболевшем... Wolfcub принцип хранения истории мне ясен - мне сейчас важно определиться: ВАРИАНТ А: хранить ОБЕ границы временного периода или ВАРИАНТ В: только ЛЕВУЮ (раннюю) чисто из следующих соображений: A. скорость обработки сложных запросов B. сложность программирования триггеров для управления ПРАВОЙ (вспомогательной) границей временного периода может быть я предъявляю слишком высокие требования к универсальности структуры, но мне хотелось бы реализовать поддержку след. возможных действий пользователя: 1. штатное изменение значения после того как оно произошло 2. изменение значения, которое произойдет в будущем 3. редактирование истории изменений: - удаление записей из истории - добавление - в том числе и в середину - корректировка даты начала - в том числе с изменением порядка следования записей!!! 1 п. в реализации вообще примитивный 2 п. простой как для варианта А , так и В 3 п. для варианта А - влечет усложнение структуры запросов и снижение скорости их обработки для варианта В - упрощение и повышение скорости, но ценой более сложных алгоритмов для управления дополнительной ПРАВОЙ границей периода В существующей системе, реализованной в варианте А (храним начало и конец периода), теперь требуется вводить предыдущие данные о работе сотрудника задним числом. При этом известна, естественно, только дата начала работы. Получается, что теперь нужно писать триггеры, которые бы при добавлении записи автоматически выполняли бы следующие действия: - определение даты конца нового периода - корректировка даты конца предыдущего во времени периода А кроме того - аналогичные действия для удаления периода или изменения его временных параметров... Хочу спросить - этого будет достаточно, или нужно еще что-то предусмотреть? С новым годом и спасибо! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.01.2006, 09:59 |
|
||
|
|

start [/forum/topic.php?fid=32&fpage=144&tid=1545488]: |
0ms |
get settings: |
10ms |
get forum list: |
22ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
73ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
70ms |
get tp. blocked users: |
2ms |
| others: | 249ms |
| total: | 448ms |

| 0 / 0 |
