5.데이터 타입 선정하기
데이터 타입을 선정할 때 참고할 가이드라인은 다음과 같음
1-1. 범위는 가능한 작게
사용하고자 하는 데이터가 가질 수 있는 값의 범위를 대략적으로 파악 후 해당 값의 범위를 수용할 수 있는 가장 적절한 타입을 선택하는 것이 권장됨
데이터 타입이 작을수록 디스크, 메모리, CPU 캐시의 공간을 덜 사용하기 때문에 더 빠른편
처음에 어떤 데이터 타입을 사용해야할지 애매할 경우, 한 사이즈 정도 크게 정해보는 것도 괜찮음
1-2. 특별한 케이스를 제외하고, 되도록 단순하게
일반적으로 실제 데이터의 값은 숫자인데 문자열 기반의 데이터 타입을 선택할 경우, 해당 컬럼을 값에 따라 정렬해야 하거나, 문자열 비교를 통해 값을 비교해야 하기 때문에 처리가 더 복잡해질 수 있음
따라서 예외적인 케이스를 제외하고는 숫자 값 데이터를 저장할 때는 문자열 대신 현재 사용 중인 DBMS에서 제공하는 기본 타입(ex. INT, NUMBER 등)을 사용하는 것을 권장
날짜와 시간의 경우에도 마찬가지로 기본 제공 타입인 datetime, timestamp 등 사용 권장
1-3. NULL보다는 기본 값으로
의도적으로 NULL을 저장하는 경우가 아니라면 대부분의 열은 NOT NULL로 지정하는 것을 권장
NULL은 인덱스 통계 정보 및 값 비교(ex. NULL != NULL)를 복잡하게 만들기 때문에 NULL이 허용되는 컬럼들은 최적화가 어려움
2. MySQL 데이터 타입 종류
2-1. 정수 - Numeric Data Types
정수형 데이터 타입의 종류는 아래와 같음 INTEGER, BIT, TINYINT(8bit), SMALLINT(16bit) MEDIUMINT(24bit), INT(32bit), BIGINT(64bit) 등도 제공
2-1-1. SIGNED, UNSIGNED 속성
정수형은 값을 저장할 수 있는 범위를 음수, 양수를 포함할 지에 따라 별도의 속성을 가지는데, 정수형의 기본 속성은 SIGNED로 값의 범위가 음수가 포함되는 설정을 가지고 있음
ex) TINYINT SIGNED 일 경우,
-128 ~ 127 사이의 값 저장 가능
반대로 UNSIGNED 속성은 음수 값을 허용하지 않고 양수 값을 허용 범위의 2배로 지정 가능
ex) TINYINT UNSIGNED일 경우,
0 ~ 255 사이의 값 저장 가능
INT(5)?
5의 의미는 데이터 값의 범위 제한이 아닌 MySQL Command Line Client 툴에서 해당 컬럼의 정수형 값을 표시할 때 나타낼 너비의 길이(length)를 말함
따라서 값을 저장, 계산하기 위한 목적에 있어서 INT(1)과 INT(10)은 차이가 없음
2-2. 실수 - Exact Value, Approximate Value
실수형의 경우에도 소수 부분의 값이 고정인지 부동인지에 따라 2가지로 구분됨
2-2-1. Fixed-Point Types (Exact Value, 정확한 값)
고정 소수점 타입, 정확한 값으로 실수 표현 ex) 1.5, 5(5.0), -2.1..
타입 종류 DECIMAL, NUMERIC
2-2-2. Floating-Point Types (Approximate Value, 근사값)
부동 소수점 타입, 가수부와 지수부로 실수 표현 ex) 1.26123e-1, 1.26123e0..
타입 종류 FLOAT, DOUBLE
소수점까지 근사값이 아닌 정확한 값을 저장할 때는 DECIMAL 사용 권장
2-3. 문자열 타입 - String
2-3-1. VARCHAR, CHAR
대표적인 두 가지 문자열 데이터 타입
대표적인 차이는 값을 저장할 수 있는 문자의 길이가 고정되어있는지 유동적으로 변할 수 있는지(가변)에 대한 차이
VARCHAR - 길이가 변할 수 있는 가변 길이 문자열 타입
CHAR - 길이가 고정된 고정 길이 문자열 타입
VARCHAR
가변 길이 문자열, 가장 일반적으로 자주 사용하는 문자열 데이터 타입 필요한 공간만큼만 값을 사용하기 때문에 고정 길이 문자열 타입인 CHAR보다 저장 공간이 덜 필요할 수 있음
차이는 저장되는 문자열 값의 길이에 따라 범위를 늘리거나 줄이기 위한 연산을 내부적으로 수행 후, 해당 값의 크기가 얼마인지에 대한 정보를 별도로 저장해두기 위한 공간을 위해 1~2바이트 정도의 추가 저장 공간이 필요
최대로 저장할 수 있는 길이 자체는 제한할 수 있지만, 해당 값의 범위보다 작은 값이 들어오면 그 크기만큼 저장 공간이 줄어들기 때문에 성능에 도움이 됨
일반적으로 UTF-8과 같은 복잡한 문자 인코딩을 사용할 때 사용
VARCHAR(N) 과 같이 N 부분에 문자열 값의 허용 길이를 정할 수 있는데, MySQL 4.1 버전 이전에는 N이 바이트 크기를 의미했으나, 그 이후 버전부터는 문자 수로 통합됨
UTF-8 기준 영문, 숫자, 기호 1글자는 1바이트 한글, 한자는 3바이트로 표현되었음
ex) VARCHAR(30)
한글 영문 관계 없이 30자 저장 가능
CREATE TABLE varchar_length_table( val VARCHAR(3));INSERT INTO varchar_length_table(val) VALUES ('결명자');
-- Query OK, 1 row affected (0.00 sec)
INSERT INTO varchar_length_table(val) VALUES ('ABC');
INSERT INTO varchar_length_table(val) VALUES ('페퍼민트');
-- Data too long for column 'val' at row 1
CHAR
저장 공간의 크기가 고정되어있기 때문에 실제로 저장되는 문자열 값의 크기가 얼마인지를 계산 후 별도로 저장할 공간이 필요하지 않음
저장되는 문자열의 길이가 확실하고, 보통 짧은 길이의 문자열을 저장할 때 사용
Y, N값만 보유할 수 있도록 설계 시 CHAR(1)로 사용할 수도 있음
길이가 10인 CHAR 타입 테이블 생성
CREATE TABLE char_table( char_column CHAR(10));INSERT INTO char_table(char_column) VALUES ('string1'), (' string2'), ('string3 ');뒷 부분은 공백이 제거되어서 조회됨
SELECT CONCAT("'", char_column, "'") FROM char_table;동일한 결과
SELECT char_column FROM char_table;길이가 10인 VARCHAR 타입 테이블 생성
CREATE TABLE varchar_table( varchar_column VARCHAR(10));
INSERT INTO varchar_table(varchar_column) VALUES ('string1'), (' string2'), ('string3 ');VARCHAR 타입은 뒷 부분도 공백이 제거되지 않고 조회됨
SELECT CONCAT("'", varchar_column, "'") FROM varchar_table;그 외 대용량 데이터를 바이너리 형태로 저장할 때 사용하는 BLOB
문자열 형태로 저장할 때 사용하는 TEXT 타입도 제공
2-4. 날짜, 시간 타입 - Date, Time
일반적으로 날짜만 저장할 때는 DATE 타입을 사용 시간만 저장할 때는 TIME 등
날짜와 시간 모두를 한 번에 저장할 때는 두 가지 타입을 제공
2-4-1. DATETIME
YYYYMMDDHHMMSS 패턴의 정수로 압축된 날짜와 시간을 저장, 8바이트 저장 공간 사용
ex) 2005-05-25 10:05:27, ANSI 표준 방식
2-4-2. TIMESTAMP
1970년 1월 1일 자정부터 지금까지 경과된 시간을 ms로 저장
해당 MySQL 서버를 사용하는 국가, 운영 체제, 서버 설정에 따라 표시되는 값과 시간대가 다름