콘텐츠로 이동

1. 데이터형#

SQL을 사용하여 데이터베이스에 데이터를 저장, 변경하고 질의하기 위해서는 데이터베이스의 자료형에 대한 이해가 선행되어야 한다. 이 장에서는 Altibase가 지원하는 데이터형에 대해서 자세히 설명한다.

데이터형의 종류#

Altibase에서 지원하는 데이터형은 다음과 같다.

문자형 데이터형#

M : 정의된 칼럼 길이
L : 입력 문자열의 길이
타입 Length Size
CHAR(M) 1 ~ 32000 M + 2
VARCHAR(M) 1 ~ 32000 length + 2
여기서
입력 값이 가변영역에 저장되면, length = L
입력 값이 고정영역에 저장되면, length = M
NCHAR(M) 1 ~ 16000(UTF16)
1 ~ 10666(UTF8)
M*2 + 2(UTF16)
M*3 + 2(UTF8)
NVARCHAR(M) 1 ~ 16000(UTF16)
1 ~ 10666(UTF8)
length*2 + 2(UTF16)
length*3 + 2(UTF8)
여기서:
입력 값이 가변영역에 저장되면, length = L
입력 값이 고정영역에 저장되면, length = M

NCHAR와 NVARCHAR는 유니코드 문자형 타입이다. UTF16으로 인코딩된 문자열의 최대 길이는 UTF8로 인코딩된 문자열의 최대 길이와 다르다.

숫자형 데이터형#

Non-native 타입 Precision Scale Size (bytes) 비 고
NUMERIC 38 0 3+((precision)+2)/2 *고정 소수점 숫자
*DECIMAL은 NUMERIC과 동일한 데이터 타입이다.
NUMERIC(p) 1 ~ 38 0
NUMERIC(p,s) 1 ~ 38 -84 ~ 128
DECIMAL 38 0
DECIMAL(p) 1 ~ 38 0
DECIMAL(p,s) 1 ~ 38 -84 ~ 128
NUMBER(p) 1 ~ 38 0
NUMBER(p,s) 1 ~ 38 -84 ~ 128
NUMBER 38 X 3+((precision)+2)/2 *부동 소수점 숫자
FLOAT 38 X
FLOAT(p) 1 ~ 38 X
Native 타입 호환 C Type Size(bytes) 비고
DOUBLE double 8 *부동 소수점 숫자
REAL float 4
BIGINT long
또는 long long
8 *정수형
INTEGER int 4
SMALLINT short 2

예제 1

고정 소수점 숫자 크기 계산 : ( 3 + ( ( p ) + 2 ) / 2 )

- NUMERIC  
  NUMERIC(38, 0): 크기 = 3 + 40/2 = 23 bytes

- NUMERIC(p) / NUMERIC(p, 0)  
  NUMERIC(10): 크기 = 3 + 12/2 = 9 bytes

- NUMERIC(p, s)  
  NUMERIC(10, 9): 크기 = 3 + 12/2 = 9 bytes

- DECIMAL: NUMERIC과 동일

- DECIMAL(p): NUMERIC(p)과 동일

- DECIMAL(p,s): NUMERIC(p,s)과 동일

- NUMBER(p): NUMERIC(p)과 동일

- NUMBER(p,s): NUMERIC(p,s)과 동일

예제 2

부동 소수점 숫자 크기 계산: ( 3 + ( ( p ) + 2 ) / 2 )

- FLOAT  
  FLOAT(38): 크기 = 3 + 40/2 = 23 bytes

- FLOAT(p)  
  FLOAT(20): 크기 = 3 + 22/2 = 14 bytes

- NUMBER: FLOAT과 동일

날짜 데이터형#

타입 Size (byte)
DATE 8

이진 데이터형#

M : 정의된 칼럼 길이
L : 입력 문자열의 길이
타입 Length Size
BLOB/CLOB 1 ~ 4294967295
BYTE 1 ~ 32000 M + 2
VARBYTE 1 ~ 32000 length + 2
여기서
입력 값이 가변영역에 저장되면, length = L
입력 값이 고정영역에 저장되면, length = M
NIBBLE 1 ~ 254 M/2 + 1
BIT 1 ~ 64000 M/8 + 4
VARBIT 1 ~ 64000 length/8 + 4
여기서
입력 값이 가변영역에 저장되면, length = L
입력 값이 고정영역에 저장되면, length = M

