데이터베이스에서 비트 마스크를 사용할 때의 장단점


22

얼마 전 나는 동료와 이야기를 나누었으며 데이터베이스에 저장된 모든 값을 이해하기가 어렵 기 때문에 비트 마스크를 사용하는 것에 대해 확실히 반대했습니다. 내 의견으로는 항상 현재 사용자의 역할을 결정하는 데 사용하는 것이 나쁜 생각은 아닙니다. 그렇지 않으면 별도의 테이블에 저장해야 하나의 JOIN이 추가로 발생합니다. 내가 틀렸다면 알려주시겠습니까? 비트 마스크 사용의 다른 부작용, 장점 / 단점?


2
데이터베이스가 내부적으로 비트 마스크를 작성하고 비트를 별도의 열로 표시하도록하는 것이 더 합리적 일 수 있습니다. 요구 사항이 변경 될 수 있습니다.
Simon Richter

1
조인을 사용하지 않으면 원하는 방식으로 관계형 데이터베이스를 사용하지 않는 것입니다.
Pieter B

답변:


38

비트 마스크를 사용하여 사용자 역할 할당을 저장하는 응용 프로그램을 사용합니다. 엉덩이가 아파요. 이것이 나를 편견으로 만들면 유죄로 기소됩니다.

이미 관계형 데이터베이스를 사용하고 있다면 대부분의 관계 이론과 모든 정규화 규칙을 위반하는 반 패턴입니다. 자체 데이터 스토리지를 구축 할 때 그리 나쁜 아이디어는 아닙니다.

너무 많은 테이블을 조인하는 것과 같은 것이 있지만 관계형 데이터베이스는이를 처리하기 위해 만들어졌습니다. 성능이 문제가되는 경우 인덱스, 인덱싱 된 뷰 등의 추가 기능이 많이 있습니다. 찾고있는 값이 자주 변경되지 않더라도 Bitmask의 장점은 인덱싱을 관리해야하는 오버 헤드입니다. 데이터베이스에서 매우 쉽습니다.

데이터베이스는 데이터 집계 작업을 잘 수행하지만 복잡한 수식이나 스칼라 함수 등을 데이터 세트에 도입하기 시작하면 느려질 수 있습니다. 앱에서 비트 단위로 작업을 수행 할 수 있지만 사용자가 수행하는 모든 작업이 관련 데이터를 얻는 것 (사용자 역할을 찾는 것)이라면 데이터 스토리지가 가장 잘 수행하는 기능을 활용하지 못합니다.

그것에 대한 나의 마지막 주장은 다른 개발자에게는 단순 할 것입니다. 사용자, 역할 및 할당이 있습니다. 공통적 인 다 대다 관계 세트 (하나 이상의 관계가 있기 때문에)는 관리하기 쉬워야합니다. CRUD 일뿐입니다.


8
관계형 데이터베이스는 비트 마스크에서 최악의 장소입니다. 스토리지 비용은 더 이상 나쁘지 않으므로 몇 개의 조인과 추가 테이블로 인해 문제가 발생합니다. 확실히 모든 것을 추론하기 어렵게 만듭니다. 권한을 자체 테이블의 데이터베이스에 비트 (1/0)로 저장하고 플래그는 있지만 코드로 표시합니다. 꽤 적절하고 실현 가능한 것 같습니다. 개발자는 간단한 플래그를 얻고 dbas에는 정규화 된 테이블이 있습니다. 모든 사람이 행복하다.
Mike McMahon 2016 년

3
동의 한 바에 따르면, 데이터베이스에서 사용자 역할 및 권한에 비트 마스크를 사용하는 응용 프로그램을 지원했습니다. 악몽이었다. 32 비트 int를 사용하면 비트가 부족하여 누군가가 더 많은 비트 마스크 를 추가 한 다음 겹치는 부분이 좋으므로 한 열의 비트 4는 다른 열의 비트 8을 의미하며 동기화되지 않았습니다. 알겠습니다 인덱스는 개별 비트가 아닌 이산 열 값을 저장하므로 where some_bit_mask & 12 > 0행별로 스캔하지 않으면 행 을 검색 할 수 없으므로 인덱스하기가 어려웠습니다 .
Brandon

하루가 끝나면 다 대다 user_role_map또는 user_priv_map테이블이 충분했을 것입니다.
Brandon

@ MikeMcMahon, 당신은 테이블 디자인에 대해 더 깊이 뛰어 들어 주시겠습니까? 그리고 당신이 말하는 결과를 달성하기 위해 어떻게 코드로 매핑해야합니까?
Alex Ovechkin 2016 년

2
@usr-절대로 말하지 마십시오. 물론 비트 마스크를 사용할 수는 있지만 관계형 데이터베이스를 사용하는 응용 프로그램에서는 비트 마스크를 사용하지 않습니다. 레거시 데이터를 처리하거나 속도가 매우 필요한 경우가 있습니다.
JeffO

