LINUX.ORG.RU

[бугалтерия][архитектура] Схема размещения в БД

 


0

0

вот в обычной бумажной бугалтерии основой является списание/занесение на счет, списание+занесение становится транзакцией перевода денех со счета на счет. Смотрим например gnucash для примеру.

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

Теперь вопрос. Как это все хранят в БД (SQL) люди с опытом и всякие известные программыные продукты вроде 1c ? Хранить по строчке на уровне списание -занесение? Или наоборот, хранить по строчке на транзакцию, не занося избыточную информацию но добавляя каждый раз код для обработки этих транзакций ?

Короче вопрос профессионлам, как это правильно делается, как это делается неправильно но распостраненно, где об этом можно почитать.

PS
Стоит ли репостнуть в Talks ?

★★☆

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

Правильно/неправильно понятия растяжимые - что в одной ситуации единственно правильно, в другой полностью неправильно.

no-dashi ★★★★★
()
Ответ на: комментарий от no-dashi

> Ну вообще, стоит заметить что у тебя все смешалось в кучу. Для
> начала, выдели основные сущности, их две - операция и проводка.


Понятно.

> Операция это цикл некоторого процесса (продажа например), и вторая

> сущность - проводка, переброска со счета на счет. Та же продажа

> отображается множеством проводок в одной операции, но каждая проводка

> всегда имеет две стороны (дебет/кредит).


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

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

Как то так.

> Правильно/неправильно понятия растяжимые - что в одной ситуации единственно правильно, в другой полностью неправильно.


Это понятно. Хотелось бы примеров и обоснований почему так. Но коротко. Например(голословно, я не знаю как там) "1эс хранит проводки в таблице вместе с тегом операции. И это хорошо пока число проводок < 1M"

kernel ★★☆
() автор топика
Ответ на: комментарий от Karapuz

> Стоит репостнуть.

Чуть позже - как выяснилось у меня неправильная понятийная база :)

kernel ★★☆
() автор топика

ИМХО ты не озвучил цели, зачем тебе это? Тебе нужно просто зафиксировать некую транзакцию или тебе так же нужно поддерживать некие актуальные(мгновенные или за период) итоги, а также список транзакций за период, с аналогичной адресацией по счетам, содержанию и тд. От этого нужно плясать, а не смотреть на конкретные реализации, тем более 1С.

justuser ★★
()
Ответ на: комментарий от justuser

> ИМХО ты не озвучил цели, зачем тебе это? Тебе нужно просто
> зафиксировать некую транзакцию или тебе так же нужно поддерживать

> некие актуальные(мгновенные или за период) итоги, а также список

> транзакций за период, с аналогичной адресацией по счетам, содержанию

> и тд.


Ну мне скорее нужно второе. Точнее мне нужно чтобы выбранная изначально модель хранения потом не мешала расширяемости. В любом случае будет некий компромисс. И опять же, любой современный бухпакет это некое хранение, некие отчеты и возможность добавлять относительно просто отчеты свои.

> От этого нужно плясать, а не смотреть на конкретные реализации, тем более 1С.


Понимаешь в чем дело, популярные пакеты бухучета уже нашли некие компромиссы. Вот и хотелось бы тезисно узнать какие они, эти самые компромиссы. На ЛОР есть люди которые со всем этим работали. Согласись, если каждый из них черкнет пару строчек, всем от этого будет польза.

kernel ★★☆
() автор топика
Ответ на: комментарий от kernel

>Понимаешь в чем дело, популярные пакеты бухучета уже нашли некие компромиссы.

Правильно мыслишь, вот Линус взял и придумал свой велосипед, а не стал подражать Таненбауму, а ведь мог повторить успех миникса!!!

Ну мне скорее нужно второе. Точнее мне нужно чтобы выбранная изначально модель хранения потом не мешала расширяемости. В любом случае будет некий компромисс. И опять же, любой современный бухпакет это некое хранение, некие отчеты и возможность добавлять относительно просто отчеты свои.

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

justuser ★★
()
Ответ на: комментарий от justuser

> Правильно мыслишь, вот Линус взял и придумал свой велосипед, а не стал подражать Таненбауму, а ведь мог повторить успех миникса!!!

Перед этим он изучил миникс :) Собственно настолько, что сисколлы у него были поначалу миниксовые. А до этого пробовал помочь миниксу, но был прогнан тамошним главным с аргументацией "ххх не нужен" :)


> ... смотри что для тебя предпочтительнее.


Спасибо за разъяснения, но хотелось бы примеров :)

