문제

나는 이것을 호기심으로 묻습니다. 기본적으로 내 질문은 깃발처럼 행동하기 위해 행 항목이 필요한 데이터베이스가있을 때입니다. 모범 사례는 무엇입니까? 이에 대한 좋은 예는 스택 오버플로의 배지 또는 Bugzilla의 운영 체제 필드입니다. 주어진 항목에 대해 플래그의 모든 하위 집합이 설정 될 수 있습니다.

일반적으로 C 및 C ++ 작업을 수행하므로 내장 반응은 서명되지 않은 정수 필드를 뒤집을 수있는 비트 세트로 사용하는 것입니다. 그러나 여러 가지 이유로 좋은 해결책은 아님을 알고 있습니다. 가장 분명한 것은 규모 능력이며, 내가 가질 수있는 깃발의 수에는 단단한 상한이있을 것입니다.

또한 모든 정보를 얻기 위해 여러 선택이 필요하기 때문에 성능 문제가 더 좋을 수있는 몇 가지 다른 솔루션을 생각할 수 있습니다.

그렇다면이 작업을 수행하는 "올바른"방법은 무엇입니까?

도움이 되었습니까?

해결책

닫힌 플래그 세트 (예 : StackoverFlow 배지)에서 무한한 선택이 필요한 경우 "관계형 방법"은 해당 플래그를 대상 엔티티와 관련시키는 깃발 테이블과 별도의 테이블을 만드는 것입니다. 따라서 사용자, 깃발 및 유용한 사람들.

그러나 공간 효율이 심각한 관심사이고 쿼리 가능성이 아니라면 서명되지 않은 마스크도 거의 작동합니다.

다른 팁

일반적으로, 나는 비트 마스크 필드를 피합니다. 그들은 미래에 읽기가 어렵고 이해에 대한 데이터에 대한 훨씬 더 심층적 인 지식이 필요합니다.

관계형 솔루션은 이전에 제안되었습니다. 당신이 설명한 예를 감안할 때, 나는 (SQL Server)와 같은 것을 만들 것입니다.


CREATE TABLE Users (
  UserId INT IDENTITY(1, 1) PRIMARY KEY,
  FirstName VARCHAR(50),
  LastName VARCHAR(50),
  EmailAddress VARCHAR(255)
);

CREATE TABLE Badges (
  BadgeId INT IDENTITY(1, 1) PRIMARY KEY,
  [Name] VARCHAR(50),
  [Description] VARCHAR(255)
);

CREATE TABLE UserBadges (
  UserId INT REFERENCES Users(UserId),
  BadgeId INT REFERENCES Badges(BadgeId)
);

많은 경우 데이터베이스 백엔드와 같은 많은 것들에 따라 다릅니다. 예를 들어 MySQL을 사용하는 경우 데이터 유형을 설정합니다 정확히 당신이 원하는 것입니다.

기본적으로 비트 마스크 일뿐입니다. 각 비트에 값이 할당됩니다. MySQL은 최대 64 비트 값 (64 개의 다른 토글)을 지원합니다. 8 만 있으면 행당 바이트 만 필요합니다. 이는 정말 멋진 절약입니다.

단일 필드에 정직하게 64 개 이상의 값이 있다면, 필드가 더 복잡해 질 수 있습니다. MySQL이 고유 한 이해가없는 원시 비트 세트 인 Blob Datatype으로 확장 할 수 있습니다. 이것을 사용하면 MySQL이 바이너리, 16 진수 또는 10 진수 값으로 취급하는 데 기꺼이 임의의 비트 필드를 만들 수 있습니다. 64 개 이상의 옵션이 필요한 경우 응용 프로그램에 적합한 많은 필드를 작성하십시오. 단점은 필드를 인간을 읽을 수있게하기가 어렵다는 것입니다. 그만큼 비트 데이터 유형 또한 64로 제한됩니다.

매우 관계형 접근

세트 유형이없는 데이터베이스의 경우 새 테이블을 열어 각 플래그가 설정된 엔티티 세트를 나타낼 수 있습니다.

예를 들어, "학생" "학생"은 "등록자", "병사", 문제가있는 것 등을 가질 수 있습니다. 각 테이블에는 하나의 열만 있습니다 : wiching_id. 학생들이 어떤 학생들이 "등록"또는 "아프다"고 알고 싶다면 이것은 실제로 매우 빠릅니다. 모든 DBM에서 같은 방식으로 작동합니다.

플래그가 매우 다른 의미가 있고 SQL 쿼리 또는 뷰에서 직접 사용되는 경우 여러 유형의 유형을 사용하는 경우 BOOLEAN 좋은 생각 일 수 있습니다.

어쨌든 각 플래그를 추가 열에 넣으십시오. 어쨌든 별도로 읽고 수정하십시오. 깃발을 그룹화하려면 열 이름을 공통 접두사, 즉 다음 대신에 제공하십시오.

CREATE TABLE ... (
    warnings INTEGER,
    errors   INTEGER,
    ...
)

당신은 사용해야합니다 :

CREATE TABLE ... (
    warning_foo BOOLEAN,
    warning_bar BOOLEAN,
    warning_...
    error_foo   BOOLEAN,
    error_bar   BOOLEAN,
    error_...   BOOLEAN,
    ...
)

MySQL에는 부울 유형이 없지만 그 목적으로 준 표준 Tinyint (1)를 사용하여 0 또는 1로만 설정할 수 있습니다.

데이터베이스가 지원하는 경우 부울 데이터 유형을 사용하는 것이 좋습니다.

그렇지 않으면 가장 좋은 방법은 숫자 (1) 또는 동등한 숫자를 사용하고 유효한 값을 (0,1)으로 제한하는 열에 검사 제약 조건을 두는 것입니다. 내장 유형이없는 경우 문자 열을 사용하는 것보다 숫자를 사용하는 것이 모호하지 않습니다. (True의 가치는 무엇입니까? "T"또는 "Y"또는 "T")

이것에 대한 좋은 점은 sum ()을 사용하여 실제 행의 수를 계산할 수 있다는 것입니다.

SELECT COUNT(1), SUM(ActiveFlag)
FROM myusers;

몇 가지 이상의 깃발이 있거나 앞으로 그렇게 될 가능성이 높으면 별도의 깃발 테이블과 그들 사이에 다수의 테이블을 사용하겠습니다.

소수의 깃발이 있고 깃발이없고 어디에서나 사용하지 않겠다면, set () 또는 비트 필드 등을 사용하겠습니다. 그들은 읽기 쉽고 더 컴팩트하지만 쿼리에 대한 고통과 때로는 ORM과 함께 두통이 더 많습니다.

깃발이 몇 개 밖에 없다면 가고 있다 몇 개의 깃발이 되려면 - 나는 단지 몇 비트/부울/등을 만들 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top