공간 데이터형#

타입 Length Size (byte)
GEOMETRY 8 ~ 104857600 length + 40

실제 레코드의 크기는 위에 각 데이터형 별로 명시된 크기(bytes)에서 헤더 정보 크기 만큼 추가된다. 헤더 정보는 운영체제에 따라 다를 수 있다.

NULL#

행을 테이블에 삽입할 때 열의 값을 모르거나 값이 아직 결정되지 않은 경우, 즉 값이 존재 하지 않는 것을 나타내는 경우에 널(NULL)이 사용된다. 널(NULL)은 0 또는 공백과는 다르며, 비교연산이나 저장시 특별하게 취급된다.

NVL() 함수, IS NULL 조건, IS NOT NULL 조건을 제외한 수식 연산에 널이 포함되면, 최종 연산의 결과는 널이 된다. 즉, 수식에 널이 포함되면 비교 또는 연산이 의미가 없어지게 된다.

테이블 생성 시 NOT NULL 또는 PRIMARY KEY로 정의되지 않은 모든 데이터 유형의 칼럼에는 널을 입력할 수 있다.

데이터 타입 변환#

서로 다른 데이터 타입에 대한 연산을 수행할 때 정확한 연산을 위해 데이터 타입이 변환되어 수행된다. 변환 방법은 묵시적인 방법과 명시적인 방법이 있다.

묵시적 데이터 타입 변환#

묵시적 변환이란, 타입이 다른 데이터를 연산할 때에는 내부적으로 데이터 타입을 변환하지만 데이터 타입의 속성은 유지되는 것을 의미한다. 같은 데이터 타입의 두 값을 비교 연산할 때, 어떤 변환 없이 직접 그 값에 대해 비교 연산이 수행된다. 그러나 비교되는 두 값의 데이터 타입이 다른 경우 한 쪽 값을 다른 값의 데이터 타입으로 변환한 후 비교 연산이 수행된다.

다음의 테이블은 묵시적 데이터 타입의 변환 가능한 행렬을 나타낸다 (O: 데이터 타입이 변환되어도 속성이 유지되는 것에 표시). 기존 테이블의 데이터 타입을 MODIFY 구문으로 변환하는 방법은 SQL Reference의 modify_column_clause 구문을 참조한다.

변환 후 ►
변환 전 ▼
char var char nchar nvarchar clob big int deci mal dou ble float int eger num ber num eric real small int date blob byte varbyte nibble bit varbit geometry
char o o o o o o o o o o o o o o
varchar o o o o o o o o o o o o o o o
nchar o o o o o o o o o o o o o o
nvarchar o o o o o o o o o o o o o o o
clob o
bigint o o o o o o o o o o o o o
decimal o o o o o o o o o o o o o
double o o o o o o o o o o o o o
float o o o o o o o o o o o o o
integer o o o o o o o o o o o o o
number o o o o o o o o o o o o o
numeric o o o o o o o o o o o o o
real o o o o o o o o o o o o o
smallint o o o o o o o o o o o o o
date o o o o o
blob o
byte o o o
varbyte o o o
nibble o
bit o o
varbit o o o
geometry o

묵시적 데이터 타입 변환 규칙#

테이블 t10 테이블에 bit 타입의 '1000'을 입력하면 integer '1000'으로 변환은 성공하지만, 데이터 타입의 속성이 달라지기 때문에 묵시적인 데이터 타입 변환이라고 볼 수 없다.

iSQL> create table t10 (i1 integer);
Create success.
iSQL> insert into t10 values (bit'1000');
1 row inserted.
iSQL> select * from t10;
I1
--------------
1000
1 row selected.

