Oracle의 부울 필드


145

어제 Oracle 테이블에 부울 필드를 추가하고 싶었습니다. 그러나 Oracle에는 실제로 부울 데이터 유형이 없습니다. 여기 누구든지 부울을 시뮬레이션하는 가장 좋은 방법을 알고 있습니까? 인터넷 검색에서 몇 가지 접근 방식이 발견되었습니다.

  1. 정수를 사용하고 0 또는 1 이외의 다른 것을 할당하지 마십시오.

  2. 두 개의 값으로 'Y'또는 'N'이있는 문자 필드를 사용하십시오.

  3. CHECK 제약 조건과 함께 열거 형을 사용하십시오.

숙련 된 Oracle 개발자는 어떤 접근 방식이 선호 / 정규인지 알고 있습니까?


195
wall부울을 사용할 때 오라클이 데이터 유형을 가지고 있기 때문에 머리를 부술 수 있기를 바랍니다 .
Greg

답변:


82

링크가 유용하다는 것을 알았습니다 .

다음은 각 접근법의 장단점을 강조한 단락입니다.

가장 일반적으로 보이는 디자인은 Oracle의 데이터 사전보기에서 사용하는 많은 부울 유사 플래그를 모방하여 'Y'를 true로, 'N'을 false로 선택하는 것입니다. 그러나 JDBC, OCCI 및 기타 프로그래밍 환경과 같은 호스트 환경과 올바르게 상호 작용하려면 getBoolean 및 setBoolean 함수에서 올바르게 작동 할 수 있도록 false로 0을, true로 1을 선택하는 것이 좋습니다.

기본적으로 그들은 효율성을 위해 방법 번호 2를 옹호합니다.

  • getBoolean()점검 제한 조건이있는 0/1의 (JDBC 등과 의 상호 운용성으로 인해 )
  • CHAR의은 (그 수보다 적은 공간을 사용하기 때문에).

그들의 예 :