kernel ★★☆
() автор топика
Ответ на: комментарий от kernel

>Спасибо за разъяснения, но хотелось бы примеров :) Погугли что-то типа методических указаний по проектированию баз данных для бухучета - их много болтается в интернетах же.

justuser ★★
()
Ответ на: комментарий от kernel

> Точнее мне нужно чтобы выбранная изначально модель хранения потом не мешала расширяемости

Мораль - тебе нужна модель независимых регистров со сквозной идентификацией объектов в регистрах, с «одетой сверху» структурой межобъектных связей :-)

no-dashi ★★★★★
()
Ответ на: комментарий от no-dashi

>Мораль - тебе нужна модель независимых регистров со сквозной идентификацией объектов в регистрах, с "одетой сверху" структурой межобъектных связей :-)


Завсит от учетной политики, например: Некое ООО, имеет одного поставщика сырья, один продукт, одну технологическую операцию по производству, один склад и одного покупателя, но 500 000 документов в день, приход, передача сырья в цех, выпуск продукции, списание сырья, передача готовой продукции на склад и реализация. Аналитики не нужно, нужен вал за месяц. Учет на таком предприятии, будет радикально отличаться от учета в сети супермаркетов, с сотнями тысяч номеклатуры, сотнями магазинов, с неоходимостью иметь мгновенные остатки, делать сверки с поставщиками, иметь массу разрезов по аналитическому учету. И модели нужно делать сильно разные.

justuser ★★
()

Скорее всего надо хранить счета, балансы счетов, операции над балансами и проводки (проводка — набор операций, произведённых в определённом порядке). Сущности каждого типа имеет смысл хранить в своей таблице (например, счёт acc, баланс bal, операция op, проводка tran).

Для счетов и балансов надо хранить всю историю их изменения (например, изменение информации о держателе счёта, изменение величины баланса). Поэтому каждая запись в таблице счётов и в таблице балансов должна описывать состояние счёта или баланса на определённый промежуток времени. Для этого в каждой записи должны быть поля «от» и «до» (например, from и till). В записи, описывающей последнее состояние счёта/баланса, поле «до» должно иметь значение «условная бесконечность», тогда такую запись легко найти. Когда состояние счёта/баланса меняется, добавляется ещё одна запись, а у записи с предыдущим состоянием модифицируется дата «до». По идее разрывов во времени и перекрытий для одного отдельно взятого счёта/баланса быть не должно, тогда на любую заданную дату должна быть найдена только одна запись, описывающая счёт/баланс. Такая схема хранения позволяет получить информацию по счёту/балансу на любую дату без трудоёмких вычислений.

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

Чтобы всё это работало быстро, необходимо секционировать таблицы и индексы по времени так, чтобы записи, хранящие старое состояние счетов/балансов и старые операции/проводки, хранились отдельно от новых. Например, Partitioning Option к Oracle Enterprise Edition это умеет, но EE и его опции недёшевы.

iliyap ★★★★★
()
Ответ на: комментарий от iliyap

> Чтобы всё это работало быстро, необходимо секционировать таблицы и индексы по времени так

За что я любю ораклистов, так это за то, что они персистентно доставляют лулзы своими предложения по организации данных, когда даже приблизительно неизвестен профиль нагрузки приложения и структура базы :-)

no-dashi ★★★★★
()
Ответ на: комментарий от iliyap

Спасибо, очень познавательно.

> Для операций и проводок историю модификаций хранить не надо, так как

> эти сущности не меняют своего состояния после создания.


А корректировки как делают тогда ?

> Чтобы всё это работало быстро, необходимо секционировать таблицы и

> индексы по времени так, чтобы записи, хранящие старое состояние

> счетов/балансов и старые операции/проводки, хранились отдельно от

> новых.


А в случае если субд этого не держит, нужно разносить по разным таблицам, например ? И из расчета этого момента делать схему ?

kernel ★★☆
() автор топика
Ответ на: комментарий от no-dashi

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

у меня глупый вопрос - а для универсальных систем, бывает такое когда система может менять схему БД в зависимости от необходимых условий. То есть интерфейс на уровне объктов единый, а способы организации БД зависят от. На этапе инсталляции например ?

kernel ★★☆
() автор топика
Ответ на: комментарий от kernel

Видимо вы имеете в виду не «способ организации БД» а способ хранения БД. Например, в MySQL способ хранения называется storage engine: можно выбрать MyISAM, InnoDB, NDB, и т.д. MyISAM всегда хранит данные каждой таблицы в отдельном файле, и тут ничего не настраивается. InnoDB позволяет размещать таблицы в нужных табличных пространствах, а табличные пространства в нужных файлах или сырых устройствах.

