В Gency используется Простая модель (базы) данных, описывающая связи между записями основной таблицы (таблицы категорий) и дополнительными таблицами (таблицами объектов):
Служебными полями таблицы категорий являются поля id и mode (bits в Gency). Поле id должно иметь символьный тип. Значения этого поля используются для идентификации категорий и соответствующих им таблиц объектов. Допустимо использовать отдельное поле для идентификации таблиц объектов, но в Gency такая возможность сейчас не поддерживается. Для связывания нескольких записей таблицы категорий с одной таблицей объектов можно использовать представления, отражающие точный или измененный образ таблицы объектов:
Поле mode должно иметь целочисленный тип, обычно беззнаковый. Значения этого поля определяют доступность соответствующей таблицы объектов:
- 0 – категория не имеет доступную таблицу объектов;
- 1 – категория не имеет доступную таблицу объектов, но может являться точкой доступа к объектам, хранящимся в какой-либо другой форме;
- 2 – категория имеет доступную таблицу объектов;
- 3 – категория имеет доступную таблицу объектов и, вероятно, объект с пустым символьным идентификатором в ней.
Значащими являются только два младших двоичных разряда данного поля, поэтому, например, значение 4 (1002) также будет соответствовать режиму 0.
Служебным полем таблицы объектов является поле id. Оно может иметь как символьный, так и целочисленный тип, обычно беззнаковый. Значения этого поля используются для идентификации объектов в пределах одной таблицы.
Для доступа к произвольным объектам базы данных используются составные идентификаторы, включающие идентификатор категории и идентификатор объекта в пределах одной таблицы, например в Gency на уровне интерфейса пользователя используются адреса вида /id_категории/id_объекта
(в случае объекта с пустым символьным идентификатором – /id_категории
).
В Gency не поддерживается редактирование записей таблицы категорий, их детальное отображение в режимах 2 и 3, а также какое-либо отображение в режимах 0 и 1. Но к ним можно организовать доступ, как к объектам, используя категорию с рекурсивной связью, т.е. связанную с самой таблицей категорий (напрямую или через представление). Например, можно создать представление site_pages для доступа к категориям с режимом 0 при помощи такого запроса:
CREATE ALGORITHM=MERGE VIEW `site_pages` AS SELECT `id`, `name`, `content` FROM `site_categories` WHERE `bits`&3=0
Для использования этого представления можно создать категорию pages при помощи такого запроса:
INSERT INTO `site_categories` (`id`, `name`, `content`, `bits`) VALUES ('pages', 'Страницы', '', 3)
Такая необычная организация доступа к записям таблицы категорий является очень гибкой при настройке под конкретные нужды.
Не пойму, как связать категории с объектами.
Нужно размещать объекты в отдельных таблицах, используя символьный идентификатор категории при формировании имени соответствующей таблицы объектов. Сейчас в Gency используется такое правило формирования имени таблицы объектов: берется символьный идентификатор категории, в котором все дефисы заменяются на символы подчеркивания, после чего к нему добавляется табличный префикс, например site_ или просто символ подчеркивания.
Также можно размещать объекты в единой таблице и делить их на группы при помощи представлений. Пример создания таких представлений можно найти в статье Как сделать фильтрацию элементов по уровню иерархии?
Для обратного связывания можно добавить в таблицы объектов специальное поле, предназначенное для хранения идентификаторов категорий. Смотрите тот же пример по ссылке из предыдущего абзаца, в котором связующим является поле div (поле cat там используется для связывания на более глубоком уровне вложенности).
Расширение модели, используемое в G-Drive и G-Front (дополнительные биты поля bits и поле module), можно считать отдельным абстрактным слоем. Это позволяет создавать более детализированные базы данных, сохраняя абстрагированность от конкретного front-end-движка.
Насчет поля module (имя может быть другим) полностью согласен. Его наличие может быть обусловлено следующей причиной: категориям с определенным режимом, например 0, требуются разные обработчики и при этом какой-то группе таких категорий требуется общий обработчик. Т.е. это поле необходимо, когда недостаточно имеющихся данных для определения обработчика. К тому же номер режима не предназначен для определения обработчика, хотя и может быть использован для этого с учетом ограниченного количества таких номеров.
Что касается дополнительных битов поля bits, то об их включении в модель нужно подумать. Да, конечно, сама архитектура неявно предполагает наличие двух типов обработчиков. Но вот про возможность обрабатывать (выполнять) шаблоны вне частных обработчиков или вовсе не использовать частные обработчики этого не скажешь.
Помимо типа обработчика и выполнения шаблона вне обработчика расширение также позволяет контролировать наличие GET-параметра p. Причем это хорошо укладывается в модель, т.к. в описании соответствующих флагов говорится о пустых и непустых объектах, а сам параметр является достаточно общим (пагинация, для которой он обычно используется, присутствует всюду). Кстати, от имени «p» можно легко абстрагироваться, так же как и от формы представления параметра (помнится, я писал о возможности указывать в строке параметров только значение параметра, например ?1).
Также обратите внимание на следующий момент. В «новой схеме» отличительным флагом для двух типов обработчиков является бит 4, а не 5, поэтому в модель можно включить из этих двух только бит 4 (используемое сейчас расширение этому не противоречит) и описать его в модели, как флаг, определяющий тип обработчика.
Итак, вводится следующее расширение модели в отношении битов поля mode (bits):
Вводится необязательное поле module, значение которого определяет имя или номер закрепленного за категорией обработчика, если это значение отлично от NULL, 0, пустой строки или строки, состоящей из символа 0.
Номер режима можно продублировать или разместить в старших разрядах поля mode (bits). Это позволит более эффективно различать категории с режимами 2 и 3, явно используемые в Gency, и категории с режимами 0 и 1.
Ниже показана взаимосвязь режима доступа и допустимого формата пути:
Используемые обозначения:
Режим 3 можно использовать не только для доступа к пустому объекту базы данных при помощи программного каркаса, но и для запрета пути формата /category, если в базе данных не размещать соответствующий пустой объект.