Вам трудно найти его, потому что это не настоящий (в смысле широко принятого и поощряемого) шаблон проектирования базы данных.
Держитесь подальше от таких шаблонов.В то время как ORM упрощает сопоставление таблиц базы данных с типами, таблицы не являются типами, и наоборот .Хотя неясно, что должна делать описанная вами модель, у вас не должно быть столбцов, которые служат поддельными внешними ключами для нескольких таблиц (когда я говорю «поддельные», я имею в виду, что вы храните значение простого идентификатора, котороесоответствует первичному ключу другой таблицы, но вы не можете определить столбец как внешний ключ).
Моделируйте вашу базу данных для представления данных, моделируйте ваши объекты для представления процесса и используйте ORM и промежуточные слои для выполнения перевода;не пытайтесь вставить базу данных в свой код и не вставляйте свой код в базу данных.
Редактируйте в ответ на комментарий
Вы смешиваете терминологию базы данных и OO;хотя я не знаком с синтаксисом, который вы используете для определения этой функции, я предполагаю, что это функция экземпляра типа User
с именем getLocation
, которая не принимает параметров и возвращает объект Location
.Базы данных не поддерживают понятия функций экземпляра (или любых основанных на типах);Реляционные базы данных могут иметь пользовательские функции, но это простые процедурные функции, которые принимают параметры и возвращают либо значения, либо наборы результатов.Они никоим образом не соответствуют конкретным таблицам или полям, за исключением того факта, что вы можете использовать их в теле функции.
При этом здесь есть два вопроса, на которые нужно ответить: как это сделатьчто вы спросили, и что может быть лучшим решением.
Для того, что вы спросили, похоже, что у вас есть отношение супертип-подтип, которое является стандартным дизайном базы данных.шаблон.В этом случае у вас есть одна таблица супертипа, которая представляет родительский элемент:
Location
---------------
LocationID (PK)
...other common attributes
(обратите внимание, здесь я использую LocationID
для простоты; у вас должны быть более конкретные и логические атрибуты дляопределить первичный ключ, если это возможно)
Тогда у вас есть одна или несколько таблиц, которые определяют подтипы:
Address
-----------
LocationID (PK, FK to Location)
...address-specific attributes
Country
-----------
LocationID (PK, FK to Location)
...country-specific attributes
Если конкретный экземпляр Location
может быть только одним из подтипов,затем вы должны добавить значение дискриминатора в родительскую таблицу (Location
), которое указывает, какому из подтипов оно соответствует.Вы можете использовать ограничения CHECK
, чтобы в этом поле находились только допустимые значения для данной строки.
В конце, похоже, вам лучше использовать гибридный подход.Вы в основном представляете два разных типа местоположений, из того, что я вижу:
- Координаты на основе координат (L & L)
- Муниципальные / Почтовые / Etc. Местоположения (Страна, City, Address), и каждый из них является просто более конкретной версией предыдущего
. Учитывая это, простая модель будет выглядеть следующим образом:
Location
------------
LocationID (PK)
LocationType (non-nullable) ('C' for coordinate, 'P' for postal)
LocationCoordinate
------------------
LocationID (PK; FK to Location)
Latitude (non-nullable)
Longitude (non-nullable)
LocationPostal
------------------
LocationID (PK, FK to Location)
Country (non-nullable)
City (nullable)
Address (nullable)
ТеперьЕдинственная проблема, которая остается, состоит в том, что у нас есть обнуляемые столбцы.Если вы хотите, чтобы ваши запросы были простыми, но не обращали внимания (оправданно!) На то, что люди оставляют пустые столбцы, вы можете оставить все как есть.Если вы хотите перейти к тому, что большинство людей сочли бы базой данных с лучшим дизайном, вы можете перейти к 6NF для наших двух обнуляемых столбцов.Выполнение этого также будет иметь приятный побочный эффект, так как даст нам немного больше контроля над тем, как эти поля заполняются, без необходимости делать что-либо дополнительное.
Наши два поля, которые можно обнулять, это City
и Address
.Я собираюсь предположить, что наличие Address
без City
было бы бессмыслицей.В этом случае мы удаляем эти два атрибута из таблицы LocationPostal
и создаем еще две таблицы:
LocationPostalCity
------------------
LocationID (PK; FK to LocationPostal)
City (non-nullable)
LocationPostalCityAddress
-------------------------
LocationID (PK; FK to LocationPostalCity)
Address (non-nullable)