따라서 묵시적 데이터 타입의 변환은 아래와 같은 규칙을 따른다.

  • 숫자형 데이터 타입과 문자형 데이터 타입의 비교 연산 또는 사칙 연산시, 문자형 데이터 타입을 숫자형 데이터 타입으로 변환하여 수행한다.
  • 날짜형 데이터 타입과 문자형 데이터 타입의 비교 연산시, 문자형 데이터 타입을 날짜형 데이터 타입으로 변환하여 비교 연산을 수행한다.
  • 데이터 타입의 변환이 불가능한 연산은 무효화 된다.
  • 함수에서 사용되는 인자는 함수에서 정의된 인자의 데이터 타입으로 변환한다.
  • 문자형 데이터 타입이나 십진 정밀도(decimal precision)를 사용하는 수치형 데이터 타입을 이진 정밀도(binary precision)를 사용하는 부동소수점 수치형 데이터 타입으로 변환하면 값이 손실될 수 있다.
  • INSERT, UPDATE 실행시 INSERT, UPDATE 되는 칼럼의 데이터 타입으로 데이터형이 변환된다.

예제#

<질의> 숫자형 데이터 타입과 문자형 데이터 타입의 비교 연산시 문자형 데이터 타입 '10'은 숫자형 데이터로 변환된다.

iSQL> create table emp (empno integer, name varchar(10), hire_date date);
insert into emp values (10,'altibase', '10-nov-2015');

iSQL> select name from emp where empno = '10';
NAME
--------------
altibase
1 row selected.

<질의> 숫자형 데이터 타입과 문자형 데이터 타입 간 사칙연산시 문자형 데이터 타입 '10'은 숫자형 데이터 타입으로 변환된다.

iSQL> select empno + '10' from emp;
EMPNO+'10'
-------------------------
20
1 row selected.

<질의> 날짜형 데이터 타입과 문자형 데이터 타입의 비교 연산시 문자형 데이터 타입 '10-nov-2015'은 날짜형 데이터 타입으로 변환된다.

iSQL> select hire_date from emp where hire_date = '10-nov-2015';
HIRE_DATE
---------------
10-NOV-2015
1 row selected.

<질의> 숫자형 데이터 타입과 문자형 데이터 타입 간 사칙연산시 이진 데이터 타입은 숫자형 데이터 타입으로 변환할 수 없어 연산이 무효화된다.

iSQL> select empno + cast(12345 as nibble(6)) from emp;
[ERR-2100C : Conversion not applicable.
0001 : select EMPNO + CAST(12345 as NIBBLE(6)) from EMP
             ^                               ^
]

<질의> 함수 SUM에 문자형 데이터 타입 '10'을 인자로 받는 경우 숫자형 데이터로 변환된다.

iSQL> select sum('10') from dual;
SUM('10')
--------------
10
1 row selected.

<질의> 문자형 데이터 타입 '12.123456789'을 부동소수점 숫자형 데이터 타입인 float으로 변환하면, 유효 자릿수는 float(11)로 되어 값의 손실이 발생한다.

iSQL> select float'12.123456789' from dual;
FLOAT'12.123456789'
----------------------
12.1234568
1 row selected.

<질의> INSERT 되는 숫자형 데이터의 값은 INSERT 되는 칼럼의 데이터 유형에 맞게 변환되어 값이 INSERT 된다.

iSQL>  create table t1 ( i1 char(10), i2 integer, i3 double);
Create success.
iSQL>  insert into t1 values (integer'1020', char'1928', float'123.1234');
1 row inserted.
iSQL>     select * from t1;
I1          I2          I3
---------------------------------------------------
1020        1928        123.1234
1 row selected.

명시적 데이터 타입 변환#

명시적 데이터 타입 변환은 SQL 변환 함수 또는 아래와 같이 타입 캐스팅을 사용해서 명시적으로 수행될 수 있다. 데이터 타입을 변환하는 SQL 함수는 SQL Reference에서 설명한다.

구문#

datatype '문자 또는 상수 literal '

예제#

어떤 데이터 타입의 상수 데이터를 명시적으로 다른 데이터 타입으로 변환한다. 다음은 157.27의 숫자 값을 '157.27'의 문자열로 변환하는 예제이다.

CHAR '157.27'

문자열 표기#

