PostgreSQL: constraint which affects multiple tables

荒凉一梦 提交于 2019-12-11 05:19:50

问题


I have a hierarchical structure of entities, each of which might have more than one name, so that I have a separate table for names. A simplified SQL Schema looks as follows:

CREATE TABLE users (
  id SERIAL NOT NULL PRIMARY KEY,
  -- some fields
);

CREATE TABLE entities (
  id SERIAL NOT NULL PRIMARY KEY,
  parent_id INTEGER NOT NULL,
  owner_id INTEGER NOT NULL,
  FOREIGN KEY (parent_id) REFERENCES entities(id),
  FOREIGN KEY (owner_id) REFERENCES users(id)
);

CREATE TABLE entity_names (
  id SERIAL NOT NULL PRIMARY KEY,
  entity_id INTEGER NOT NULL,
  name VARCHAR(30) NOT NULL,
  FOREIGN KEY (entity_id) REFERENCES entities(id)
);

And I need to ensure that there's no entities with duplicate name (of course, with the same parent_id and owner_id).

I can ensure that right before adding a name to entity_names with the query like this:

SELECT COUNT(t.id)
  FROM entity_names n
  JOIN entities e ON n.entity_id = e.id
  WHERE e.parent_id = 123 and e.owner_id = 456 and n.name = 'foo'

But I'm wondering if it's possible (and sane) to implement this constraint in the database?


回答1:


There is no multitable constraints in Postgres but you can emulate check constraint by placing your query in a trigger on tag_names.




回答2:


Each entity_id in entity_names table identifies a row within entities table. Trying to add a duplicate name for a particular entity would look like:

INSERT INTO entity_names (entity_id, name) VALUES (2, 'Name1');

Each entity has it's own parent and owner, but is still uniquely identified with an id. Thus, I think you are overthinking your issue and do not need cross-table constraint, but a simple UNIQUE one:

CREATE UNIQUE INDEX ON entity_names (entity_id, name);

This is assuming that there are no two records with the same parent_id and owner_id as your entities - I doubt it would make any sense since to me they seem like a candidate key.


If that is actually not the case (hardly believable for me) then create a function which returns trigger and perform a check there, then create BEFORE INSERT trigger on entity_names table.



来源:https://stackoverflow.com/questions/39884356/postgresql-constraint-which-affects-multiple-tables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!