[SQL] 널 열 고유 제한 조건을 만들기
SQL널 열 고유 제한 조건을 만들기
나는이 레이아웃 테이블이 :
CREATE TABLE Favorites
(
FavoriteId uuid NOT NULL PRIMARY KEY,
UserId uuid NOT NULL,
RecipeId uuid NOT NULL,
MenuId uuid
)
나는이 유사한 고유 제한 조건을 만들려면 :
ALTER TABLE Favorites
ADD CONSTRAINT Favorites_UniqueFavorite UNIQUE(UserId, MenuId, RecipeId);
menuId와이 NULL 인 경우에는, 이것은 동일한 (사용자 아이디, RecipeId)과 복수의 열을 허용 할 것이다. 나는 어떤 메뉴를 관련 지을 수있는 즐겨 찾기를 저장하는 menuId와의 NULL을 허용 할,하지만 난 단지 사용자 / 조리법 쌍 당이 행의 대부분 하나를 원한다.
내가 지금까지 가지고있는 아이디어가 있습니다 :
나는 포스트 그레스 9.0을 사용하고 있습니다.
내가 바라 보는거야 어떤 방법이 있습니까?
해결법
-
==============================
1.이 부분 인덱스를 생성합니다 :
이 부분 인덱스를 생성합니다 :
CREATE UNIQUE INDEX favo_3col_uni_idx ON favorites (user_id, menu_id, recipe_id) WHERE menu_id IS NOT NULL; CREATE UNIQUE INDEX favo_2col_uni_idx ON favorites (user_id, recipe_id) WHERE menu_id IS NULL;
menu_id 효과적으로 원하는 제약을 구현 NULL이고 이렇게 만 (USER_ID,에는 Recipe_ID) 중 하나의 조합이있을 수있다.
가능한 단점 : 당신이 외래 키 참조를 (USER_ID, menu_id,에는 Recipe_ID) 가질 수 없습니다, 당신은 조건이 부분 인덱스를 사용할 수 없습니다 일치하지하지베이스 부분 인덱스에 CLUSTER, 및 쿼리 할 수 있습니다. (- 대신 PK 컬럼을 사용 당신이 세 개의 열 폭 FK 참조를 원하는 것 같지는 않다).
당신이 전체 색인이 필요한 경우 선택적으로 favo_3col_uni_idx에서 WHERE 조건을 삭제할 수 있습니다 귀하의 요구 사항은 여전히 적용됩니다. 지수는 현재 전체 테이블을 포함, 다른 하나 겹쳐 더 큰 가져옵니다. 일반적인 쿼리와 NULL 값의 비율에 따라,이 또는 유용하지 않을 수도 있습니다. 극단적 인 상황에서 심지어 세 인덱스 (두 부분들과 위에 총)을 유지하는 데 도움이 될 수 있습니다.
제외 : 나는 PostgreSQL을에 혼합 된 경우 식별자를 사용하지 않는 것이 좋습니다.
-
==============================
2.당신은 menuId와의 유착과 고유 인덱스를 만들 수 있습니다 :
당신은 menuId와의 유착과 고유 인덱스를 만들 수 있습니다 :
CREATE UNIQUE INDEX Favorites_UniqueFavorite ON Favorites (UserId, COALESCE(MenuId, '00000000-0000-0000-0000-000000000000'), RecipeId);
당신은 단지 "현실"에서 발생하지 않을 것 COALESCE에 대한 UUID를 선택해야 할 것입니다. 당신은 아마 현실에서 제로 UUID를 볼 수 없을 것입니다하지만 당신은 당신이 편집증 경우 CHECK 제약 조건을 추가 할 수 있습니다 (그들이 정말로 때문에 ... 당신을 얻기 위해) :
alter table Favorites add constraint check (MenuId <> '00000000-0000-0000-0000-000000000000')
-
==============================
3.별도의 테이블에 관련된 메뉴와 즐겨 찾기를 저장할 수 있습니다 :
별도의 테이블에 관련된 메뉴와 즐겨 찾기를 저장할 수 있습니다 :
CREATE TABLE FavoriteWithoutMenu ( FavoriteWithoutMenuId uuid NOT NULL, --Primary key UserId uuid NOT NULL, RecipeId uuid NOT NULL, UNIQUE KEY (UserId, RecipeId) )
-
==============================
4.나는 의미 론적 문제가 여기에 있다고 생각합니다. 내 관점에서, 사용자는 특정 메뉴를 준비하는 (그러나 단 하나의) 마음에 드는 조리법을 가질 수 있습니다. (영업 이익은 메뉴와 조리법 혼합을 가지고, 만약 내가 잘못 : 제발 아래 menuId와 및 RecipeId 교환) 즉 {사용자 메뉴}이 테이블의 고유 키해야한다는 것을 의미한다. 그리고 그것은 정확히 하나 개의 레시피를 가리켜 야합니다. 사용자는 더 행이 {사용자 메뉴} 키 쌍에 대해 존재하지 않는해야이 특정 메뉴에 대한 마음에 드는 조리법이없는 경우. 또한 : 대리 키 (FaVouRiteId)는 불필요 : 복합 기본 키 관계형 매핑 테이블에 완벽하게 유효합니다.
나는 의미 론적 문제가 여기에 있다고 생각합니다. 내 관점에서, 사용자는 특정 메뉴를 준비하는 (그러나 단 하나의) 마음에 드는 조리법을 가질 수 있습니다. (영업 이익은 메뉴와 조리법 혼합을 가지고, 만약 내가 잘못 : 제발 아래 menuId와 및 RecipeId 교환) 즉 {사용자 메뉴}이 테이블의 고유 키해야한다는 것을 의미한다. 그리고 그것은 정확히 하나 개의 레시피를 가리켜 야합니다. 사용자는 더 행이 {사용자 메뉴} 키 쌍에 대해 존재하지 않는해야이 특정 메뉴에 대한 마음에 드는 조리법이없는 경우. 또한 : 대리 키 (FaVouRiteId)는 불필요 : 복합 기본 키 관계형 매핑 테이블에 완벽하게 유효합니다.
즉, 감소 테이블 정의가된다 :
CREATE TABLE Favorites ( UserId uuid NOT NULL REFERENCES users(id) , MenuId uuid NOT NULL REFERENCES menus(id) , RecipeId uuid NOT NULL REFERENCES recipes(id) , PRIMARY KEY (UserId, MenuId) );
from https://stackoverflow.com/questions/8289100/create-unique-constraint-with-null-columns by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] MySQL의 쿼리에서, 왜 사용하는 대신 어디 조인? (0) | 2020.03.15 |
---|---|
[SQL] 대 = 같은 LIKE (0) | 2020.03.15 |
[SQL] MySQL의에서 일괄 삽입 작업을 수행하는 방법 (0) | 2020.03.15 |
[SQL] 무한 행 오프셋 MYSQL (0) | 2020.03.15 |
[SQL] 는 SQL Server 쿼리에 대한 최대 크기? IN 절? 더 나은 접근 방법이 있나요 [중복] (0) | 2020.03.15 |