Я создаю веб-приложение с Laravel, где пользователи могут искать местоположения на основе фильтров близости и атрибутов, и теперь мне стало интересно, что такое хорошая схема для хранения атрибутов.Как сохранить динамические/множественные атрибуты объекта
Например, пользователи могут создать листинг для ресторана, а затем должны быть в состоянии добавить информацию о том, какие варианты оплаты принимаются в ресторане (наличные деньги, карта, может быть, даже paypal), какой ресторан (быстрый еда, ужин, столовая) или какой тип (а) кухни у них есть (мексиканский, итальянский, французский).
Я хотел бы построить решение, в котором:
- Атрибуты не являются обязательными, администратор не должен заполнить все атрибуты
- Locations фургон имеет атрибут имеет несколько значений, например, в в ресторане вы можете заплатить наличными и карту
- Решение подходит к «способу мышления» Ларавеля. Я хотел бы, чтобы это играть вместе с красноречивым красиво
Я придумал несколько решений о том, как решить эту проблему, но я не уверен, что является лучшим и, если возможно, даже лучше решение?
Вариант 1
сериализовать все на самой таблице местоположения, например, в колонке «атрибуты». Это кажется «ленивым способом», потому что поддерживать/обновлять местоположения будет очень сложно, и поиск/фильтрация еще больше.
Вариант 2
Есть различные таблицы для каждого атрибута со всеми значениями и многие ко многим отношениях с места. Например, таблица payment_methods:
-----------------------------
| id | name | description |
-----------------------------
| 1 | cash | ...... |
-----------------------------
| 2 | card | ...... |
-----------------------------
| 3 | paypal | ...... |
-----------------------------
И сводная таблица, которая связывает варианты оплаты в места
----------------------------------
| id | payment_id | location_d |
----------------------------------
| 1 | 1 | 1 |
----------------------------------
| 2 | 2 | 1 |
----------------------------------
| 3 | 1 | 2 |
----------------------------------
Теперь все значения хранятся в таблице поэтому администраторы могут легко добавить возможные варианты и это легко поддерживать в ларавеле с помощью Eloquent
\App\Location::with('paymentMethods')->...
Но проблема в том, что для каждого типа атрибута I необходимо добавить миграцию, а база данных будет загромождать столами, такими как payment_methods, kitchen_types & restaurant_types. Я думаю, что это не было бы так же хорошо обслуживаемым, так как вам нужно написать новый интерфейс администратора и миграцию для каждого нового атрибута.
Вариант 3
Есть одна таблица (product_attributes) со всеми атрибутами, значения и описания.Можно группировать атрибуты со значением атрибута как свойство в местоположении, а его значения - как массив.
------------------------------------------------
| id | attribute | value | description |
------------------------------------------------
| 1 | payment_method | cash | ...... |
------------------------------------------------
| 2 | payment_method | card | ...... |
------------------------------------------------
| 3 | payment_method | PayPal | ...... |
------------------------------------------------
| 4 | kitchen_type | French | ...... |
------------------------------------------------
| 5 | kitchen_type | Italian | ...... |
------------------------------------------------
| 6 | kitchen_type | Mexican | ...... |
------------------------------------------------
И сводная таблица, которая связывает варианты оплаты местоположений
--------------------------------------------
| id | product_attribute_id | location_d |
--------------------------------------------
| 1 | 1 | 1 |
--------------------------------------------
| 2 | 2 | 1 |
--------------------------------------------
| 3 | 3 | 2 |
--------------------------------------------
Всех значения хранятся в одной таблице и админам могут также добавить опции и новые атрибуты прямо сейчас. Нет необходимости добавлять новые таблицы, поэтому мне кажется более чистым. Проблема, похоже, больше связана с тем, что одна таблица загромождает все виды информации/атрибутов.
Также мне было интересно, о том, как извлекать данные из базы данных с помощью красноречивых в следующем формате:
$location->attributes->attribute_name = ['value1', 'value2']
Например
$location = \App\Location::with('productAttributes')->find($id);
$location->attributes->payment_methods = ['Cash']
$location->attributes->kitchen_types = ['French', 'Italian']
Может кто-нибудь, пожалуйста, сообщите мне о том, что является хорошим решение в моей ситуации? Для меня последний вариант (3) представляется наиболее подходящим, так как вы можете хранить всевозможные атрибуты без необходимости добавления нескольких таблиц в новые атрибуты. Но, может быть, есть и другие варианты, которые еще лучше?
Заранее благодарен!
Спасибо за советы, очень благодарен! Возможно ли иметь все разные атрибуты под одним ключом на объекте? например: $ location-> attributes-> payment_methods. А также, не будет ли сложнее работать с БД, когда вы laravel должны присоединиться к 15 таблицам в таблице мест вместо 1? –
Я не вижу необходимости добавлять промежуточный уровень «attrivutes» для ваших местоположений. Все, что было в модели местоположения, было бы и может быть самим атрибутом. Я думаю, что это добавило бы сложности вашим моделям и приложениям без реальной выгоды. Что касается отношений таблиц, то это зависит от отношения между ними, если это одно для многих. Это усложняется, когда у них есть вложенные отношения в моделях –
Но тогда для каждого нового атрибута вам нужны две таблицы, одна для хранения значений и сводная таблица для управления отношениями. Итак, если бы было 10 атрибутов, вам нужно создать 20 таблиц ... Для меня это выглядит немного излишним –