306 Часть II. Типовые решения
этого у каждой таблицы может быть собственный первичный ключ. В этом случае для
привязки соответствующих строк в таблицу суперкласса добавляются внешние ключи
таблиц производных классов.
Еще одна важная проблема реализации наследования с таблицами для каждого класса
— эффективное извлечение данных из множества таблиц. Очевидно, выполнение
отдельного запроса к каждой таблице не будет эффективным, поскольку потребует мно-
жества обращений к базе данных. Эту проблему можно решить путем соединения нес-
кольких таблиц. Следует, однако, учесть, что в силу способа оптимизации, применяемого
в большинстве баз данных, соединение трех или более таблиц будет обрабатываться
крайне медленно.
И наконец, нельзя не обратить внимание на такой аспект: при выполнении запросов
не всегда известно, к каким именно таблицам следует применить соединение. Если вы
ищете сведения о футболисте, то, естественно, обратитесь к таблице футболистов; если
же потребуются сведения о группе игроков, к каким таблицам обратиться? Разумеется, не
все таблицы будут содержать необходимые данные. Для выполнения эффективных со-
единений с такими таблицами применяется внешнее соединение, однако оно нестан-
дартно и достаточно медленно. В качестве альтернативы можно предложить следующее
решение: вначале считать корневую таблицу, а затем использовать код типа класса, что-
бы определить, какие таблицы следует считывать далее. К сожалению, этот способ требу-
ет выполнения нескольких запросов.
Назначение
Типовые решения наследование с таблицами для каждого класса, наследование с одной
таблицей (Single Table Inheritance, 305) и наследование с таблицами для каждого конкрет-
ного класса (Concrete Table Inheritance, 313) применяются для отображения иерархии на-
следования на реляционную базу данных.
Наследование с таблицами для каждого класса имеет ряд преимуществ.
• Все поля таблицы соответствуют содержимому каждой ее строки (т.е. есть в каж
дом описываемом объекте), поэтому таблицы легки в понимании и не занимают
лишнего места.
• Взаимосвязь между моделью домена и схемой базы данных проста и понятна.
Однако это типовое решение имеет и слабые стороны.
• Загрузка объекта охватывает сразу несколько таблиц, что требует их соединения
либо множества обращений к базе данных с последующим "сшиванием" результа
тов в памяти.
• Перемещение полей в производный класс или суперкласс требует изменения
структуры базы данных.
• Таблицы суперклассов могут стать "узким местом" в вопросах производительно
сти, поскольку доступ к таким таблицам будет осуществляться слишком часто.
• Высокая степень нормализации может стать препятствием для выполнения запро
сов, не хранящихся в базе данных (ad hoc queries).