Postgres: ограничение Not-null с двумя внешними ключами - PullRequest
0 голосов
/ 04 июня 2018

Я новичок в проектировании баз данных и хотел попробовать создать простое веб-приложение для чата, чтобы попрактиковаться в этом навыке.

Я пытаюсь создать приложение чата, похожее на Messenger.com, где пользователи могут отправлять сообщенияконтакты и группы.

Я нашел этот хороший учебник, но у меня возникла проблема с таблицей "сообщений": http://www.vertabelo.com/blog/technical-articles/database-model-for-a-messaging-system

Идея заключалась в том, что когда сообщение отправляетсяДля пользователя «reciever_group_id» равен NULL, а когда сообщение отправляется группе, «reciever_user_id» равен NULL.Однако postgres не позволит добавить сообщение в таблицу «Сообщения», поскольку внешние ключи не могут иметь значение NULL, то есть нарушают ограничение NOT-NULL для reciever_user_id ИЛИ reciever_group_id.

Любые советы?

CREATE TABLE users (
  id serial primary key,
  username character varying(32) NOT NULL UNIQUE,
  password character varying(255) NOT NULL,
  name character varying(64) NOT NULL,
  image character varying(255),
  active int NOT NULL DEFAULT 0
);

CREATE TABLE groups (
  id serial primary key,
  name character varying(255) NOT NULL
);

CREATE TABLE group_users (
  id serial primary key,
  user_id serial references users(id),
  group_id serial references groups(id)
);

CREATE TABLE messages (
  id serial primary key,
  user_id serial references users(id),
  reciever_user_id serial references users(id),
  reciever_group_id serial references groups(id),
  body text
);

1 Ответ

0 голосов
/ 04 июня 2018

Требуется проверочное ограничение, которое гарантирует, что ровно один из этих двух столбцов содержит ненулевое значение.

CREATE TABLE messages (
  id serial primary key,
  user_id integer,
  receiver_user_id integer,
  receiver_group_id integer,
  body text,
  constraint check_group_user check (
      (receiver_user_id is null and receiver_group_id is not null) 
   or (receiver_user_id is not null and receiver_group_id is null) )
);

Кроме того: do not определите столбцы FK как serial, которые будут автоматически генерировать разные идентификаторы, поскольку каждый столбец использует другую последовательность.

Столбцы внешнего ключа должны определяться с базовым типом данных указанного столбца.Так что integer вместо serial. serial не является реальным типом данных

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