나는 여기에 주기적 인 것이 보이지 않습니다. 이 엔티티들 사이 에는 사람 과 게시물 그리고 두 개의 독립적 인 관계가 있습니다. 이러한 관계 중 하나의 구현으로 좋아요 를 볼 수 있습니다.
- 사람은 많은 게시물을 쓸 수 있으며 게시물은 한 사람이 작성합니다.
1:n
- 사람은 많은 게시물을 좋아할 수 있고 많은 사람들이 게시물을 좋아할 수 있습니다
n:m
. n : m 관계는 다른 관계로 구현 될 수 있습니다 likes
.
기본 구현
기본 구현은 PostgreSQL 에서 다음과 같이 보일 수 있습니다 .
CREATE TABLE person (
person_id serial PRIMARY KEY
, person text NOT NULL
);
CREATE TABLE post (
post_id serial PRIMARY KEY
, author_id int NOT NULL -- cannot be anonymous
REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE -- 1:n relationship
, post text NOT NULL
);
CREATE TABLE likes ( -- n:m relationship
person_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE
, post_id int REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE
, PRIMARY KEY (post_id, person_id)
);
특히 게시물 에는 작성자 ( ) 가 있어야NOT NULL
하지만 좋아요의 존재는 선택 사항입니다. 기존의 추천을하지만, post
하고 person
있어야 모두 적용 (참조 할 것을 PRIMARY KEY
모두 열을 만드는 NOT NULL
자동 (당신이 그렇게 익명 좋아도 불가능) 중복, 명시 적으로 이러한 제약을 추가 할 수 있습니다.
n : m 구현에 대한 세부 사항 :
자기 같은 것을 방지
당신은 또한 썼습니다 :
(만든 사람은 자신의 게시물을 좋아할 수 없습니다).
위의 구현에서는 아직 시행되지 않았습니다. 트리거를 사용할 수 있습니다 .
또는 더 빠르고 안정적인 솔루션 중 하나 :
비용이 많이 드는 견고한
그것이 될 필요가있는 경우 견고한 , 당신은에서 FK를 확장 할 수 likes
에 post
인클루드하는 author_id
중복을. 그런 다음 간단한 CHECK
제약 조건으로 근친상간을 배제 할 수 있습니다 .
CREATE TABLE likes (
person_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE
, post_id int
, author_id int NOT NULL
, CONSTRAINT likes_pkey PRIMARY KEY (post_id, person_id)
, CONSTRAINT likes_post_fkey FOREIGN KEY (author_id, post_id)
REFERENCES post(author_id, post_id) ON UPDATE CASCADE ON DELETE CASCADE
, CONSTRAINT no_self_like CHECK (person_id <> author_id)
);
다음과 같은 경우에도 중복 제약 이 필요 합니다 .UNIQUE
post
ALTER TABLE post ADD CONSTRAINT post_for_fk_uni UNIQUE (author_id, post_id);
나는 유용한 인덱스author_id
를 제공하기 위해 먼저 제공 했다.
더 관련 답변 :
CHECK
구속 조건 이있는 더 싼
위의 "기본 구현"을 기반으로합니다.
CHECK
제약 조건은 변경 불가능합니다. 검사를 위해 다른 테이블을 참조하는 것은 결코 변하지 않습니다. 우리는 여기서 개념을 조금 남용합니다. NOT VALID
이를 제대로 반영하기 위해 제약 조건을 선언하는 것이 좋습니다 . 세부:
CHECK
게시물 작성자가 절대 변하지 않는 속성처럼 보이기 때문에이 특별한 경우 에는 제약이 합리적으로 보입니다. 해당 필드의 업데이트를 확실하게하지 마십시오.
우리 는 함수를 위조 합니다 IMMUTABLE
:
CREATE OR REPLACE FUNCTION f_author_id_of_post(_post_id int)
RETURNS int AS
'SELECT p.author_id FROM public.post p WHERE p.post_id = $1'
LANGUAGE sql IMMUTABLE;
'public'을 실제 테이블 스키마로 바꾸십시오. 제약 조건
에서이 함수를 사용하십시오 CHECK
.
ALTER TABLE likes ADD CONSTRAINT no_self_like_chk
CHECK (f_author_id_of_post(post_id) <> person_id) NOT VALID;