#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)