metaclass: (Default)
[personal profile] metaclass
Будучи связан с базами данных по долгу службы в течение последних 7 лет,
постоянно задумываюсь об отсутствии в них многих полезных вещей. Все они
либо ни с какого бока не относятся к реляционной модели данных, либо
противоречат ей, что,собственно говоря, и является причиной отсутствия этих
вещей на уровне базы и необходимости каждый раз делать их заново.


Первая из таких вещей - отсутствие в описаниях полей и таблиц упоминания
о том, что их вообще-то редактируют пользователи. Которые любят понятные
сообщения об ошибках, а не "Foreign key "FK_UserEditedFieldRefToOtherTable"
violation". Любят справочники, из которых так удобно доставать эти самые
значения внешних ключей. Любят названия полей на родном языке и с пробелами
в них. Любят поля для редактирования с форматированием, куда гораздо труднее
ввести неправильное значение.

Соответственно, вводится таблица FieldDescs стиля вроде:
TABLE_NAME
FIELD_NAME
USER_FIELD_NAME
FORMAT
VIEW_WIDTH
REFTABLE
итд,

заполняется и таскается с собой вместе с инсталлятором/дампом базы. Обрабатывается
при отображении заголовков полей в экранных таблицах и при редактировании.

----------
Вторая вещь достаточно спорная и заимствована из идеи о объектных базах данных.
Это наследование структуры записей. Т.е. мы имеем, к примеру, две таблицы

tbl0
Field0,
Field1,
Field2
и
tbl1
Field0,
Field1,
Field2,
Field3,
Field4

при этом вторая таблица фактически расширяет первую двумя дополнительными полями.
Каждой записи из второй таблицы соответствует запись в первой.

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

select tbl0.id, tbl0.Field0,tbl0.Field1,tbl0.Field2,tbl1.Field3,tbl1.Field4
from tbl0
left join tbl1 on tbl1.id=tbl0.id

в данном случае печаль в том, что добавление объекта требует заполнения
всех таблиц в которые попадают его части и установки первичного ключа
во всех таблицах.

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

select tbl0.Field0,tbl0.Field1,tbl0.Field2
from tbl0
union
select tbl1.Field0,tbl1.Field1,tbl1.Field2
from tbl1

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

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


---------
Третья часть - версионность записей и история их изменений

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

Но дело в том, что часто версионность и история изменений нужна и на пользовательском уровне.
Даже реализовав систему разграничения доступа к записям и разрешив менять записи только строго
определенным пользователям - у них возникает вопрос "А какое значение в этой записи было вчера?".
Поэтому приходится реализовывать историю изменений и хранение версий самому, как минимум частично
повторяя существующую функциональность сервера.

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

Date: 2005-04-19 07:18 am (UTC)
From: [identity profile] apophates.livejournal.com

Соответственно, вводится таблица FieldDescs стиля вроде:
заполняется и таскается с собой вместе с инсталлятором/дампом базы. Обрабатывается
при отображении заголовков полей в экранных таблицах и при редактировании.


Или иным образом сохраняеые метаданные. Вот пример софтинки, которая удачно скрывает проблему: AppMaker (http://www.westheaven.com/app/whWebStyle1.asp?id=86&catid=95&pg=1&cpg=whWebStyle1.asp).


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


А кто сказал, что реляционая теория - способ удовлетворения всех наших желаний? Догматики штудируют низкоуровневый "ассемблер" SQL, в то время, как реально продуктивны только связки СУБД и некоторого рантайма.

Вот, поглядите понимательнее: http://www.alphora.com/ К тому же, оно фактически фришное. Денег хотят только за подробные доки и примеры.


Третья часть - версионность записей и история их изменений

Версионность - частный случай временнЫх рядов. На эту тему у буржуев продаются какие-то книжки. Вот эта вот (http://www.amazon.com/exec/obidos/tg/detail/-/1558604367/qid=1113894749/sr=8-1/ref=sr_8_xs_ap_i1_xgl14/103-5386314-3122207?v=glance&s=books&n=507846) у меня лежит в PDF (прочесть пока не довелось).

Date: 2005-05-04 04:01 pm (UTC)
From: [identity profile] golosptic.livejournal.com
Третья часть - версионность записей и история их изменений

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

Но дело в том, что часто версионность и история изменений нужна и на пользовательском уровне.
Даже реализовав систему разграничения доступа к записям и разрешив менять записи только строго
определенным пользователям - у них возникает вопрос "А какое значение в этой записи было вчера?".
Поэтому приходится реализовывать историю изменений и хранение версий самому, как минимум частично
повторяя существующую функциональность сервера.

А еще есть такая вещь, как изменения задним числом в бухгалтерии. Мрачная печаль, хотелось бы заметить.
Изменение одной записи иногда тянет за собой каскад изменений других и методику адекватной

В 90-ом году написал на Clipper 5 движок, который реализовывал обе задачи - т.е. журналирование и была возможна корректировка записей в двух режимах - внесение очередных изменений (по ним можно было вытаскивать историю) и исправление ошибок задним числом. Когда выпустил бету (писалось всё под конкретную аппликуху), решил, что пойду повешусь от полноты пережитых чувств.
Релиз так и не был выпущен, в связи с переводом проекта на CodeBase.

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

Так вот, логическим было показана, что задача в общем виде не решабельна. Есть несколько различных методов - их приходится отруливать вручную на основе свободного волеизлеяния бухгалтера.

Profile

metaclass: (Default)
metaclass

April 2017

S M T W T F S
      1
2345678
9101112 131415
16171819202122
23242526272829
30      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Aug. 23rd, 2025 12:13 am
Powered by Dreamwidth Studios