create table tbool (bool char check (bool in (0,1));
insert into tbool values(0);
insert into tbool values(1);`

31
'N'과 'Y'는 언어에 따라 다르므로 사용하지 않는 것이 좋습니다. 앵글 폰은 때때로 대부분의 세계가 문자 Y로 진실의 개념을 나타내지 않는다는 것을 잊어 버립니다. 대조적으로, 0과 1의 의미는 언어 장벽에서 일정합니다.
앤드류 스펜서

7
부울 값으로서의 0과 1은 컴퓨터 과학 내에서 일관성이 없습니다-쉘 스크립트 유형 언어는 성공으로 0, 비제로 실패하는 반면 C 유형 언어는 실패로 0, 그리고 제로가 아닌 경향이 있습니다.
Phil

41
으로 부울 값, 그들은 헷갈 리지 않을 정도까지만이다. 프로세스 리턴 코드는 부울 값이 아닙니다.
Andrew Spencer

13
이 링크에서 제공된 링크의 전체 단락이 무시 된 이유는 무엇입니까? "가장 일반적으로 보이는 디자인은 Oracle의 데이터 사전보기에서 사용하는 많은 부울과 유사한 플래그를 모방하여 'Y'를 true로, 'N'을 false로 선택하는 것입니다. 그러나 JDBC, OCCI, 다른 프로그래밍 환경에서는 getBoolean 및 setBoolean 함수에서 올바르게 작동 할 수 있도록 false로 0을, true로 1을 선택하는 것이 좋습니다. " 'Y / N'이 일반적이지만 호스트 환경과의 호환성을 높이기 위해 '0/1'을 사용하는 것이 좋습니다.
justin.hughey

28

Oracle 자체는 부울 값에 Y / N을 사용합니다. 완전성을 위해 pl / sql에는 부울 유형이 있으며 그렇지 않은 테이블 일뿐입니다.

필드를 사용하여 레코드를 처리해야하는지 여부를 표시하는 경우 Y 및 NULL을 값으로 사용하는 것을 고려할 수 있습니다. 따라서 공간을 거의 차지하지 않는 매우 작은 (빠른 읽기) 인덱스가 만들어집니다.


7
+1 Y / N을 사용하는 Oracle 내부 뷰 및 테이블에 대한 장점. 오라클이 그렇게한다면 옳 아야합니다! :)
Jeffrey Kemp

Y 및 NULL이 Y 및 N에 비해 작은 인덱스를 만드는 방법을 설명 할 수 있습니까?
styfle

6
NULL은 Oracle에서 인덱싱되지 않으므로 인덱스에 Y 문자가 몇 개 포함되어 있지만 대부분 NULL이면 인덱스가 매우 작습니다.
레이 리펠

25

최소한의 공간을 사용하려면 'Y'또는 'N'으로 제한된 CHAR 필드를 사용해야합니다. Oracle은 BOOLEAN, BIT 또는 TINYINT 데이터 유형을 지원하지 않으므로 CHAR의 1 바이트는 가능한 한 작습니다.


19

가장 좋은 옵션은 0과 1입니다 (숫자-다른 대답은 공간 효율을 위해 CHAR 로 0과 1을 제안 하지만 나에게는 너무 꼬임입니다). NOT NULL과 검사 제한 조건을 사용하여 내용을 해당 값으로 제한합니다. (열이 널 입력 가능 해야하는 경우 처리하는 부울이 아니라 세 개의 값을 가진 열거입니다 ...)

0/1의 장점 :

  • 언어 독립적. 모두가 사용한다면 'Y'와 'N'은 괜찮을 것입니다. 그러나 그들은하지 않습니다. 프랑스에서는 'O'와 'N'을 사용합니다 (내 눈으로 이것을 보았습니다). 핀란드에서 'E'와 'K'를 사용하는지 여부를 확인하도록 프로그래밍하지 않았습니다. 의심 할 여지없이 그보다 똑똑하지만 확실하지는 않습니다.
  • 널리 사용되는 프로그래밍 언어 (C, C ++, Perl, Javascript)의 실습에 적합
  • 응용 프로그램 계층 (예 : 최대 절전 모드)으로 더 잘 재생
  • 예를 들어, 얼마나 많은 바나나가 먹을 수 있는지 또는 심지어 select sum(is_ripe) from bananas는 먹을 수 있는지를 알기 위해 더 간결한 SQL로 연결됩니다.select count(*) from bananas where is_ripe = 'Y'select sum(case is_ripe when 'Y' then 1 else 0) from bananas

'Y'/ 'N'의 장점 :

  • 0/1보다 적은 공간을 차지합니다
  • 오라클이 제안한 것이므로 일부 사람들이 더 익숙한 것일 수도 있습니다.

다른 포스터는 성능 향상을 위해 'Y'/ 널을 제안했습니다. 당신이 한 경우 입증 그런 다음 성능, 공정 충분히 필요하지만, 덜 자연 (쿼리하게하기 때문에, 그렇지 않으면하지 않는 것이 some_column is null대신 some_column = 0)과 왼쪽에 당신이 존재하지 않는 레코드 불성실 conflate 것입니다 가입 할 수 있습니다.


3
요즘에는 많은 부울이 TriState 즉 true, false 및 unknown이라는 것을 알 수 있습니다. 데이터베이스 null 아이디어와 완벽하게 일치합니다. 답이 전혀 없다는 것을 아는 것이 매우 중요하기 때문에
MikeT

1
예, 참 거짓을 알 수는 있지만, 내가 까다 롭다면 부울로 묘사해서는 안된다고 말하고 싶습니다.
앤드류 스펜서

2
당신이 까다 롭다면 모든 데이터 유형에 대해 동일한 논쟁을 할 수 있습니다. 엄격한 정의 정수 아래로 두 번 등 진, 문자열, 모든 값을 제공하지만, 데이터베이스 구현은 항상 부울 어떤 다르지 않다 NULL 값 옵션을 추가한다고 가정 (내가 이중 길이의 보수는 부동 소수점을 보완 말해야한다 생각)
MikeT을

1
사실, 숫자를 올바르게 구성하면 메소드의 플러스 노트에서 char 필드와 동일한 단일 바이트에 저장할 수도 있습니다. 이는 1 / 1을 사용하지 않고 크기 인수를 무효화합니다. 현재 링크를 찾을 수 없지만 구성에 따라
1-22

4
다운 보트는 가장 효율적인 메모리 구현을 선택한다는 레거시 관점 때문이라고 생각합니다. 요즘 메모리 효율성은 우선 순위보다 훨씬 낮으며 사용성 및 호환성 후에 고려해야합니다. 이 의견에 응답 할 수있는 사람이라면 조기 최적화에 대해 읽어 보는 것이 좋습니다. 이는 메모리 효율성을 기반으로 'Y / N'을 선택함으로써 발생하는 것과 정확히 일치합니다. 이러한 결정으로 인해 일반적으로 사용되는 프레임 워크와의 기본 호환성이 손실됩니다.
justin.hughey

5

점검 제한 조건이있는 1/0 또는 Y / N입니다. 에테르 방식은 괜찮습니다. 개인적으로 perl에서 많은 작업을 수행하므로 개인적으로 1/0을 선호하며 데이터베이스 필드에서 perl 부울 연산을 수행하기가 정말 쉽습니다.

당신이 오라클 머리 honchos 중 하나가이 문제의 정말 깊이 토론을 원하는 경우에, 톰 카이트는 이것에 대해 무슨 얘기 체크 아웃 여기에


1/0 IS는 "적은 메모리 효율성"이 될하지만 ... 나는 그것을처럼 더도 (그리고 분명히 부울 1/0을 필요로 최대 절전 모드)라고
rogerdpack

1/0은 부울에 대한 최대 절전 모드의 기본값이지만 원하는 사용자 정의 매핑을 정의 할 수 있습니다.
앤드류 스펜서

char 필드가 1 바이트, 또는 nchar에 대해 2 바이트이기 때문에 @rogerdpack은 그것이 정의되는 방법에 따라 1에서 22 바이트까지 가능합니다
MikeT

4

내가 작업 한 대부분의 데이터베이스는 'Y'/ 'N'을 부울로 사용했습니다. 이 구현으로 다음과 같은 몇 가지 트릭을 시작할 수 있습니다.

  1. 참인 행 수 :
    SELECT SUM (CASE WHEN BOOLEAN_FLAG = 'Y'THEN 1 ELSE 0) FROM X

  2. 행을 그룹화 할 때 "한 행이 참이면 모두 참"논리를 적용하십시오.
    SELECT MAX (BOOLEAN_FLAG) FROM Y
    반대로, 한 행이 거짓이면 MIN을 사용하여 그룹화를 강제로 거짓으로 만듭니다.


4
실제로 표시된 예제는 0/1 접근 방식에도 유용하며 IMHO도 더 빠릅니다.
igorsantos07

2

Oracle 데이터베이스의 기존 테이블에 "부울"열을 추가하여 허용되는 답변을 구현하는 실제 예제 ( number유형 사용 ) :

ALTER TABLE my_table_name ADD (
my_new_boolean_column number(1) DEFAULT 0 NOT NULL
CONSTRAINT my_new_boolean_column CHECK (my_new_boolean_column in (1,0))
);

이 새로운 열 생성 my_table_name이라는 my_new_boolean_column수락하지 않습니다 열 0의 기본 값으로 NULL값을하고 하나에 허용되는 값을 제한 0하거나 1.


1

데이터베이스에서는 TRUE 또는 FALSE를 전달하는 열거 형을 사용합니다. 처음 두 가지 방법 중 하나를 수행하면 적절한 디자인을 거치지 않고 정수에 새로운 의미를 추가하거나 Y, y, N, n, T, t를 갖는 char 필드로 끝나는 것이 너무 쉽습니다. F, f 값 및 코드의 어느 섹션에서 어떤 테이블을 사용하고 어떤 버전의 true를 사용하는지 기억해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.