PostgreSQL использует такую же двухуровневую систему: таблицы в табличных пространствах, табличные пространства в файлах.

Многие системы не поддерживают секционирование, но имеют механизмы, позволяющие это секционирование сделать самостоятельно. Например, создать view с триггерами на операции insert/update/delete (обычно это называют updatable view). Эти триггеры вставляют данные в реальные таблицы-секции в зависимости от значения поля, по значению которого производится выбор секции. Такую схему не очень приятно поддерживать (надо модифицировать триггеры при добавлении секций), но она вполне рабочая.

iliyap ★★★★★
()
Ответ на: комментарий от iliyap

> Многие системы не поддерживают секционирование, но имеют механизмы, позволяющие это секционирование сделать самостоятельно. Например, создать view с триггерами на операции insert/update/delete (

Я имел в виду такую схему на уровне сервера приложений или самого приложения. Структура БД то меняется

kernel ★★☆
() автор топика
Ответ на: комментарий от iliyap

> Для счетов и балансов надо хранить всю историю их изменения (например, изменение информации о держателе счёта, изменение величины баланса). Поэтому каждая запись в таблице счётов и в таблице балансов должна описывать состояние счёта или баланса на определённый промежуток времени.

> Для операций и проводок историю модификаций хранить не надо


Всё ровно наоборот.

> эти сущности не меняют своего состояния после создания.


Школярская наивность. Лечиться работой в реальном мире.

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

> > Для операций и проводок историю модификаций хранить не надо

> Всё ровно наоборот.


IMHO, ты путаешь историю как элемент логики и историю как элемент аудита.

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

Или второй пример - ставка налогообложения изменилась. Но старые счета-фактуры и накладные должны печататься из системы в том виде, в каком они были "тогда", до изменения, и все вычисления должны вестись так же. И реализация товара до мая месяца должна попадать в графу "товары с НДС 18%, а с мая месяца и дальше - в графу "товары с НДС 30%". В этом случае история - элемент логики, и нужна всегда, а аудит ей фактически не нужен.

no-dashi ★★★★★
()
Ответ на: комментарий от kernel

> бывает такое когда система может менять схему БД в зависимости от необходимых условий.

Не путаем изменения схемы данных и реорганизацию хранения данных! Второе это нормальный рабочий процесс, а первое встречается крайне редко, практически никогда - только в игрушечных поделках. Если при постановке задачи становится ясно, что нужно хранить атрибуты разнородных классов, на момент разработки неочевидных, то используется LDAP-подобный принцип.

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

no-dashi ★★★★★
()
Ответ на: комментарий от kernel

> Я имел в виду такую схему на уровне сервера приложений или самого приложения

Ну, для этого обычно вводится абстракция объектной модели от структуры данных.

no-dashi ★★★★★
()
Ответ на: комментарий от no-dashi

> ты путаешь историю как элемент логики и историю как элемент аудита.

Нет, не путаю. "Наоборот" относилось в первую очередь вот к этому:

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


Ну и аудит, да. Куда ж без этого.

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

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

Крайне опасное заблуждение. Регистров "состояние объекта на определенный промежуток" времени надо избегать как огня. По опыту работы и разработки, я бы так обобщил накопленые знания:
1. НСИ подлежит журналированию с указанием периода действия каждого журналируемого показателя. НСИ это названия, ИНН, номера счетов, цены, ставки налогов, адреса, штатные расписания и так далее, то есть все справочники. Журналирование не отменяет аудита, и наоборот. Журналирование обязательно, аудит опционален.
2. Операционные регистры (проводки, документы, операции и прочее) должны описывать только характеристики действия. Аудит опционален, его отсуствие несмертельно, хотя и неприятно
3. Таблицы "остатки" надо убивать везде где только возможно. Ну, если без них никак - то их содержимое должно перегенерироваться автоматически везде где только можно.
4. В обязательном порядке должен быть регистр "все объекты" :-)
5. Необходимо как огня избегать ссылок из объекта на объект (например, из накладной на счет-фактуру и наоборот).

no-dashi ★★★★★
()
Ответ на: комментарий от no-dashi

> Крайне опасное заблуждение.

Ты это кому говоришь? Я это предложение логически инвертировал и уже постов -дцать назад написал, что все делают вот так:

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

LamerOk ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.