Проектирование базы данных — два внешних ключа, но один всегда равен нулю, а другой всегда не равен нулю

#mysql #sql #database #postgresql #database-design

#mysql #sql #База данных #postgresql #проектирование базы данных

Вопрос:

У меня есть три таблицы: property , person , и company . Одно свойство может принадлежать только человеку или компании. У человека или компании может быть более одного свойства. Мой текущий дизайн базы данных должен включать два внешних ключа — person_id и company_id в property таблицу, всегда с одним из них null, а другим not null. Мне просто интересно, есть ли лучший способ спроектировать базу данных в этом сценарии?

 CREATE TABLE person(
   person_id int NOT NULL PRIMARY KEY,
   name varchar(255)
);

CREATE TABLE company(
   company_id int NOT NULL PRIMARY KEY,
   name varchar(255)
);

CREATE TABLE property(
   property_id int NOT NULL PRIMARY KEY,
   name varchar(255),
   person_id REFERENCES person,
   company_id REFERENCES company
);
  

Комментарии:

1. У меня возникнет соблазн сказать, что все свойства принадлежат организациям. Некоторые из этих организаций могут быть частными лицами.

2. @Strawberry Это может быть не очень хороший дизайн. Если вы сделаете это, вы предположите, что компания и человек имеют одинаковые атрибуты, но в реальном сценарии это не так. Другой сценарий, в который может вписаться ваш дизайн: если две таблицы, например, student и teacher , вы можете просто создать таблицу person и добавить атрибут person_type, чтобы указать, является ли человек студентом или преподавателем.

3. Вы используете MySQL или Postgresql?

4. Нет. Это не совсем так. В этом сценарии пользователи являются членами организаций.

Ответ №1:

Создайте дополнительное ограничение проверки таблицы:

 CREATE TABLE property(
   property_id int NOT NULL PRIMARY KEY,
   name varchar(255),
   person_id REFERENCES person,
   company_id REFERENCES company,
   CHECK (person_id IS NULL   company_id IS NULL = 1)
);
  

Это запретит неправильные значения (оба NULL или оба NOT NULL).

PS. Наличие двух ссылок само по себе является законным и безопасным.

Комментарии:

1. последняя строка синтаксиса PostgreSQL: ПРОВЕРЬТЕ (person_id РАВНО НУЛЮ, А company_id НЕ РАВНО НУЛЮ ИЛИ person_id НЕ РАВНО НУЛЮ, А company_id РАВНО НУЛЮ = TRUE)