24

관련 장단점을 이미 지정했습니다.

  • 비트 필드는 공간을 절약합니다.
  • 레코드 자체에 데이터를 저장하므로 데이터를 찾기 위해 JOIN이 필요하지 않습니다. 그러나 레코드의 개별 플래그 필드는 동일합니다.
  • 원시 SQL 출력으로 생산적으로 작업하려면 읽기가 어렵습니다.

수행 할 작업을 결정하려면 추가 정보가 필요합니다.

  • 사용 사례에 디스크 공간이 얼마나 부족합니까?
  • 실제로 사용자 역할을 너무 자주 읽고 참여할 때 병목 현상이 발생합니까?
  • 있습니까 당신은 그 기반으로 SQL 출력과 메이크업 결정을 읽을 것 - 또는 당신의 시스템의 기계 코드를 읽을 수 있다는 사실처럼 읽을 수없는 데이터베이스 기록 중요하지 않다?

따라서 당신이해야 할 일은 위험 요소를 수집하고 가중치를 부여 하여 전문가가 단점을 능가하는지 확인하는 것입니다.


답변 주셔서 감사합니다, 당신의 생각에 전적으로 동의하지만, 일반적으로 이것이 반 패턴입니까? 그리고 프로젝트에서 마스크를 사용합니까?
Alex Ovechkin

12
@Alex 귀하의 경우에 무엇을해야할지 결정할 수있는 "모범 사례"와 같은 것은 없습니다. 공간이 매우 부족한 경우 비트 필드를 사용하는 것이 가장 좋습니다. CEO에 대한 보고서에서 SQL 출력을 사용하려면 말하기 이름을 사용하는 것이 가장 좋습니다. 그러나 귀하 는 이러한 상황을 아는 유일한 사람이므로 커뮤니티는 항상 유효한 처방전을 줄 수 없습니다 .
Kilian Foth

공간 인수를 "gimme"으로 간주합니다. 비트 마스크를 사용할지 여부에 대한 문제는 이것이 그 이상의 이점을 유추하는지 여부에 달려 있습니다.
로비 디

또한 데이터베이스의 정보를 처리해야하거나 사용하기 전에 항상 응용 프로그램으로 읽어야합니까?
Ian

1
"SQL 출력을 읽고이를 기반으로 의사 결정을 하시겠습니까? 아니면 시스템의 기계 코드를 읽을 수 없다는 사실과 마찬가지로 읽을 수없는 데이터베이스 레코드가 중요하지 않습니까?" 모든 개발자에게 말할 수는 없지만, 개발할 때 DB에서 데이터를 선택하여 무언가를 이해하거나 확인하는 것이 매우 일반적입니다. 저는 보통 이것 에 대한 대답은 "그렇습니다, 누군가는 할 것입니다" 라고 주장합니다 .
jpmc26

18

당신이 정말 있다면 정말 , 정말 디스크 공간이 부족한, 당신은 수있는 사용자 권한에 대한 비트 맵을 고려한다. 성능이 걱정된다면, 그것들을 골라내는 것이 실제로 느리기 때문에 모두 잊어 버려라. 비트 맵 필드를 의미있게 인덱싱 할 수 없으므로 데이터베이스 테이블 스캔이 발생하며 이로 인해 거의 항상 성능이 저하됩니다.

Amazon 또는 Netflix 가 아닌 한, 사용자 권한과 관련된 데이터 양은 보유하고있는 모든 데이터에 비해 무시할 수 있습니다.

심각한 DBMS는 깜박임없이 해당 "추가 조인"을 처리 할 수 ​​있습니다.


7
+1 : 좋은 관계형 데이터베이스는 실제로 자신이하는 일에 정말 능숙한 사람들이 개발합니다. 비트 필드를 사용하여 얻을 수있는 마지막 성능을 줄이려는 사람은 질문 할 필요가 없습니다. 데이터를 모델링 한 다음 수행하지 않는 부분을 찾으십시오.
Blrfl

조인하면 응용 프로그램 코드가 더 복잡해 지므로 역할이 처리되는 위치가 많이 있습니다.
Ian

4
@Ian에 참여하는 것은 비트 마스크 권한을 해독하는 방법을 알아야하는 것보다 더 복잡해 보이지 않습니다.
Brad

@Brad, C #의 플래그 집합 인 열거 형을 생각해보십시오. 데이터베이스에 값이“있는 그대로”저장되어 있으면 C # 콜드가 더 단순 해집니다. 조인을 사용하는 경우 C # 코드는 "1 대 다수"관계에 대처해야합니다.
Ian

