Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 24.05.2014 22:03:17

Вопрос по моделям

Здравствуйте. мой вопрос относится скорее всего к ООП.

В своем приложение (на laravel) я создаю модель Place это будет объект заведение. Заведение имеет список услуг, город, станция метро, тип заведения. То есть порядка 20 таких списков из которых нужно будет выбрать один или несколько пунктов. Как это должно быть реализовано? Нужно для каждого списка создавать модели (City, MetroStaition, Type, Usluga итд) со связями или реализовать как-то в рамках модели Place?

На данном моменте встаю в тупик т.к с фреймворком и MVC работаю первый раз. Может что-то почитать на эту тему?

Не в сети

#2 06.09.2014 14:03:04

Re: Вопрос по моделям

здравствуйте. Присоединяюсь к вопросу. Очень интересно услышать ответ, ведь подобные задачи встречаются постоянно.
Судя по документации, необходимо создавать модели для каждого списка. Думаю, это верное решение,  с точки зрения расширяемости, т.к. в дальнейшем, может возникнуть, например, задача вывести все услуги в городе N, и тогда мы по связям модели сможем без труда это сделать.

Не в сети

#3 06.09.2014 16:01:48

Re: Вопрос по моделям

Вариантов может быть несколько, всё зависит от конкретной ситуации — где-то может иметь смысл делать модели на каждый список, а где-то это может быть слишком громоздким и неоправданным даже в будущем.

Допустим, у нас есть объект «заведение». Этот объект имеет поле «город». Некоторые заведения находятся в одном городе, для них значение поля совпадает.

В этом случае на ум приходят такие варианты:

  • Не мудрствовать и просто использовать значение «город» как есть, то есть текстом. К примеру, $model->city == 'Москва'.
    • [+] самый прямолинейный и очевидный путь
    • [+] не создается лишних сущностей, таблиц, кода и т.п.
    • [+] все данные в одной таблице, JOIN при выборке не нужны (впрочем, это может быть и минусом — если записей много, много повторяющихся значений этого поля, то они будут дублироваться как есть, а не ссылками на ID, съедая место на диске)
    • [—] нельзя ограничить значения на уровне СУБД (т.е. можно присвоить любую абракадабру) — но можно добавить проверки в модель (т.е. на backend)
    • [—] чтобы получить список текущих заведенных городов делается выборка из таблицы, что может быть медленно (но не обязательно — зависит от индексов и числа строк)
    • [—] если нужно будет локализовать или еще как-то видоизменять значение при выводе придется все строки «переводить» с языка оригинала в какой-то другой формат, что не очень красиво и гибко
  • Создавать таблицы-списки на каждое такое поле и ссылаться на него (конкретное значение поля) по ID в этом списке. Соответственно, минусы предыдущего подхода становятся плюсами этого и наоборот.
    • [—] больше кода, так как как минимум нужно создать еще одну модель для таблицы-списка
    • [—] возможно, понадобиться еще одна таблица, если отношения m2m (когда поле может иметь несколько значений, к примеру, теги) — в первом варианте все значения можно вписать в поле, разделив | или другим символом — если не нужно (часто) делать выборки по этому полю, а только хранить — это может работать
    • [+] более быстрая выборка, отлично подходит для фильтров (СУБД отлично заточены под JOIN и их можно оптимизировать)
    • [+] меньше данных на диске, ограничения значений поля на уровне СУБД (вешаешь foreign key на city и оно не сможет принять значение, которое не существует в таблице-списке)
    • [+] для очень больших таблиц с фиксированными типами данных типа число, CHAR и т.п. — удаление полей, длина которых меняется от строки к строке, переведет таблицу в compact/fixed row format, когда строка занимает постоянный размер вне зависимости от того, какие в ней записаны данные (то есть если в нашей таблице 2 поля и это 4-байтовые числа, то любая строка занимает ровно 8 байт). В этом режиме можно получить хороший бонус к скорости, но как уже сказал — имеет смысл только для очень больших таблиц и то не факт.

В случае, описанном в первом посте, логичным кажется второй вариант, так как нужна фильтрация. Часто, впрочем, достаточно просто комбинировать оба подхода — одно поле списком, другое как есть — зависит от того, что нужно фильтровать, сколько данных, какие ресурсы сервера и прочих вещей. Думаю, понятно.

Не в сети

Подвал раздела