Практически все Yii-приложения построены на базах данных. И хотя фреймворк Yii очень
гибок в плане взаимодействия с базой данных, некоторые решения призваны сделать разработку еще
проще и удобней.
Первый и наиболее важный момент заключается том, что Yii-приложения широко
используют шаблон ActiveRecord. Исходя из этого, все конструктивные соображения
направлены на оптимизацию такого использования, а не на человека, который будет
составлять сложные SQL-запросы. В самом деле, многие из проектных решений напрямую
конфликтуют с передовой практикой для создания дружественных SQL-схем.
Здесь идет речь о создании кода, который могут читать и понимать другие люди, где
названия точно передают смысл. Если не следовать этим простым правилам, то за
получившимся кодом будет гораздо сложнее следить.
Это особенно верно, в случае если вы просите о помощи на форумах или на канале #yii:
использование неподходящих имен, которые не отражают смысла, порождает много
вопросов и уточнений. Вы получите меньше справочной информации, чем могли бы.
Согласованность играет очень большую роль.
Тем не менее, это всего лишь рекомендации, а не правила, и ваш код будет работать, даже
если вы не последовали им. Принимая рекомендации, вы облегчите себе жизнь.
Называйте таблицы баз данных в единственном числе
SQL-таблицы содержат большое количество объектов, модель является лишь одним из
них: странно наблюдать такую картину, где $model = new Comments(). Такая конструкция
встречается снова при определении отношений и во многих других местах.
Назовите вашу таблицу comment вместо comments, invoice а не invoices и так далее, также
указывайте имена моделей классов (Comment, Invoice и т.д.).
Если вы не можете изменить схему базы данных, то измените хотя бы класс модели Yii. Обязательно
сделайте дополнительный комментарий в коде, чтобы напомнить другому пользователю про
это несоответствие.
Не предваряйте имена полей названием таблицы
Такая практика распространена в традиционном проектировании схемы SQL, но это
утомительно при работе с ActiveRecord. Ваша таблица category может иметь вид:
-- NO -- YES
create table category ( create table category(
category_id INTEGER ..., id INTEGER ...,
category_name VARCHAR ..., name VARCHAR ...,
category_value INTEGER value INTEGER
); );
// YUCK // BETTER
$model->category_id $model->id
$model->category_name $model->name
$model->category_value $model->value
Проделывая такой длинный путь, вы вручную создаете SQL-запросы, которые просты для
восприятия, но неудобны для использования в ActiveRecord.
Не включайте префикс таблицы в имя модели класса
Фреймворк Yii поддерживает понятие префикса таблицы, который используется в среде
виртуального хостинга, где все ваши приложения работают с единой базой данных.
Например, начиная названия таблиц блога с blog_, таблиц приложений — с time_ и т.д., вы
можете держать их в одной и той же базе данных, причем они не будут конфликтовать друг с
другом.
Во многих учебниках и примерах также часто встречается префикс tbl_.
Но классы не должны содержать эти префиксы, так как в этом нет необходимости. Ваш блог
и приложение — это две параллельные прямые, которые не пересекаются.
class TblComment extends CActiveRecord { // NO
class Comment extends CActiveRecord { // YES
Это очень отвлекает при просмотре кода.
Указывайте id в качестве идентификатора таблицы
Многие таблицы имеют независимый одиночный столбец с уникальным первичным ключом
(например, int NOT NULL AUTO_INCREMENT PRIMARY KEY). Многие вещи будут
работать плавнее, если называть столбец id (не commentid или postid).
Фреймворк Yii может обнаружить первичный ключ, обращаясь к схеме базы данных,
независимо от того, как вы его называете. Но другие части системы могут быть недоступны и
явно зависят от id ключа.
Пример: CArrayDataProvider обнаружил, что id является ключом, и хотя его можно
переопределить с помощью атрибута keyField, это создает дополнительные удобства, и вы
избегаете необходимость переопределения ключа.
Иногда это правило не применяется, например, когда таблица имеет несколько столбцов
с первичным ключом, или когда первичный ключ таблицы является внешним ключом к
другому идентификатору таблицы.
Избегайте семантически значимых первичных ключевых имен
Классическая ошибка при разработке — создание таблицы с первичным ключом, который
имеет актуальное значение. В этом примере в качестве первичного ключа использовано имя
пользователя:
-- don't do this!
CREATE TABLE user (
name VARCHAR(16) PRIMARY KEY, -- bad idea
email VARCHAR...
...
)
Это создает две проблемы:
- Ссылки на это поле становятся гораздо менее эффективными, потому что оно содержит 16
символов вместо четырехбайтового целого числа. Это может вызвать реальную проблему с
производительностью в более крупном приложении с большим количеством ссылок. - Пользователю будет сложнее изменить свое имя, если ограничения внешнего ключа
включены в эту систему: поле таблицы и все ссылки должны быть изменены одновременно.
Это дорого вам обойдется.
Гораздо лучше создать первичный ключ и сделать имя уникальным:
-- much better
CREATE TABLE user (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(32) NOT NULL UNIQUE,
email ...
...
);
Таким образом, изменение имени пользователя приводит к обновлению только одной этой
записи.
Определите отношения внешнего ключа в схеме базы данных
Большинство баз данных позволяют устанавливать взаимоотношения между таблицами,
например: поле содержит идентификатор, указывающий на первичный ключ другой таблицы.
Эти внешние ключи и помогут обеспечить ссылочную целостность, не позволяя удалить
строку, если кто-то другой указывает на нее.
InnoDB в MySQL применяет ограничения внешнего ключа, и хотя MyISAM позволяет
определить их, он не будет проводить их в действие. Yii понимает, как следует
интерперетировать эти отношения из схемы, а инструменты Gii / Giix будет создавать
отношения автоматически.
Внешние ключи являются важной частью поддержания ссылочной целостности базы данных.
Этому посвящено множество учебников, которые имеются в свободном доступе в сети.
Названия внешних ключевых полей должно заканчиваться на «id»
Если у вас есть поле, которое содержит идентификатор пользователя, вызывайте поле userid,
а не поле user. Это делается для того, чтобы для каждого внешнего ключа, который вы
подключили в таблицу, вы могли определить отношение.
В фреймворке Yii, класс переменных, поля базы данных, виртуальные атрибуты и отношения — все
разделяют единое пространство имен, так что конструкция $model->user не может быть и
внешним ключом в таблице, и отношением.
Вызывая внешний ключ userid, BELONGS_TO
относится к $model->user следующим образом:
class Post extends CActiveRecord {
public function relations()
{
return array(
'user' => array(self::BELONGS_TO, 'User', 'userid')
);
}
Примечание: некоторые предпочитают использовать Id или _id вместо идентификатора. Это
вопрос личных предпочтений, но будьте последовательны.
Называйте отношения с учетом их единственного или множественного характера
Продолжая тему последовательностей и создания удобочитаемого код, надо сказать, что
отношения должны отражать единство или множественность в своих названиях.
- HAS_ONE — возвращает одиночную модель: singular
- BELONGS_TO — возвращает одиночную модель: singular
- HAS_MANY — возвращает массив моделей: plural
- MANY_MANY — возвращает массив моделей: plural
Отметим, что отношения, возвращающие массив, могут иметь только одну модель, но по
факту массив будет иметь множественный характер.
Нужно делать так, чтоб вы могли определить — возвращает отношение массив или модель,
лишь взглянув на код:
Посмотрите на свой код и сделайте его легкочитаемым и простым в поддержке.