또한 테이블에 여러 부울 열이있는 경우 대부분의 데이터베이스는 가능한 한 작은 공간으로 열을 스쿼시하는 방법을 알아 내고 비트 트위들 링을 처리합니다.
Blrfl

8

스토리지 비용이 비쌌을 때 비트 마스크를 사용하면 공간을 절약 할 수있었습니다. 빅 데이터 시대에는 이것이 한 번의 문제가 아닙니다.

비트 마스크로 저장된 역할을 인용하는 예를 들자면 데이터베이스 디자인 관점에서 첫 번째 정상적인 형태를 위반하는 코드 냄새가납니다 . 이런 의미에서, 그들은 반 패턴입니다.

이 모든 것을 말하면, 하나 또는 다른 것일 필요는 없습니다. 데이터를 비트 마스크로 저장 한 다음 사용자 역할을 즉시 가져올 수있는보기를 가질 수 있습니다. 그러면 어떤 사용자가 동일한 역할을했는지 한눈에 확인할 수있는 이점도 있습니다.


2

비트 마스크 사용의 유일한 장점은 비트 필드의 의미가 정적 인 것이 아니라는 것입니다. 관계형 테이블은 각 필드가 레코드에 무엇인지 미리 알고있는 경우에만 잘 작동 CREATE TABLE합니다. 결국 DDL 문 에서 필드를 식별해야합니다 .

경우 각 비트 필드의 의미는 런타임에 구성 또는 기타 미리 알 수 없습니다, 그것은 수있는 비트 필드로 논리 값을 저장하는 데 의미합니다. 그렇다하더라도, 임의의 필드와 테이블을 정의 할 수 있습니다 : field_1, field_2, 등이 당신에게 청소기 관계형 디자인을 제공합니다,하지만 여전히 적합하지 않습니다. 이것이 비트 필드보다 우선적인지 여부는 해결책이 이상적이지 않기 때문에 크게 의견의 문제입니다.

개발 중 비트가 무엇을 나타내는 지 알고 있으면 각 비트에 대한 필드를 작성 하고 의미있는 이름을 지정하십시오 .

내부 플랫폼 효과에 주의하십시오 . 한 가지 인 임의이지만 잘 입력 된 필드를 정의하게되지만 그보다 너무 멀리 갈 경우 관계형 데이터베이스 내에서 관계형 데이터베이스를 다시 발명하게됩니다.


2

비트 마스크에 대해 모호합니다. 나는 그들의 비난의 대부분이 이진수와 16 진수를 이해하지 못한다는 것을 안다. 명확성을 위해 좋은 니모닉을 사용하십시오.

위에서 언급하지 않은 이점은 잠재적으로 시간이 많이 걸리는 새 열을 추가하지 않고도 비트 마스크에 새로운 의미를 추가 할 수 있다는 것입니다. 우리의 db 디자이너 (나보다 먼저)는 이제 매일 5 백만 개의 새로운 레코드를 얻는 테이블에 있습니다. 새로운 동작을 나타 내기 위해 새로운 열을 추가하는 데 시간이 오래 걸리지 만 새로운 비트를 정의하려면 (64/33을 소비 함) 테이블을 다시 작성할 필요가 없습니다.

아니요, 비트 마스크는 인덱싱 할 수 없지만 33 개의 인덱스를 작성하는 것은 말도 안되며 크롤링에 대한 삽입 속도가 느려집니다. 테이블 검색은 날짜 및 레코드 "소유자"인덱스를 사용하므로 가능하면이 비트 마스크의 인덱스는 사용되지 않습니다.


흥미로운 경우입니다. 테이블에 "예비"열을 정의한 다음 필요에 따라이를 사용하여 정직하고 명시적인 방식으로 동일한 결과를 얻을 수 있다고 가정합니다. 그런 다음 선택하면 적어도이 열을 선택적으로 색인화 할 수 있습니다.
스티브

1

디스크 공간을 절약하는 것이 목표라면 나쁜 생각이라고 생각합니다.

  • 오늘 GB 비용을보고
  • 보고서와 쿼리를 작성하고 필드에 무엇이 있는지, 특정 비트를 해결하는 방법을 알아 내야하는 사람들의 시간 비용과 비교하면 비용 / 이익 비교가 잘못된 측면에서 끝날 수 있습니다.
  • SQL 데이터베이스로 작업하는 경우 많은 쿼리에서 필요한 추가 비트 액세스 작업이 필요한 것보다 더 많은 컴퓨팅 시간을 소비 할 수도 있습니다

그러나 비트 필드 사용을 판단 할 수있는 경우가 있습니다.

  • 비트가 항상 전체적으로 함께 처리하는 복잡한 플래그 집합을 나타내는 경우,
  • 이 세트에 패턴 매칭 알고리즘을 적용해야하는 경우
  • 특히이 데이터가 가장 자주 사용되는 선택 기준 중 하나가 아닌 경우.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.