Когда вы обозреваете множество кода, вы часто удивляетесь, почему что-то было написано так как было. Особенно когда делаются дорогие запросы в базу данных, я все еще вижу вещи, которые могут и должны быть улучшены.
Метка: бд
Проблемы с проектированием базы данных на основе ORM (Kohana)
Сначала перечисляю сущности.
sуstems – некие системы.
preferences – некоторые настройки, сокращенно pref
pref имеет разные типы, например настройки кеша (cache) и тамаута (timeout). Таким образом pref можно записывать в одну таблицу с полями id, value, type или в две разные таблицы – prefcache и preftimeout с той же структурой. Идем дальше.
Поля таблицы system – id, name. Осуществляется связь многие ко многим через таблицу prefs_systems с полями: id_system, id_pref, type (можно вынести сюда в случае отдельных таблиц prefcache и preftimeout.
И вот зачем две таблицы pref, я хочу на каждую делать свой ORM, т.е. есть базовый ORM_Pref extends ORM и от него наследуются ORM_Prefcache и ORM_Preftimeot. Каждый работает со своей таблицей, а общие настройки в базовом классе.
В этом случае в каждой ORM прописываются связи $_has_many. В случае ORM pref все очевидно, по одной записи связей $_has_many к ORM_System. В случае с описанием ORM_System получается такая конструкция (додумался пока писал).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
protected $_has_many = array( 'prefcache' => array( 'model' => 'orm_prefcache', 'foreign_key' => 'id_system', 'through' => 'prefs_systems', 'far_key' => 'id_pref', ), 'preftimeot' => array( 'model' => 'orm_preftimeout', 'foreign_key' => 'id_system', 'through' => 'prefs_systems', 'far_key' => 'id_pref', ), ); |
Вопросы:
- Нормально ли я придумал структуру?
- Могу ли я базовый класс ORM_Pref объявить абстрактным (т.к. у него нет привязанной таблицы и его не надо создавать) ?
- Можно ли как-то улучшить мою структуру? Если все выше правильно, то при добавления нового типа настроек я должен буду прописать связь в ORM_System, это не удобно.
UPD. 02.04.2014
Спустя полтора года мой пост выше кажется мне уже простым вопросом новичка. Решил добавить сюда еще решение по ORM
Получение свойства ORM сразу с UNCOMPRESS.
Проблема: Можно ли как-то через ORM извлекать данные, которые были записаны через COMPRESS () в mysql в BLOB?
В кохановском ОРМ такого нет. Приходится писать функции в ORM типа
1 2 3 4 5 6 7 8 9 10 11 |
public function find_uncompress() { $result = DB::select("*", array(DB::expr("UNCOMPRESS(response)"), "response")) ->from($this->_table_name) ->where("id", "=", $this->pk()) ->execute()->as_array(); return $result; } |
Задачу решает, но было бы приятнее просто указать в каких-то правилах как извлекать столбец, как фильтры после извлечения, только эти во время.
Решение нашел коллега. В нужной ORM модели надо переопределить
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
protected function _build($type) { if($type==Database::SELECT) { $this->select(array( DB::expr("UNCOMPRESS(request)"),'requestUncompress')); $this->select(array( DB::expr("UNCOMPRESS(result)"),'resultUncompress')); } parent::_build($type); } |
В данном случае поля request и result сжаты, извлекаются под псевдонимами с распаковкой и будут доступны $model->requestUncompress, например.