연관 테이블을 사용하는 것보다 플래그를 비트 마스크로 저장하는 것이 더 나은 경우는 언제입니까?
사용자가 다른 기능(예: 읽기, 만들기, 다운로드, 인쇄, 승인 등)을 사용할 수 있는 권한이 다른 응용 프로그램에서 작업하고 있습니다.권한 목록은 자주 변경되지 않을 것으로 예상됩니다.이러한 권한을 데이터베이스에 저장하는 방법에 대한 몇 가지 옵션이 있습니다.
어떤 경우에 옵션 2가 더 나을까요?
옵션 1
연관 테이블을 사용합니다.
사용자----사용자 ID(PK)이름.부서
허가----권한 ID(PK)이름.
사용자_권한----사용자 ID(FK)권한 ID(FK)
옵션 2
각 사용자에 대한 비트 마스크를 저장합니다.
사용자----사용자 ID(PK)이름.부서권한
[Flags]
enum Permissions {
Read = 1,
Create = 2,
Download = 4,
Print = 8,
Approve = 16
}
훌륭한 질문입니다!
먼저, "더 나은" 것에 대해 몇 가지 가정을 해 보겠습니다.
디스크 공간은 크게 신경 쓰지 않는 것 같습니다. 공간 측면에서는 비트마스크가 효율적이지만 SQL 서버를 사용하는 경우에는 그다지 중요하지 않습니다.
속도에 신경 쓰시는 것 같은데요.비트 마스크는 계산을 사용할 때 매우 빠를 수 있지만 비트 마스크를 쿼리할 때 인덱스를 사용할 수 없습니다.이것은 그다지 중요하지 않지만, 어떤 사용자가 작성 권한을 가지고 있는지 알고 싶다면, 당신의 질문은 다음과 같습니다.
select * from user where permsission & CREATE = TRUE
(현재 이동 중에 SQL 서버에 액세스할 수 없습니다.)이 쿼리는 수학적 연산 때문에 인덱스를 사용할 수 없으므로 사용자가 많을 경우 매우 고통스러울 수 있습니다.
유지관리에 신경을 쓰시는 것 같군요.유지 관리 측면에서 비트 마스크는 명시적 권한을 저장하는 것만큼 기본 문제 도메인만큼 표현력이 높지 않습니다.데이터베이스를 포함한 여러 구성 요소에 걸쳐 비트마스크 플래그 값을 거의 확실히 동기화해야 합니다.불가능한 건 아니지만, 등에 통증이 있습니다.
따라서 "더 나은" 평가를 위한 다른 방법이 없는 한 비트마스크 경로는 정규화된 데이터베이스 구조에 권한을 저장하는 것만큼 좋지 않습니다.저는 "가입을 해야 하기 때문에 속도가 느릴 것"이라는 데 동의하지 않습니다. 완전히 작동하지 않는 데이터베이스가 없으면 이를 측정할 수 없습니다. 반면 활성 인덱스의 이점이 없는 쿼리는 수천 개의 레코드로도 눈에 띄게 느려질 수 있습니다.
개인적으로, 저는 연상표를 사용할 것입니다.
비트마스크 필드는 쿼리하고 가입하기가 매우 어렵습니다.
언제든지 C# 플래그 열거형에 매핑할 수 있으며 성능이 향상되고 문제가 발생하면 데이터베이스를 리팩터할 수 있습니다.
조기 최적화에 대한 가독성 ;)
확실한 답은 없으니, 당신에게 맞는 것을 하세요.하지만 여기 내가 잡은 것이 있습니다.
다음과 같은 경우 옵션 1 사용
- 사용 권한이 여러 개로 증가할 것으로 예상됩니다.
- 데이터베이스 저장 프로시저 자체에서 권한 검사를 수행해야 할 경우
- 테이블의 레코드가 대규모로 증가하지 않도록 수백만 명의 사용자가 필요하지 않습니다.
다음과 같은 경우 옵션 2 사용
- 사용 권한이 소수로 제한됩니다.
- 수백만 명의 사용자가
정규화된 사용 권한을 저장합니다(비트 마스크가 아님).시나리오에 대한 요구 사항은 아니지만(특히 권한이 자주 변경되지 않을 경우) 쿼리를 훨씬 더 쉽고 명확하게 수행할 수 있습니다.
다음과 같은 이유로 비트마스크를 사용하지 않는 것이 좋습니다.
- 인덱스를 효율적으로 사용할 수 없습니다.
- 쿼리가 더 어렵습니다.
- 가독성/유지보수에 심각한 영향을 받음
- 일반 개발자들은 비트마스크가 무엇인지 모릅니다.
- 유연성이 감소합니다(숫자의 비트 nr에 대한 상한).
쿼리 패턴, 계획된 기능 세트 및 데이터 배포에 따라 옵션 1 또는 다음과 같은 간단한 옵션을 선택할 수 있습니다.
user_permissions(
user_id
,read
,create
,download
,print
,approve
,primary key(user_id)
);
열을 추가하는 것은 스키마 수정이지만, "Purge" 권한을 추가하는 것은 코드가 필요하기 때문에 권한이 생각만큼 동적일 필요가 없을 수도 있습니다.
사용자 기반의 90%가 단일 권한을 가지고 있지 않은 것과 같이 데이터를 잘못 배포하는 경우 다음 모델도 잘 작동합니다. 그러나 더 큰 검색(5방향 조인 하나와 전체 테이블 검색 하나)을 수행할 때는 작동하지 않습니다.
user_permission_read(
user_id
,primary key(user_id)
,foreign key(user_id) references user(user_id)
)
user_permission_write(
user_id
,primary key(user_id)
,foreign key(user_id) references user(user_id)
)
user_permission_etcetera(
user_id
,primary key(user_id)
,foreign key(user_id) references user(user_id)
)
사용 권한을 저장하기 위해 비트마스크 필드를 사용하는 경우를 생각할 수 있는 유일한 방법은 오래된 모바일 장치에서 사용하는 물리적 메모리의 양에 정말로 제약을 받는 경우입니다.사실, 저장하는 메모리의 양은 가치가 없습니다.수백만 명의 사용자라도 하드 드라이브 공간은 저렴하며 비트마스크가 아닌 접근 방식을 사용하여 훨씬 더 쉽게 권한 등을 확장할 수 있습니다(이것은 권한 등을 가진 사용자를 보고하는 것에 관한 것입니다).
데이터베이스에서 사용자 권한을 직접 할당하는 것이 가장 큰 문제 중 하나입니다.일반적으로 애플리케이션 데이터를 많이 사용하지 않고 애플리케이션 자체를 관리하기 위해 애플리케이션을 사용해야 한다는 것을 알고 있지만, 때로는 필요할 때도 있습니다.비트 마스크가 실제로 문자 필드가 아니고 사용자가 정수 대신 어떤 권한을 가지고 있는지 쉽게 확인할 수 있는 경우가 아니라면 분석가 등에게 설명해 보십시오.필드를 업데이트하여 누군가에게 쓰기 권한 등을 부여하는 방법... ...그리고 당신의 산술이 정확하기를 기도합니다.
구조가 바뀌지 않고 항상 함께 사용될 때 유용합니다.이렇게 하면 서버로의 왕복 이동이 거의 없습니다.변수를 한 번 할당하면 모든 권한에 영향을 줄 수 있기 때문에 성능 면에서도 좋습니다.
저는 개인적으로 그들을 좋아하지 않아요...일부 성능 집약적인 애플리케이션에서는 여전히 사용됩니다.저는 당신이 보드를 단일 비교로 평가할 수 있었기 때문에 이것들을 사용하여 체스-AI를 구현했던 것을 기억합니다.함께 일하는 것은 괴로운 일입니다.
데이터베이스가 단순히 레코드를 보관하는 것이 아니라면 항상 정규화된 상태로 저장할 것이며, 검색 및 저장 이외에는 이 작업을 수행하지 않을 것입니다.이에 대한 시나리오는 로그인 시 사용자의 권한 문자열이 가져와 서버 코드에서 처리되고 캐시되는 경우입니다.그런 경우에는 비정규화되는 것이 그다지 중요하지 않습니다.
만약 당신이 그것을 끈에 저장하고 DB 수준에서 작업을 하려고 한다면, 당신은 X페이지에 대한 허가를 얻기 위해 약간의 체조를 해야 할 것이고, 이것은 고통스러울 수 있습니다.
값을 이해하기 위해 관련 테이블에 조인을 포함할 필요가 없으므로 플래그 열거(비트 마스크)를 사용하여 쿼리가 더 빠르게 실행됩니다.
언급URL : https://stackoverflow.com/questions/5708239/when-is-it-better-to-store-flags-as-a-bitmask-rather-than-using-an-associative-t
'programing' 카테고리의 다른 글
DataReader 개체에서 필드의 데이터 유형 찾기 (0) | 2023.07.09 |
---|---|
JPA 및 최대 절전 모드를 사용하여 Java 부울 열을 Oracle 번호 열에 매핑 (0) | 2023.07.09 |
스프링 부트(보안) 및 키클로크로 역할 인증을 사용하시겠습니까? (0) | 2023.07.09 |
Oracle 저장 프로시저에 대한 varchar2 입력의 기본 크기는 얼마이며 변경할 수 있습니까? (0) | 2023.07.09 |
메서드가 여러 개 중 하나의 인수로 호출되었다고 주장합니다. (0) | 2023.07.09 |