Основы ORM — связи между таблицами — Часть 1

Комментарии: 4  Просмотры: 33 456

Как я и обещал, в этом уроке мы рассмотрим построение связей между таблицами, используя ORM. Поскольку материала получилось как-то очень много, решил разбить урок на две части.
Итак, думаю все помнят, что связи бывают четырех типов: связь «один-к-одному», связь «один-ко-многим», связь «много к одному» и связь «многие-ко-многим». Напомню для тех, кто забыл.

Связь один-к-одному — когда одной записи в таблице соответствует только одна запись в другой таблице. Допустим, если у нас есть таблица с фамилиями студентов и таблица с номерами зачетных книжек, то связь между ними будет один-к-одному, так как у одного человека может быть только одна зачетка (в пределах ВУЗ-а конечно). Впрочем, у меня было две зачетки, когда я, уже занимаясь написанием диплома по одной специальности, пошел на другую, но мы этот момент здесь не учитываем.

Связь один-ко-многим — когда одной записи в таблице соответствует несколько записей в другой таблице. Приведу уже набивший оскомину пример, как книги и авторы. Мы не рассматриваем книги, написанные несколькими авторами, поэтому в данном случае одному автору может соответствовать несколько книг, но книге — только один автор.

Связь много-к-одному — все аналогично рассмотренной выше записи один-ко-многим. Много книг, но у них один автор.

Связь много-ко-многим — когда нескольким записям в таблице соответствует несколько записей в другой таблице. Наглядный и часто используемый на сайтах пример — фильмы и жанры. Одному жанру может соответствовать несколько фильмов (фантастика — Прометей, Живая сталь, Вспомнить все итд). Но фильмы также могут быть нескольких жанров: (8 первых свиданий — это и комедия, и мелодрама одновременно).

Один к одному
Если брать наш пример, то у нас будет две таблицы — со списком студентов и со списком зачеток. В уроке Введение в ORM мы уже рассматривали некоторые правила по именованию полей в таблице. Согласно этим правилам первичный ключ будет называться id, а внешний ключ — название связанной таблицы в единственном числе + _id. То есть примерно так:

ORM Связь один к одному

А модели будут такими:

class Model_Student extends ORM {
    protected $_has_one = array(
        'book' => array(
            'model' => 'book',
            'foreign_key' => 'student_id',
            ),
        );
}
class Model_Book extends ORM {
}

Как можно заметить, в классе Model_Student указывается название модели, отвечающей за связанную таблицу (в нашем случае это модель для таблицы зачеток book), а также название внешнего ключа student_id. Кстати, $_has_one переводится как «имеет один» или «есть один», так что если вы хоть немного знаете английский, запомнить этот и другие параметры (для других типов связей) будет несложно.

Получение

$student = ORM::factory('student', 2);
echo $student->name; // Гриша Петров
echo $student->book->number; // 14

Запросы, которые при этом будут выполнены, выглядят следуюшим образом:

SELECT `student`.* FROM `students` AS `student` WHERE `student`.`id` = 2 LIMIT 1
SELECT `book`.* FROM `books` AS `book` WHERE `book`.`student_id` = '2' LIMIT 1

Но для нас все это весьма прозрачно. Мы и знать не знаем ни про какие запросы. Мы просто создаем объекты и получаем нужные нам свойства. В этом вся прелесть ORM. Но если очень нужно, то запросы, которые генерирует ORM, вы всегда можете посмотреть с помощью такой вот строки:

echo View::factory('profiler/stats');

Хотя бы, чтобы проверить, сильно ли они тяжелые.
ORM Связь один к одному

Много к одному
Опять берем приведенный выше пример — много книг написаны одним автором. Как и в прошлом примере у нас будет две таблицы — список книг и список авторов:

ORM Связь много к одному

Модели:

Class Model_Book extends ORM {
protected $_belongs_to = array(
      'author'  => array(
               'model'       => 'author',
               'foreign_key' => 'author_id',
          )
    );
};
class Model_Author extends ORM {
}

Практически тоже самое, что и при связи «один-к-одному», только вместо $_has_one мы видим $_belongs_to, т.е. «принадлежит к».

Получение данных:

$book = ORM::factory('book', 3);
echo $book->name; // Разум на торги
echo $book->author->id; // 1
echo $book->author->name; // Андре Нортон

Запросы, которые будут выполнены:

SELECT `book`.* FROM `books` AS `book` WHERE `book`.`id` = 3 LIMIT 1
SELECT `author`.* FROM `authors` AS `author` WHERE `author`.`id` = '1' LIMIT 1

Продолжение следует.

<< Назад | Вперед >> | Обсудить на форуме


К записи оставлено 4 коммент.

добрый день! пожалуйста подскажите как связать в ORM несколько баз, для нескольких поисковиков. заранее спасибо.

Вам наверное это надо:

В случае, если для работы Модели нужно использовать не стандартную БД, а какую-то другую, достаточно указать ее название:

protected $_db_group = 'my_db';

Отсюда: http://kohanaframework.su/database/orm_entering

не, он наверно имел ввиду такое
db1.peoples(idpeople,people,….)

db2.flats(idflat,flat,address,.. , fk_db1_idpeople)
таблица связана с таблицей в другой базе данных.

если надо нечто, что не существует — обычно в СУБД есть инструменты для создания этого…в sql server знаю чтоно, для такого случая, можно создать типо мнимую бд, которая будет состоять из таблиц других баз — ток при этом все внешние ключи и прочая бабуйня не возможны. только тригерами или хранимыми процедурами самим реализовывать логику связи между таблицами

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

Спасибо за статьи! Все очень доступно описано. Освоил kohana за неделю благодаря вам )



Оставить комментарий или два

Пожалуйста, зарегистрируйтесь для комментирования.