Создание системы комментариев для разных типов сущностей

Я создаю систему комментариев в PostgreSQL, где я могу комментировать (а также «ставить лайки») по различным объектам, которые у меня уже есть (например, продукты, статьи, фотографии и т. Д.). На данный момент я придумал это:

(примечание: внешний ключ между comment_board и product / article / photo здесь очень свободный. ref_id просто хранит идентификатор, который используется вместе с comment_board_type, чтобы определить, какая это таблица )

Решение 1

Очевидно, это не похоже на хорошую целостность данных. Что я могу сделать, чтобы сделать его более целостным? Кроме того, я знаю, что для каждого продукта / статьи / фотографии потребуется доска комментариев. Может ли это означать, что я использую comment_board_id для каждого продукта / статьи / фото, например этого ?:

Решение 2

Я знаю это решение SO, но оно заставило меня задуматься над супертипами и их сложностями: Дизайн базы данных - статьи, сообщения в блогах, фотографии, рассказы

Любое руководство приветствуется!


person Handonam    schedule 27.02.2016    source источник
comment
Для этой цели может оказаться полезным наследование (postgresql.org/docs/current /static/ddl-inherit.html).   -  person Gordon Linoff    schedule 27.02.2016
comment
@GordonLinoff Вы думали, что продукты / статьи / фотографии унаследуют comment_board? Похоже, что одна из проблем с наследованием postgres заключается в том, что оно не может устанавливать index / FK-ограничения для детей. возможно, не имеет большого значения. Я подумываю о том, чтобы изменить comment_board на entity, а затем получить: Entity (entity_id PK, created_at, updated_at), product (id, created_at, updated_at, entity_id) и comment(id PK, entity_id REFERENCES entity(entity_id), ...). Единственное, что я не знаю, это наследовать другие таблицы постфактум.   -  person Handonam    schedule 28.02.2016


Ответы (1)


В итоге я просто указал комментарии прямо в поля продукта / фото / статьи. Вот что я в итоге придумал

CREATE TABLE comment (
  id SERIAL PRIMARY KEY,
  created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT (now()),
  updated_at TIMESTAMP WITH TIME ZONE,
  account_id INT NOT NULL REFERENCES account(id),
  text VARCHAR NOT NULL,

  -- commentable sections
  product_id INT REFERENCES product(id),
  photo_id INT REFERENCES photo(id),
  article_id INT REFERENCES article(id),

  -- constraint to make sure this comment appears in only one place
  CONSTRAINT comment_entity_check CHECK(
    (product_id IS NOT NULL)::INT
    +
    (photo_id IS NOT NULL)::INT
    +
    (article_id IS NOT NULL)::INT
    = 1
   )
);

CREATE TABLE comment_likes (
  id SERIAL PRIMARY KEY,
  created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT (now()),
  updated_at TIMESTAMP WITH TIME ZONE,
  account_id INT NOT NULL REFERENCES account(id),
  comment_id INT NOT NULL REFERENCES comment(id),

  -- comments can only be liked once by an account.
  UNIQUE(account_id, comment_id)
);

В результате чего:

введите описание изображения здесь

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

person Handonam    schedule 28.02.2016