SQL쿼리에서 문자열을 표기할 시에는 홀 따옴표(')로 문자열을 묶어서 사용한다. 홀 따옴표를 문자열로 표기할 시에는 홀 따옴표가 escape문자가 되므로 앞에 홀 따옴표를 붙여줘야 한다.

예제

SELECT * FROM EMPLOYEE WHERE NAME = 'KIM';
INSERT INTO EMPLOYEE VALUES ('GILDONG''');//GILDONG' 값을 삽입
SELECT * FROM REMOTE_TABLE(link1, 'SELECT * FROM EMPLOYEE WHERE NAME=''KIM'''; //''는  따옴표가 아니라  따옴표  개임

FIXED/VARIABLE 옵션#

FIXED와 VARIABLE은 칼럼의 데이터가 어느 영역에 저장될 지를 지정하는 키워드이다.

한 레코드 전체가 연속된 공간에 저장될 때, 이 공간을 고정(FIXED) 영역이라고 한다. 칼럼들 중의 하나가 그 레코드의 나머지 연속된 고정 영역이 아닌 다른 분리된 공간에 저장될 때, 이 칼럼은 가변(VARIABLE) 영역에 저장된다고 말한다.

한 칼럼이 가변 영역에 저장될 때, 데이터 길이와 실제 데이터가 저장된 위치를 가리키는 포인터 같은 그 칼럼의 헤더 정보는 고정 영역에 저장된다. 반면 칼럼의 데이터는 가변 영역에 저장된다.

디스크 테이블스페이스에 테이블 생성시, 사용자가 FIXED 또는 VARIABLE을 지정하더라도 이는 무시되고 테이블의 모든 칼럼은 FIXED로 처리된다. 그러나 메모리 테이블스페이스에 테이블을 생성할 때는 사용자가 명시한 옵션이 그대로 사용된다.

그러나, 모든 LOB 데이터 타입 칼럼의 데이터는 항상 VARIABLE로 처리되고, 그 데이터는 IN ROW 절에 지정된 값에 따라서 고정 또는 가변 영역에 저장될 수 있다.

다음의 데이터 타입에 대해 VARIABLE을 지정할 수 있다:

CHAR, VARCHAR, NCHAR, NVARCHAR, BYTE, VARBATE, NIBBLE, BIT, VARBIT

IN ROW 절#

이 절은 가변 영역에 저장되는 칼럼 데이터에만 관련이 있다. 테이블 생성시 FIXED와 IN ROW 절이 모두 명시되면, IN ROW 절은 무시된다. VARIABLE로 지정된 칼럼에 데이터가 입력될 때, 데이터의 길이가 IN ROW 절에 명시된 값 이하이면 데이터는 고정 영역에 저장될 것이다. 반면 데이터의 길이가 IN ROW 절에 명시된 값보다 크면, 데이터는 가변 영역에 저장될 것이다.

여기서 "데이터의 길이"는 입력된 데이터의 길이가 아니고, 메모리 또는 디스크에 실제로 저장될 데이터의 길이를 의미하는데, 이는 입력 데이터의 길이보다 다소 크다. 예를 들어, 칼럼이 'VARCHAR(400) IN ROW 200'으로 정의 되었다면, 입력 데이터의 길이가 198 (데이터 저장시 2바이트가 추가로 더 필요하다) 이하일 때 데이터는 고정 영역에 저장될 것이다.

고정 영역에 저장되는 LOB 데이터의 기본 크기는 메모리 테이블을 위한 MEMORY_LOB_COLUMN_IN_ROW_SIZE 프로퍼티와 디스크 테이블을 위한 DISK_LOB_COLUMN_IN_ROW_SIZE 프로퍼티를 사용해서 지정할 수 있다. 또한, VARIABLE 옵션이 지정된 다른 데이터 타입의 칼럼을 위한 기본 크기는 MEMORY_VARIABLE_COLUMN_IN_ROW_SIZE 프로퍼티를 사용해서 명시할 수 있다. 이들 프로퍼티를 지정하면 테이블 생성시 각 칼럼에 반복적으로 IN ROW 절을 사용할 필요가 없다.

이들 프로퍼티에 대한 상세한 설명은 2장. Altibase 프로퍼티를 참고하기 바란다.