항목 테이블이 있다고 가정 해 봅시다.
CREATE TABLE items
(
item serial PRIMARY KEY,
...
);
지금, 나는 (참고, 내가있어하십시오 각 항목에 대해 "권한"의 개념을 도입 할 수 없습니다 해당 항목에 대한 여기에 데이터베이스 액세스 권한에 대해 이야기하지만, 비즈니스 로직 권한을). 각 항목에는 기본 권한과 기본 권한을 무시할 수있는 사용자 별 권한이 있습니다.
나는 이것을 구현하는 몇 가지 방법을 생각해 보았고 다음 해결책을 생각해 냈지만 어느 것이 가장 좋은지 왜 그런지 확신하지 못한다.
1) 부울 솔루션
각 권한에 대해 부울 열을 사용하십시오.
CREATE TABLE items
(
item serial PRIMARY KEY,
can_change_description boolean NOT NULL,
can_change_price boolean NOT NULL,
can_delete_item_from_store boolean NOT NULL,
...
);
CREATE TABLE item_per_user_permissions
(
item int NOT NULL REFERENCES items(item),
user int NOT NULL REFERENCES users(user),
PRIMARY KEY(item, user),
can_change_description boolean NOT NULL,
can_change_price boolean NOT NULL,
can_delete_item_from_store boolean NOT NULL,
...
);
장점 : 각 권한의 이름이 지정됩니다.
단점 : 열 수를 크게 늘리는 수십 개의 권한이 있으며이를 두 번 정의해야합니다 (각 테이블에서 한 번).
2) 정수 솔루션
정수를 사용하여 비트 필드로 취급하십시오 (예 : 비트 0은 for can_change_description
, 비트 1은 for can_change_price
등). 비트 단위 연산을 사용하여 권한을 설정하거나 읽으십시오.
CREATE DOMAIN permissions AS integer;
장점 : 매우 빠릅니다.
단점 : 데이터베이스와 프론트 엔드 인터페이스에서 어떤 비트가 어떤 권한을 나타내는 지 추적해야합니다.
3) 비트 필드 솔루션
2)와 동일하지만을 사용하십시오 bit(n)
. 아마도 동일한 장점과 단점, 아마도 약간 느릴 수 있습니다.
4) 열거 형 솔루션
권한에 열거 형을 사용하십시오.
CREATE TYPE permission AS ENUM ('can_change_description', 'can_change_price', .....);
그런 다음 기본 권한에 대한 추가 테이블을 만듭니다.
CREATE TABLE item_default_permissions
(
item int NOT NULL REFERENCES items(item),
perm permission NOT NULL,
PRIMARY KEY(item, perm)
);
사용자 별 정의 테이블을 다음과 같이 변경하십시오.
CREATE TABLE item_per_user_permissions
(
item int NOT NULL REFERENCES items(item),
user int NOT NULL REFERENCES users(user),
perm permission NOT NULL,
PRIMARY KEY(item, user, perm)
);
장점 : 개별 권한의 이름을 쉽게 지정할 수 있습니다 (비트 위치를 처리 할 필요가 없음).
단점 : 기본 사용 권한을 검색하는 경우에도 두 가지 추가 테이블 (기본 사용 권한 테이블)과 두 번째 테이블 (enum 값을 저장하는 시스템 카탈로그)에 액세스해야합니다.
특히 해당 항목의 모든 단일 페이지보기에 대해 기본 권한을 검색해야하므로 마지막 대안의 성능 영향이 심각 할 수 있습니다.
5) 열거 형 배열 솔루션
4)와 동일하지만 배열을 사용하여 모든 (기본) 권한을 보유하십시오.
CREATE TYPE permission AS ENUM ('can_change_description', 'can_change_price', .....);
CREATE TABLE items
(
item serial PRIMARY KEY,
granted_permissions permission ARRAY,
...
);
장점 : 개별 권한의 이름을 쉽게 지정할 수 있습니다 (비트 위치를 처리 할 필요가 없음).
단점 : 첫 번째 정규 형식을 어 기고 약간 추악합니다. 권한 수가 많은 경우 (약 50 개) 행에서 상당한 바이트 수를 차지합니다.
다른 대안을 생각할 수 있습니까?
어떤 접근법을 취해야하며 그 이유는 무엇입니까?
bigint
필드 (각각 64 비트에 적합) 또는 비트 문자열을 선택할 수 있습니다 . 나는 도움이 될만한 몇 가지 관련 답변을 SO에