пользователей: 30398
предметов: 12406
вопросов: 234839
Конспект-online
РЕГИСТРАЦИЯ ЭКСКУРСИЯ

Полиморфические отношения

  1. Полиморфические отношения

Суть полиморфных связей


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

Наша еще одна таблица — news:
 

  •  

| id | text                           | date       |

  •  

|  1 | Какая-то новость               | 2015-07-05 |

  •  



И меняем таблицу comments, чтобы стало, ровно!

comments:
 

  •  

| id | text                                               | entity_id | entity_type | created_at |

  •  

|  1 | Неплохой коммент                                   |     1     | article     | 2015-07-05 |

|  2 | Неплохой коммент                                   |     1     | article     | 2015-07-05 |

|  3 | Неплохой коммент                                   |     2     | article     | 2015-07-05 |

|  4 | Коммент                                            |     1     | news        | 2015-07-05 |

  •  



Суть полиморфных связей становится ясна, при просмотре таблицы comments — entity_id — id какой-то сущности, к которой мы оставляем комментарий, entity_type — тип этой самой сущности. Ни entity_id, ни entity_type — заранее неизвестны, поэтому эти связи можно назвать динамическими.

Использовать полиморфные связи стоит тогда, когда у нас появляется две и более таблицы, у которых будет связь один-ко-многим с какой-то другой одной и той же таблицей (articles-comments, news-comments, posts-comments и т.д.). Если же, у вас есть связи только между 2 таблицами и больше не предусматривается, полиморфные лучше заменить на обычные один-ко-многим.

Полиморфные связи могут быть реализованы, и как многие-ко-многим.
Показывать таблицы с данными не имеет смысла, покажу лишь примерную структуру.
articles:
id — integer
text — text

posts:
id — integer
text — text

tags:
id — integer
name — string

tags_entities
tag_id — integer
tag_entity_id — integer
tag_entity_type — string (post|article)

 

Минусы полиморфных связей


Не всё так идеально, как могло бы показаться на первый взгляд. В силу своей динамической природы полиморфных связей, между полями связуемых таблиц, нельзя проставить связи внешних ключей (foreign key) используя СУБД, а тем более и ограничения (constraints) на изменение или удаление записей. Это, собственно самый большой минус полиморфных связей. Придется, либо писать свои триггеры (процедуры или еще что) для самой СУБД, либо, что чаще делают, переложить работу по синхронизации строк и накладыванию ограничений между таблицами на ORM и язык программирования.

Второй, уже менее значительный минус полиморфных связей состоит в типе сущности. Необходимо как-то описать какой тип, какой таблице принадлежит. Это может быть не очевидно, если например название какой-то таблицы изменилось или если вы задали тип сущности цифрами. Решить эту проблему можно, например создав отдельную таблицу, или прописав в коде проекта, ассоциативный массив с сопоставлением типа и сущности.

 

Работа ORM с полиморфными связями


Следует сказать, что современные фреймворки и их ORM без особых сложностей, способны работать с данными связями.
Например, как уже говорилось выше, Ruby on Rails поддерживает их из коробки. Php-фреймворк Laravel, также имеет в своей реализации ORM для таких типов связей удобные методы (morphTo, morphMany и т.д.), а как тип сущности использует полное название класса модели. Во фреймворке Yii2, нет из коробки каких-то специфичных методов для такого рода связей, но они могут быть реализованы через обычные методы hasOne, hasMany с дополнительными условиями при прописывании связей.

Из всего вышесказанного, новичкам стоит обратить внимание на то, когда использовать полиморфные связи. Не стоит их пихать направо и налево, из проекта в проект, только потому что это круто. Нужно немного прикинуть наперед, а появятся ли завтра новые таблицы, новые сущности с одинаковым функционалом и требованиями, которые можно было бы вынести и сделать динамическими, и исходя от ответа проектировать свои БД.

 


22.06.2017; 21:34
хиты: 97
рейтинг:0
для добавления комментариев необходимо авторизироваться.
  Copyright © 2013-2024. All Rights Reserved. помощь