Наследование одной таблицы

Ответ на мой вопрос о дизайне БД предложил нечто, называемое наследованием одной таблицы. Я немного искал по этому поводу, но, похоже, я не могу найти по нему достаточно четкой информации.

В основном то, что я, кажется, понимаю из этого, так это то, что у вас есть большая таблица со всеми полями в ней, а также поле типа - а затем ваш уровень ORM использует поле типа, чтобы предоставить вам различные представления объектов. Это правильно?

Что еще более важно, является ли наследование одной таблицы «одобренным» методом проектирования базы данных? Под этим я подразумеваю, «разумно» ли его использовать? Безопасно ли его использовать или это вызывает проблемы?

Другой вопрос, насколько хорошо это работает в рельсах? Я нашел несколько ссылок на него на рельсах - но вызывает ли он проблемы, если делать что-то нетрадиционным способом?

Любая помощь очень ценится.


person robintw    schedule 14.10.2008    source источник


Ответы (7)


Это хорошая идея ? По-разному. Это нарушает нормализацию, поскольку таблица не имеет единственной цели. Что произойдет, если вы расширите базовый класс в энный раз? Вам нужно будет добавить столбцы в таблицу. У большинства современных БД нет проблем с этим, поскольку вы можете изменить таблицу, но как насчет рефакторинга и удаления класса. Теперь у вас есть столбцы, у которых нет цели.

Эмпирическое правило - если большая часть дизайна разработана, вероятно, использовать его безопасно. Если дизайн часто меняется - у вас есть другие проблемы, и вам нужно ограничить свои варианты использования / требования пользователей. (да, не совсем дружелюбен к XP)

Я не знаю об эффектах Rails.

person jim    schedule 14.10.2008

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

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

person Mike Woodhouse    schedule 14.10.2008
comment
Я думаю, что другой дизайн мог бы быть (более гибким и масштабируемым) типом ‹методов (набор) комиссий в модели (или миксином модуля, если эти методы также используются в других местах) для расчета структуры комиссий, условно подлежащих на: type Это сделает его более масштабируемым. 1. Вы можете иметь любое количество различных типов 2. Вы можете расширить логику в любое время, не беспокоясь о структуре базы данных 3. Данные более нормализованы. Есть ли недостатки? (может, я вижу, что выгода у меня затуманена) - person Ram on Rails React Native; 12.05.2010
comment
@ramonrails - я не обязательно не согласен, хотя я бы сказал, что эти два подхода (если я понимаю ваш и помню свой!) фактически одинаковы, за исключением того, что мой - результат применения рефакторинг, который может или не может быть подходящим, в зависимости от контекста. Смотрим на плюсы: 1. То же самое и с классами, конечно, и мне не нужно трогать существующие модули? 2. Опять же, хотя схема должна измениться, если появится что-то совершенно новое; 3. Мне что-то не хватает по этому поводу :-) - person Mike Woodhouse; 13.05.2010

Короче говоря, наследование одной таблицы (STI) - это шаблон проектирования, который позволяет отображать отношения наследования ООП с базой данных. Если вы определяете какие-либо подклассы из объектов модели ActiveRecord, вам следует рассмотреть STI.

STI (изначально?) Задокументирована в книге Мартина Фаулера «Шаблоны архитектуры корпоративных приложений», а также описана в канонической книге DHH «Гибкая веб-разработка с Rails» (раздел 18.4, я думаю). Я отсылаю вас к этим книгам, потому что они дают гораздо лучшее объяснение, чем я мог бы надеяться сделать в этой области.

Я категорически не согласен с мнением, выраженным на сайте www.matthewpaulmoore.com (ссылка на который содержится в этой ветке robintw), что ИППП по своей сути - это плохо. Это кажется несколько наивным взглядом, который не учитывает использование наследования ООП. Я использовал STI для создания некоторых элегантных решений в Rails, но я полагаю, что вы можете злоупотреблять любым шаблоном проектирования.

person kt103099    schedule 14.10.2008

Окончательная ссылка. Это позволяет в одной таблице хранить несколько объектов, имеющих общий базовый класс.

Ruby on Rails использует библиотеку под названием Active Record. Это обычная среда Ruby, поддерживающая STI.

person Matt Brown    schedule 14.10.2008

Я могу говорить только с точки зрения (новой) ADO Entity Framework, которая включает функциональность таблицы для каждого типа (TPT).

Вот хорошая серия сообщения в блоге, знакомящие с основными концепциями (с использованием Entity Framework), также есть статья MSDN по этому поводу здесь.

Также, похоже, есть некоторые рекомендации по использованию nHibernate для TPT, они находятся здесь.

Вот эта ссылка, которая объясняет наследование типов таблиц в SQL Server.. Кажется, это довольно хорошее резюме и введение в концепцию.

Я не уверен, какое влияние это окажет на Rails.

person RobS    schedule 14.10.2008

Я только что видел http://www.matthewpaulmoore.com/articles/1276-ruby-on-rails-code-quality-checklist#sti, что говорит о плохой идее.

person robintw    schedule 14.10.2008
comment
Я прочитал ту статью некоторое время назад и списал ее - он просто утверждает, что никогда не видел хорошего использования ИППП, поэтому никто не должен ее использовать, даже не объясняя, о чем он на самом деле говорит. Почему это не годилось? Какие ситуации он вообще видел? и т. д. и т. д. - person Orion Edwards; 23.10.2008

В целом я считаю это полезным, но я обнаружил несколько ошибок

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

person Orion Edwards    schedule 21.10.2008