![]() |
Биллинговая система NoDeny. Структура таблиц БД |
Детальное описание таблиц.
- admin
- arch_users
- cards
- dblogin
- dopfields/dopvalues/dopdata
- files
- login
- pays
- users
- s-таблицы
- t-таблицы
- x-таблицы
- y-таблицы
- z-таблицы
Таблицы баз данных
Для распределения нагрузки система NoDeny работает с несколькими базами данных, которые могут находиться на разных серверах. В простейшем случае можно все указатели установить на одну базу данных, это корректная операция. Автор именует базы данных как: основная, дополнительная и база авторизации.
Дополнительная база данных не хранит ключевую информацию, поэтому не так требовательна к надежности как основная. Большинство таблиц в дополнительной БД создаются автоматически ядром NoDeny - для каждого дня своя таблица. Это с одной стороны облегчает удаление устаревших данных, с другой стороны возможные объемы данных могут быть гигантскими, в частности в сети автора ведется полная детализация трафика, что составляет примерно 200 млн. записей в сутки. C такими объемами гораздо оптимальнее работать когда каждая таблица ответственна за определенный день месяца.
Трафик хранится в таблицах разных типов, последние определяются по первой букве имени таблицы. Необходимо отметить, что в системе NoDeny трафик предназначен не только для тарификации клиента. Ведется статистика по т.н. "нулевому пресету". Эта статистика предназначена для тех случаев, когда вы хотите оценивать трафик по критериям вашего вышестоящего провайдера. Например, последний продает вам канал без разделений на типы (внешний, городской, игровой и т.д), которые вы применяете в тарификации для своих клиентов. В таком случае, вы можете анализировать статистику по нулевому пресету для определения реальной загрузки ваших каналов.
Исходя из существования понятия "нулевой пресет", NoDeny для каждой таблицы определенного типа создает аналог, в котором обсчет производится на основе нулевого пресета. Так аналогом таблицы x является таблица s, а для x - y.
Типы таблиц с трафиком:
- x-таблицы содержат информацию об объемах трафика, потребленных каждым клиентом за каждый период снятия статистики.
Структура:
mid - id клиента (см. таблицу users); time - время среза статистики в формате timestamp; class - номер направления, которым классифицированы данные объемы трафика in - трафик к клиенту, байт; out - трафик от клиента, байт.Если клиент за период снятия статистики сформировал трафик нескольких направлений, то создается несколько записей с разными class, но с одним time.
- y-таблицы аналогичны x-таблицам, однако направления определяются на основе нулевого пресета, а не на основе пакета тарификации клиента.
- z-таблицы содержат максимально детализированную статистику по ip, портам и протоколам для трафика каждого абонента для которого включена такая функция. Эти таблицы наиболее требовательны к ресурсам памяти т.к. хранят очень большое количество информации. Последнее является причиной почему таблицы с трафиком создаются персонально для каждого дня.
Структура:
mid - id клиента (см. таблицу users); time - время среза статистики в формате: timestamp минус timestamp начала суток; bytes - трафик, байт; direction - направление, 0 - от клиента, 1 - к клиенту; ip - ip удаленной стороны, упакованный в 4 байта; port - порт удаленной стороны; proto - номер протокола.Время среза статистики для уменьшения объема таблицы предоставлено в сокращенном виде. Как известно, timestamp сообщает о количестве секунд, прошедших с начала 1970 года. В нашем случае за начало принимается 0 часов 0 минут тех суток, на которые предоставлена информация. Таким образом, если значение time = 10 в таблице z2008x3x8, то оно будет указывать на срез 10 секунд 8 марта 2008 года.
- s-таблицы хранят общий за сутки трафик каждого клиента. Эти таблицы формируются «задним числом» только при наступлении новых суток. Ядро NoDeny на основе x-таблицы соответствующего дня формирует s-таблицу для этого дня.
Структура:
mid - id клиента (см. таблицу users); class - номер направления, которым классифицированы данные объемы трафика; in - трафик к клиенту, байт; out - трафик от клиента, байт.Видно, что таблица аналогична x-таблице, за исключением отсутствия поля time, поскольку хранит информацию не за срез, а за целые сутки.
- t-таблицы аналогичны s-таблицам, хранят суммарную статистику трафика y-таблиц.
- v-таблицы хранят информацию об иных статистических показателях: сколько потоков трафика сформировал абонент, сколько было зарегистрировано в детальной статистике, было ли превышение допустимого количества регистрируемых потоков, велась ли вообще детализация и др.
- traf_lost - таблица «неучтенного» трафика, хранит данные о трафике, который не удалось классифицировать, что свидетельствует о неправильной настройке системы, например, пробросе трафика вне контроля NoDeny либо неправильной настройке NoDeny.
- user_select - вспомогательная таблица, используется для временного хранения ключевых данных клиентов когда необходимо выполнить сложный sql-запрос из разных баз данных, что пока невозможно СУБД mysql, поэтому данные клиентов из основной базы копируются в эту таблицу.
Основная база данных содержит такие таблицы:
- admin - таблица со списком администраторов и их привилегиями:
id - id администратора; office - отдел (см. таблицу offices); admin - логин; passwd - зашифрованный пароль; session - идентификатор текущей сессии; session_expire - когда сессия будет удалена; name - имя админа; post - должность; privil - привилегии; regions - приоритетные районы; tunes - персональные настройки; pay_mess - список предустановленных комментариев для платежей; ext - расширение у аватара; email - почтовый ящик; email_grp - от каких групп клиентов получать письма по почте; mess - сообщение от главного администратора; temp_block_grp - временная блокировка доступа к определенным группам клиентов;Привилегии задаются в виде списка чисел, разделенных запятыми. Каждое число указывает на то, что соответствующая ему привилегия включена. Список соответствий число=привилегия можете узнать из файла admin.pl.
- admin_session - активные на данный момент веб-сессии администраторов.
- config - таблица конфигурационных файлов. Система NoDeny оформляет конфигурацию в виде текстового файла, но при этом дублирует ее в базу данных, причем не замещает текущую, а создает новую запись. Благодаря этому всегда можно сделать откат. В поле time - время записи конфига. Ядро NoDeny при загрузке выбирает самый поздний по времени.
- conf_sat. При старте агенты на сателитах загружают свои конфигурационные файлы из этой таблицы.
id - id сателлита; time - время последней модификации конфига; login - логин сателлита; name - имя; comment - комментарий; config - непосредственно конфиг в виде текстового блока, в котором каждая строка описывает определенный конфигурационный параметр. Шаблон параметров задается в файле satellite.cfg Passwd_Key - ключ шифрования паролей в базе данных. Должен сответствовать значению $Passwd_Key в файле nodeny.cfg.pl, в противном случае авторизация клиентов не будет проходить.
- dblogin - таблица-очередь, авторизированных разными агентами, клиентов. Данные впоследствии обрабатываются ядром NoDeny.
id - порядковый номер записи; mid - id учетной записи клиента (см. таблицу users); act - режим авторизации; time - время авторизации (timestamp).Режим авторизации состоит из двух частей: кода агента, который принял авторизацию и кода авторизации. Смотрите описание к таблице login.
- files - через эту таблицу происходит обмен файлами между модулями NoDeny. В частности, через эту таблицу ядро NoDeny передает агентам доступа списки сетей, которые находятся не в БД, а загружаются, скажем, с другого сайта - сети UA-IX, например.
- nets - список описаний направлений, содержит информацию по сетям каждого пресета.
- pays - таблица событий (переводится как «платежи», что наследовано от предыдущих версий NoDeny). Хранит все события связанные с каждым абонентом и сетью: регистрация изменения данных, ошибочные действия, сообщения, платежи, события и т.д.
Структура:
Поле type может принимать строго такие значения:
Для записей с кодом 30 и 50, поле cash должно быть всегда равным 0.
Тип 40 является внутренней проводкой, указывающей на перемещение наличности от одного администратора к другому. В поле reason должен быть указан id администратора передающего наличные, а в поле coment - принимающего наличные.
Поле bonus, установленное в значение 'y' указывает на то, что платеж безналичный. Для типа 20 всегда bonus='y'.
Тип 30 указывает на то, что запись является либо сообщением либо комментарием. Чем именно скажет поле category.
Тип 50 наиболее обширный в описании. Как обычно, поле category регламентирует действие записи с типом 50.
В файле paystype.pl прописаны действия, которые необходимо применить для расшифровки поля reason для определенных категорий событий.
id - уникальный id записи; mid - id клиента (см. таблицу users); cash - денежная сумма, для всех нефинансовых записей = 0; time - время формирования записи, timestamp; admin_id - id администратора (см. табл. admin), который сформировал запись, если запись сформировал клиент или система (например, ядро) = 0; admin_ip - ip администратора/клиента с которого было произведено формирование данного события. Для ядра = 0, что соответствует 0.0.0.0, ip упаковывается в 4 байта; office - номер отдела, в котором работает админ сформировавший запись. Для ядра и клиентов = 0; bonus - для финансовых платежей указывает безналичный ли платеж; reason - многофункциональное поле. В зависимости от типа платежа (type) и категории (category) может являться: - комментарием для администратора, если запись является сообщением; - информацией о каком-то событии, например, какие поля в учетной записи были изменены; - закодированным событием, например, данные о работе. coment - многофункциональное поле. Обычно хранит сообщение для клиента. type - тип записи: платеж, событие, сообщение, передача наличных; category - категория платежа, более детально сообщает о внутреннем устройстве текущей записи.
Поле type может принимать строго такие значения:
10 - платеж клиента; 20 - временный платеж; 30 - сообщение/комментарий клиенту; 40 - передача наличных; 50 - событие.Типы 10 и 20 являются финансовыми платежами, т.е влияют на состояние счета клиента. Сумма всех платежей с типами 10 и 20 строго соотвествует значению поля balance в таблице users. При добавлении/удалении платежей с типом 10 и 20, система модифицирует поле balance.
Для записей с кодом 30 и 50, поле cash должно быть всегда равным 0.
Тип 40 является внутренней проводкой, указывающей на перемещение наличности от одного администратора к другому. В поле reason должен быть указан id администратора передающего наличные, а в поле coment - принимающего наличные.
Поле bonus, установленное в значение 'y' указывает на то, что платеж безналичный. Для типа 20 всегда bonus='y'.
Тип 30 указывает на то, что запись является либо сообщением либо комментарием. Чем именно скажет поле category.
Тип 50 наиболее обширный в описании. Как обычно, поле category регламентирует действие записи с типом 50.
В файле paystype.pl прописаны действия, которые необходимо применить для расшифровки поля reason для определенных категорий событий.
- plans2 - таблица с тарифами.
- sat_log - в эту таблицу агенты на сателлитах периодически записывают отчетную информацию, благодаря чему появляется возможность их мониторить.
- users - таблица с данными клиентов:
id - id учетной записи клиента; ip - ip в текстовом виде; name - (теперь) логин; passwd - закодированный пароль; grp - группа (см. табл. user_grp); mid - id основной записи; contract - договор; contract_date - timestamp заключения договора; state - состояние доступа вкл/выкл; auth - текущее состояние авторизации; balance - баланс; money - зарезервировано; limit_balance - граница отключения; block_if_limit - отключать ли запись при достижении границы отключения; sortip - используеся при сортировки записей по ip; modify_time - timestamp последней модификации записи; fio - ФИО; srvs - дополнительные услуги, каждый бит - услуга; paket - номер пакета тарификации (см. табл. plans2); next_paket - пакет на следующий месяц, 0 - не менять; hops - (теперь) точка подключения; cstate - техническое состояние (настроить/ремонт/вирусы...); cstate_time - timestamp последнего изменения поля cstate; comment - комментарий; lstate - нужна авторизация/всегда онлайн; start_day - «день начала потребления услуг»; detail_traf - включить ли детализацию трафика.Исторически сложилось, что некоторые поля сменили свое назначение.
У любого клиента всегда есть одна и только одна основная запись. Mid=0 указывает, что запись основная. Все финансовые операции происходят только с этой записью. Дополнительные записи ссылаются на основную через поле mid, которое указыват на ее id. В дополнительных записях поля balance, srvs и start_day должны быть нулевыми. Значения полей grp и paket копируются из основной записи.
- users_grp - таблица описания групп клиентов. Кроме интуитивно понятных полей, включает grp_admins и grp_admins2. В этих полях через запятую перечислены id администраторов, которые имеют доступ к группе. Если администратор присутствует в обоих полях - ему дается полный доступ, если в одном - ограниченный. Всегда в начале и конце списка стоит ноль. Администратора с id=0 нет в БД, эта внутренняя фича предназначена для упрощения поиска по регулярному выражению.
- traf_info - содержит статистическую информацию о ходе снятия статистики: время, затраченное на выполнение разных операций, количество обработанной информации и др. Позволяет вычислить слабые (наиболее нагруженные) части системы.
cards - таблица карточек пополнения счета
Структура:
Состояние карты определяется полем alive, которое может принимать значения:
Видно, что карту можно активировать только в единственном состоянии «good». При генерации картам устанавливается состояние «stock», которое в админке именуется как «можно активировать после продажи». Из состояния «stock» в состояние «good» карта может перейти двумя способами:
1) При продаже через админку NoDeny, когда администратор вручную вводит серийный номер карты. При этом проводится платеж о продаже карточки.
2) Администратор может самостоятельно перевести карточку из «stock» в «good» если ему даны соответствующие права.
Второй вариант предназначен строго для тех случаев, когда реализатор карточек не работает через админку NoDeny, т.е. ведет учет карточек своими средствами. Поэтому продажа каждой карточки не регистрируется в биллинге. Для того, чтобы клиенты имели возможность активировать такие карточки, последние необходимо вручную перевести в состояние «good».
Первый вариант с реализацией карточек через админку более трудоемкий, но более надежный по безопасности т.к. карточки могут быть активированы, только после того как была оформлена продажа каждой, т.е. при утере, передачи карты клиенту без получения денег, такая карточка остается бесполезной для клиента.
r>0 - указывает на id администратора, за которым числится эта карта.
r=0 - устаревшая значение «карточка на складе», сейчас r не может быть равным 0.
admin_sell>0 - карточка продана админом с id = admin_sell, при этом устанавливается r=-2
Важно: и r и admin_sell связывает карточку с администратором, однако есть определенные тонкости: admin_sell не равный 0 указывает на то, что карточка была продана через биллинг и что проведен соответствующий платеж. Т.е. деньги по биллингу уже учтены. Естественно, карточки не обязательно продаются через биллинг, например, передаются на реализацию. В этом случае речь не может идти о записи в биллинг платежа о продаже карточки. Эти карточки учитываются через поле r. Поэтому при подсчете «наличности на руках», суммируются все номиналы карточек, у которых поле r = id контрагента (администратора) и итоговая сумма числится за этим администратором.
При продаже карточки через биллинг поле r обязательно устанавливается в отрицательное значение для того чтобы номинал этой карточки уже не числился за администратором, поскольку система проводит дополнительный платеж о продаже данной конкретной карточки.
Ситуация, когда r>0 и admin_sell>0 считается некорректной и не допускается.
В биллинге также существует понятие ваучер. В отличие от карточек пополнения счета (хотя ваучер и есть карточка пополнения со стороны клиента), ваучеры выдаются биллингом в момент запроса, т.е. администратор указывает какой номинал ему необходим, биллинг выбирает свободную карточку оплаты, устанавливает admin_sell, проводит соответствующий платеж, после чего выводит данные карточки на экран. Эти данные администратор может распечатать и передать клиенту.
Обратите внимание, что в этом случае никакой передачи карточек не происходит, т.е. не задействуется поле r. Однако предварительно все карточки, которые находятся на складе и которые можно реализовать в виде ваучера должны быть помечены как r=-1.
При передаче карточек от одного администратора к другому, из состояния «good» и «stock» они переводятся в состояние «move», а поле rand_id становится равным id администратора, на которого оформляется передача. После подтверждения через админку принимающим администратором, карточки переводятся в состояние «stock» (даже если до этого у них было состояние «good»). Владелец (по полю r) карточек изменяется только после подтверждения передачи.
cid - серийный номер карты cod - код активации money - номинал stime - время генерации карты etime - время окончания действия atime - время активации admin - id админа, сгенерировавшего карту alive - состоянии карты rand_id - вспомогательное поле, используется системой при резервировании карточек admin_sell - id админа, который продал карточку time_sell - время продажи карточки id_sell - id_sell указывает на id платежа в таблице pays r - id администратора, которому была передана карточкаВремя активации atime не равное нулю не гарантирует, что карта активирована! Следует читать так: если карта активирована, то atime указывает на время ее активации.
Состояние карты определяется полем alive, которое может принимать значения:
good - карта не активирована и может быть активирована; bad - карта заблокирована; move - карта в состоянии перемещения, не может быть активирована пока не выйдет из этого состояния; stock - карта не активирована, не может быть активирована пока не выйдет из этого состояния; число - id клиента, которым активирована карта.
Видно, что карту можно активировать только в единственном состоянии «good». При генерации картам устанавливается состояние «stock», которое в админке именуется как «можно активировать после продажи». Из состояния «stock» в состояние «good» карта может перейти двумя способами:
1) При продаже через админку NoDeny, когда администратор вручную вводит серийный номер карты. При этом проводится платеж о продаже карточки.
2) Администратор может самостоятельно перевести карточку из «stock» в «good» если ему даны соответствующие права.
Второй вариант предназначен строго для тех случаев, когда реализатор карточек не работает через админку NoDeny, т.е. ведет учет карточек своими средствами. Поэтому продажа каждой карточки не регистрируется в биллинге. Для того, чтобы клиенты имели возможность активировать такие карточки, последние необходимо вручную перевести в состояние «good».
Первый вариант с реализацией карточек через админку более трудоемкий, но более надежный по безопасности т.к. карточки могут быть активированы, только после того как была оформлена продажа каждой, т.е. при утере, передачи карты клиенту без получения денег, такая карточка остается бесполезной для клиента.
r>0 - указывает на id администратора, за которым числится эта карта.
r=0 - устаревшая значение «карточка на складе», сейчас r не может быть равным 0.
admin_sell>0 - карточка продана админом с id = admin_sell, при этом устанавливается r=-2
Важно: и r и admin_sell связывает карточку с администратором, однако есть определенные тонкости: admin_sell не равный 0 указывает на то, что карточка была продана через биллинг и что проведен соответствующий платеж. Т.е. деньги по биллингу уже учтены. Естественно, карточки не обязательно продаются через биллинг, например, передаются на реализацию. В этом случае речь не может идти о записи в биллинг платежа о продаже карточки. Эти карточки учитываются через поле r. Поэтому при подсчете «наличности на руках», суммируются все номиналы карточек, у которых поле r = id контрагента (администратора) и итоговая сумма числится за этим администратором.
При продаже карточки через биллинг поле r обязательно устанавливается в отрицательное значение для того чтобы номинал этой карточки уже не числился за администратором, поскольку система проводит дополнительный платеж о продаже данной конкретной карточки.
Ситуация, когда r>0 и admin_sell>0 считается некорректной и не допускается.
В биллинге также существует понятие ваучер. В отличие от карточек пополнения счета (хотя ваучер и есть карточка пополнения со стороны клиента), ваучеры выдаются биллингом в момент запроса, т.е. администратор указывает какой номинал ему необходим, биллинг выбирает свободную карточку оплаты, устанавливает admin_sell, проводит соответствующий платеж, после чего выводит данные карточки на экран. Эти данные администратор может распечатать и передать клиенту.
Обратите внимание, что в этом случае никакой передачи карточек не происходит, т.е. не задействуется поле r. Однако предварительно все карточки, которые находятся на складе и которые можно реализовать в виде ваучера должны быть помечены как r=-1.
При передаче карточек от одного администратора к другому, из состояния «good» и «stock» они переводятся в состояние «move», а поле rand_id становится равным id администратора, на которого оформляется передача. После подтверждения через админку принимающим администратором, карточки переводятся в состояние «stock» (даже если до этого у них было состояние «good»). Владелец (по полю r) карточек изменяется только после подтверждения передачи.
files - предназначена для хранения файлов. Необходимость в этом возникает, когда система NoDeny распределена и требуется сателлитам передавать файлы со списком сетей, по которым агент управления сформирует соответствующие правила. Например, точка обмена трафиком UA-IX, в которую входит большое количесво сетей, постоянно изменяется. Если подгрузка списка сетей на сервер ядра организована, то ядро NoDeny, при каждом обновлении списка сетей, будет обновлять соответствующие данные в таблице files.
Структура:
Кроме того, таблица files выполняет вспомогательную роль контроля версий таблиц. Строка с зарезервированным
значением поля name, равным `tbl_version`, в поле data содержит номер версии таблиц NoDeny. Обратите внимание,
номер версий таблиц - это не версия NoDeny. Версия таблиц указывает в каком состоянии находятся структуры
всех таблиц NoDeny. Если разработчики производят изменения структуры какой-либо таблицы - это изменение
фиксируется под определенным номером в файле bill.sql. Таким образом, всегда есть возможность обновить
структуру таблиц до последней строго с той точки, которой они соответствуют. При инсталляции системы,
таблицы отсутствуют, принимается номер версии 0 и, следовательно, файл bill.sql обрабатывается полностью
по цепочке с самого первого sql-запроса, который, естественно, создает таблицу files, чтобы
иметь возможность фиксировать номера версий.name - имя файла data - содержимое файла
arch_users - таблица с данными клиентов за прошлые месяцы
Структура:
mon - месяц year - год uid - id клиента uip - ip grp - группа paket - пакет preset - пресет auth - 1 - была хотя бы одна авторизация за месяц, 0 - не было no_submoney - причина по которой с клиента не снимались деньги при переходе на новый месяц: 0 - деньги снимались (существует запись в таблице платежей) 1 - группа клиента блокирует снятия, например группа «разорвавшие договора» 2 - клиент еще не начал пользоваться услугами (день начала потребления услуг <0)Внимание. Если за определенный месяц и год для определенного клиента присутствует запись - это означает, что при переходе на новый месяц (см. скрипт new_month.pl) клиент уже был обработан. Таким образом, при повторном запуске скрипта не произойдет повторное снятие за услуги. Повторный запуск теоретически может понадобиться в случае если во время перехода на новый месяц произошел сбой (например, проблемы соединения с БД), т.е. когда переход мог произойти частично. В этом случае для оставшихся непереведенных клиентов необходимо запустить new_month.pl повторно.
login - таблица авторизаций клиентов, хранит информацию о том, кто и когда авторизовался для доступа в интернет.
Агенты авторизации авторизуют клиентов и регистрируют это в таблице dblogin. Ядро периодически с небольшим интервалом времени извлекает данные из этой таблицы, проводит проверки стоит ли отключить по задолженности клиента, записывает более расширенную информацию в таблицу login. Обратите внимание, данная таблица заполняется исключительно ядром.
Структура:
Метод авторизации:
1 - с помощью программы-авторизатора;
2 - PPPoE;
3 - Web-авторизация;
4 - на порту свича (802.1x).
Режим авторизации:
0 - Перестал быть авторизованным;
1 - Авторизован. Доступ заблокирован: превышен лимит трафика;
2 - Авторизован. Доступ заблокирован: превышен лимит денежной задолженности;
4 - Авторизован. Доступ заблокирован: в данное время суток по условию пакета;
5 - Авторизован. Доступ заблокирован;
7 - Авторизован в режиме "полный доступ";
8 - Авторизован в режиме "только сети направления 2";
9 - Авторизован в режиме "выключен" (только локальная сеть).
Например, act=19 указывает на то, что клиент авторизовался с помощью программы авторизатора в режиме «выключен».
mid - id клиента act - состояние авторизации time - время события в виде timestampСостояние авторизации - число, которое состоит из двух частей: первая цифра - код, указывающий каким методом авторизовался клиент, вторая - непосредственно режим авторизации.
Метод авторизации:
1 - с помощью программы-авторизатора;
2 - PPPoE;
3 - Web-авторизация;
4 - на порту свича (802.1x).
Режим авторизации:
0 - Перестал быть авторизованным;
1 - Авторизован. Доступ заблокирован: превышен лимит трафика;
2 - Авторизован. Доступ заблокирован: превышен лимит денежной задолженности;
4 - Авторизован. Доступ заблокирован: в данное время суток по условию пакета;
5 - Авторизован. Доступ заблокирован;
7 - Авторизован в режиме "полный доступ";
8 - Авторизован в режиме "только сети направления 2";
9 - Авторизован в режиме "выключен" (только локальная сеть).
Например, act=19 указывает на то, что клиент авторизовался с помощью программы авторизатора в режиме «выключен».
dopfields/dopvalues/dopdata - таблицы, обеспечивающие механизм хранения дополнительных полей данных. Проблематично, да и неразумно, включить в NoDeny все возможные данные, которые могут понадобиться. Скажем, одной организации необходимо хранить паспортную информацию каждого абонента, другой - юридические данные, третьей - специфические технические данные, четвертой - резюме каждого абонента и т.д. Поэтому разработан механизм хранения всех специфических данных в одной таблице (dopvalues) в одном стоблце (field_value). При этом тип параметра и его назначение расшифровывается исходя из таблицы dopfields, которая описывает названия полей и их характеристики. dopdata - объединение обоих таблиц.
Кроме того, предусмотрен механизм ревизий - при изменении данных, старые значения сохраняются, а новые добавляются с бОльшим номером ревизии. Благодаря этому появляются такие возможности:
1) Нет необходимости вести логи изменений т.к. в каждой ревизии есть поле `администратор, внесший изменения`;
2) Возможность вернуться к любой версии данных;
3) В удаленных модулях нет необходимости постоянно отслеживать изменения данных - достаточно мониторить изменения ревизий. например, в модуле управления фаерволом используются данные по персональным скоростям, которые извлекаются из таблицы dopdata когда обнаружено их изменение по номеру ревизии;
4) При параллельном редактировании данных не будет конфликтных ситуаций.
dopfields - содержит описания дополнительных полей:
id - идентификатор поля template_num - номер шаблона parent_type - с каким объектом ассоциируется поле. 0 - с клиентом field_type - тип поля: целое, строковое, да/нет и т.д. field_name - имя поля field_alias - алиас имени field_flags - строка флагов: убирать ли лидирующие/завершающие проблелы, включить транслитерацию, привести к нижнему регистру и т.д. field_template - регулярное выражение для проверки корректности заполнения поля comment - комментарийdopvalues - содержит данные дополнительных полей:
parent_id - хозяин данного параметра, например id абонента dopfield_id - ссылка на описание параметра в таблице dopfields (по полю id) field_value - значение параметра admin_id - id администратора, внесшего/изменившего данные time - timestamp создания/изменения данных revision - номер ревизии, чем больше тем актуальнееДля разных parent_id ревизия всегда разная.