Таблицы супертипирования - возможно ли множественное наследование? - PullRequest
1 голос
/ 05 ноября 2010

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

Допустим, я хочу создать "группу" или "класс" сущностей в моей модели данных.Как правило, я бы использовал таблицу супертипа, например, такую:

DrivableEntity
----------
ID (PK, auto-increment)
Type (int or otherwise some kind of enum)

Car
----------
ID (PK, FK to DrivableEntity)
(car-specific fields)

Bike
----------
ID (PK, FK to DrivableEntity)
(bike-specific fields)

Тогда мои вставки, вероятно, прошли бы то, что внешне выглядит как обычная процедура CRUD для каждой вложенной таблицы, но внутри вставили в DrivableEntity, а затемиспользует идентификатор области видимости для вставки в намеченную таблицу.

Будучи скорее программистом, чем разработчиком моделей данных, это заставило меня задуматься о наследовании объектов.Для прямого наследования это здорово.Общие данные / задачи могут быть абстрагированы на более высоком уровне, можно сохранить подстановку Лискова и т. Д. Но возможно ли множественное наследование в модели данных?

Я в первую очередь разработчик на C #, поэтому я начал думать в терминахинтерфейсов.Что если бы я хотел выставить таблицы, которые «реализовали» IDrivable и / или ITowable и т. Д. Возможно ли что-то подобное?Кто-нибудь делал что-нибудь подобное раньше?

Ответы [ 4 ]

1 голос
/ 05 ноября 2010

Как правило, два подхода к модели данных работают хорошо для того, что вы описали.

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

DrivableEntity
----------
ID (PK, auto-increment)
Type (int or otherwise some kind of enum)

Car
----------
ID (PK, FK to DrivableEntity)
(car-specific fields)

Bike
----------
ID (PK, FK to DrivableEntity)
(bike-specific fields)

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

Вы можете моделировать наследование или интерфейсы в исходной модели, просто добавив еще один столбец внешнего ключа к одной из «производных» сущностей.Например:

FlyableEntity
-------------
ID (PK)
... flyable attributes

FlyingCar (implements/inherits IDrivable and IFlyable)
-------------
DrivableEntityID (PK, FK)
FlyableEntityID (PK, FK)
... add flying car attributes

or:

FlyingCar (inherits from Car)
-------------
CarID (PK, FK)
FlyableEntityID (FK)
... add flying car attributes
1 голос
/ 05 ноября 2010

Дэвид,

Entity Framework имеет возможность использовать наследование. Это хороший обзор наследования в Entity Framework .Вы можете использовать POCO с EF для создания собственных интерфейсов для обеспечения доступа к данным.

Ситуация, которую вы описываете, на самом деле не множественное наследование, поскольку у вас есть одна базовая таблица / сущность и производные таблицы / сущности.Чтобы смоделировать это в EF, вы создаете базовую сущность, а затем создаете каждую дочернюю сущность.На этом этапе вы можете сопоставить свойства дочерних сущностей каждого типа с правильной таблицей.

С учетом сказанного ваша логика вставки / обновления / удаления станет очень сложной.В Entity Framework могут возникнуть проблемы со сложной моделью.

Вопрос, который у меня возник бы, заключается в следующем: зачем вы это делаете?Если это необходимо для обмена общими данными между типами, я бы порекомендовал создать представления на сервере, которые соединяют родительскую таблицу с дочерними таблицами.Это будет намного быстрее, и вы сможете обрабатывать операции CUD (создание / обновление / удаление) с помощью вместо триггера , что облегчит SQL, поскольку существует четкое разделение между доступом к данным и их хранением.

Имеет ли это смысл?

Эрик

0 голосов
/ 06 ноября 2010

Подтипирование возможно, но и не рекомендуется.Базы данных - это их собственный мир, и вам не следует пытаться привнести принципы ООП в этот мир.Многие пытались, многие потерпели неудачу.Если вы попытаетесь представить «объекты» базы данных в терминах ООП, ваша база данных пострадает.

0 голосов
/ 06 ноября 2010

Вы можете создать представления для решения этой проблемы.

viewDriveableCar
ViewDrivabaleBike
ViewTowableCar

Затем объедините виды в супер-вид, комбинируя движущиеся и буксируемые объекты, используя объединение. Вы можете включить только те столбцы, которые были общими для обоих. Аналогичные, но разные имена должны быть нормализованы:

CREATE VIEW vrDiveTow
AS

SELECT
viewDriveableCar.CarId as ID,
... other attributes

UNION

SELECT
viewTowableCar.TowableId as ID,
... other attributes
UNION

Большая гоча . SQL использует планы запросов, которые можно кэшировать для получения результатов. Если план запроса SQL построен на запросе «Seven-Up», а вы фильтруете «Coke», тогда план запроса неэффективен, и фактически используется полное сканирование таблицы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...