0. 학습 목표
- 다양한 데이터 형식에 대해 이해
- 두 테이블을 연결하는 조인을 이해하고 활용
- SQL에서 일반 프로그래밍 기능을 구현
0. 요약
- 정수형은 소수점이 없는 숫자이며 TINYINT, SMALLINT, INT, BIGINT가 있음
- 문자형은 고정형 문자형인 CHAR과 가변형 문자형인 VARCHAR이 있음
- 실수형은 소수점 아래 7자리까지 표현되는 FLOAT와 15자리까지 표현되는 DOUBLE가 있음
- 날짜형은 날짜DATE, 시간TIME, 날짜시간DATETIME이 있음
- MySQL에서 제공되는 변수 앞에는 @를 붙임
- 데이터 형식을 변경하는 형 변환 함수에는 CAST(), CONVERT()가 있음
정수형
데이터 형식 | 바이트 수 | 숫자 범위 |
TINYINT | 1 | -128 ~ 127 |
SMALLINT | 2 | -32,768 ~ 32767 |
INT | 4 | 약 -21억 ~ +21억 |
BIGINT | 8 | 약 -900경 ~ +900경 |
문자형
데이터 형식 | 바이트 수 |
CHAR(개수) | 1 ~ 255 |
VARCHAR(개수) | 1 ~ 16383 |
대량의 데이터 형식
데이터 형식 | 바이트 수 | |
TEXT 형식 | TEXT | 1 ~ 65535 |
LONGTEXT | 1 ~ 4294967295 | |
BLOB 형식 | BLOB | 1 ~ 65535 |
LONGBLOB | 1 ~ 4294967295 |
실수형
데이터 형식 | 바이트 수 | 설명 |
FLOAT | 4 | 소수점 아래 7자리 |
DOUBLE | 8 | 소수점 아래 15자리 |
날짜형
데이터 형식 | 바이트 수 | 설명 |
DATE | 3 | 날짜만 저장 YYYY-MM-DD |
TIME | 3 | 시간만 저장 HH:MM:SS |
DATETIME | 8 | 날짜와 시간을 저장 YYYY-MM-DD HH:MM:SS |
1. MySQL의 데이터 형식
※핵심 키워드: 정수형, 문자형, 실수형, 날짜형, 변수, 형 변환
1-1. 데이터 형식
정수형
정수형은 소수점이 없는 숫자에서 사용되며 정수형의 크기와 범위는 아래와 같다.
데이터 형식 | 바이트 수 | 숫자 범위 |
TINYINT | 1 | -128 ~ 127 |
SMALLINT | 2 | -32,768 ~ 32767 |
INT | 4 | 약 -21억 ~ +21억 |
BIGINT | 8 | 약 -900경 ~ +900경 |
간략하게 테이블을 만들어서 확인 해 보자.
USE market_db;
CREATE TABLE hongong4 (
tinyint_col TINYINT,
smallint_col SMALLINT,
int_col INT,
bigint_col BIGINT );
각 열에 최대값을 입력해 보자.
INSERT INTO hongong4 VALUES (127, 32767, 2147483647, 9000000000000000000);
SELECT * FROM hongong4;
# tinyint_col, smallint_col, int_col, bigint_col
'127', '32767', '2147483647', '9000000000000000000'
추가적으로 최대값을 넘는 값을 입력해 보자 에러가 난다.
INSERT INTO hongong4 VALUES (128, 32768 2147483648, 90000000000000000000);
17:25:35 INSERT INTO hongong4 VALUES (200, 32768, 2147483648, 90000000000000000000) Error Code: 1264. Out of range value for column 'tinyint_col' at row 1 0.000 sec
지난번에 만들었던 member 회원 테이블의 예제를 살펴보자.
USE market_db --market_db를 선택
CREATE TABLE member -- 회원 테이블
( mem_id CHAR(8) NOT NULL PRIMARY KEY, -- 사용자 아이디(PK)
mem_name VARCHAR(10) NOT NULL, -- 이름
mem_number INT NOT NULL, -- 인원수
addr CHAR(2) NOT NULL, -- 지역(경기,서울,경남 식으로 2글자만입력)
phone1 CHAR(3), -- 연락처의 국번(02, 031, 055 등)
phone2 CHAR(8), -- 연락처의 나머지 전화번호(하이픈제외)
height SMALLINT, -- 평균 키
debut_date DATE -- 데뷔 일자
);
- 인원 수(mem_number)는 TINYINT(최대 127)로 지정해도 충분하다
- 평균 키(height)는 SMALLINT(최대 32767)로 지정해도 충분하다
-> SMALLINT보다는 UNSIGNED와 같이 값이 0으로 시작하는 TINYINT UNSIGNED를 사용하는 것이 더 효율적이다.
TINYINT(-128 ~ 128) TINYINT UNSIGNED(1 ~ 255)
USE market_db --market_db를 선택
CREATE TABLE member -- 회원 테이블
( mem_id CHAR(8) NOT NULL PRIMARY KEY, -- 사용자 아이디(PK)
mem_name VARCHAR(10) NOT NULL, -- 이름
mem_number TINYINT NOT NULL, -- 인원수
addr CHAR(2) NOT NULL, -- 지역(경기,서울,경남 식으로 2글자만입력)
phone1 CHAR(3), -- 연락처의 국번(02, 031, 055 등)
phone2 CHAR(8), -- 연락처의 나머지 전화번호(하이픈제외)
height TINYINT UNSIGNED, -- 평균 키
debut_date DATE -- 데뷔 일자
);
문자형
문자형은 글자를 저장하기 위해 사용되며 입력할 최대 글자의 개수를 지정해야 한다. 대표적인 문자형은 아래와 같다.
데이터 형식 | 바이트 수 |
CHAR(개수) | 1 ~ 255 |
VARCHAR(개수) | 1 ~ 16383 |
CHAR는 고정길이 문자열이라고 부른다. 즉 자리수가 고정되어 있다. VARCHAR은 가변길이 문자열이라고 부른다. 자리수가 가변적이다.
- CHAR(10)이라고 선언하면 10자리를 먼저 예약하고 3개의 글자만 저장되어도 10자리 모두를 사용한다.
- VARCHAR(10)이라고 선언하고 3개의 글자가 저장되면 3자리만 사용한다.
VARCHAR가 CHAR보다 공간은 효율적으로 사용할 수 있지만, 성능면에서는 CHAR로 설정하는 것이 좋다.
회원 테이블의 문자형을 살펴보자.
USE market_db --market_db를 선택
CREATE TABLE member -- 회원 테이블
( mem_id CHAR(8) NOT NULL PRIMARY KEY, -- 사용자 아이디(PK)
mem_name VARCHAR(10) NOT NULL, -- 이름
mem_number INT NOT NULL, -- 인원수
addr CHAR(2) NOT NULL, -- 지역(경기,서울,경남 식으로 2글자만입력)
phone1 CHAR(3), -- 연락처의 국번(02, 031, 055 등)
phone2 CHAR(8), -- 연락처의 나머지 전화번호(하이픈제외)
height SMALLINT, -- 평균 키
debut_date DATE -- 데뷔 일자
);
- mem_id: 최대 8글자 입력 가능, VARCHAR(8)로 변경해도 무관
- mem_name: 최대 10글자 입력 가능, 가변 길이로 하는 것이 효율적
- addr: 지역 번호로 2글자까지만 입력 가능, 정수형으로 사용하면 앞에 0이오면 사라지기 때문에 CHAR로 선언
- phone1, 2: 정수형으로 지정할 수 있으나, 더하기/빼기, 크다/작다, 순서 등의 연산이 없어 CHAR로 선언
대량의 데이터 형식
CHAR은 255, VARCHAR은 16383까지 지정 가능하다. 이것을 넘어서는 더 큰 데이터를 저장하려면 다음과 같은 형식을 사용한다.
데이터 형식 | 바이트 수 | |
TEXT 형식 | TEXT | 1 ~ 65535 |
LONGTEXT | 1 ~ 4294967295 | |
BLOB 형식 | BLOB | 1 ~ 65535 |
LONGBLOB | 1 ~ 4294967295 |
- TEXT, LONGTEXT: 소설이나 영화 대본과 같은 것을 저장한다면 필요한 데이터 형식
- BLOB(Binary Long Object), LONGBLOB: 사진이나 동영상 같은 것을 저장한다면 필요한 데이터 형식
예를 들어 넷플릭스와 같은 동영상 사이트라면 아래와 같이 만들 수 있다.
CREATE DATABASE netflix_db;
USE netflix_db;
CREATE TABLE moive
(movie_id INT,
movie_title VARCHAR(30),
movie_director VARCHAR(20),
movie_star VARCHAR(20),
movie_script LONGTEXT,
movie_film LONGBLOB
);
실수형
실수형은 소수점이 있는 숫자를 저장할 때 사용한다.
데이터 형식 | 바이트 수 | 설명 |
FLOAT | 4 | 소수점 아래 7자리 |
DOUBLE | 8 | 소수점 아래 15자리 |
과학 기술용 데이터가 아니라면 보통 FLOAT를 사용한다.
날짜형
날짜와 시간을 저장할때 사용한다.
데이터 형식 | 바이트 수 | 설명 |
DATE | 3 | 날짜만 저장 YYYY-MM-DD |
TIME | 3 | 시간만 저장 HH:MM:SS |
DATETIME | 8 | 날짜와 시간을 저장 YYYY-MM-DD HH:MM:SS |
주의할 점은 날짜와 시간을 입력할 때는 작은따옴표로 묶어줘야 한다.
1-2. 변수의 사용
변수의 선언과 값의 대입은 다음 형식을 따른다.
SET @변수이름 = 변수의 값;
SELECT @변수이름;
변수는 MySQL 워크벤치를 재시작할 때까지는 유지되지만 종료하면 없어진다. 즉 임시로 사용한다고 생각하면 된다.
USE market_db;
SET @myVar1 = 5;
SET @myVar2 = 4.25;
SELECT @myVar1;
SELECT @myVar1 + @myVar2;
SET @txt = '가수 이름==> ';
SET @height = 156;
SELECT @txt, mem_name FROM member WHERE height > @height;
# @myVar1
'5'
# @myVar1 + @myVar2
'9.250000000000000000000000000000'
# @txt, mem_name
'가수 이름==> ', '에이핑크'
'가수 이름==> ', '블랙핑크'
'가수 이름==> ', '소녀시대'
'가수 이름==> ', '잇지'
'가수 이름==> ', '마마무'
'가수 이름==> ', '오마이걸'
'가수 이름==> ', '레드벨벳'
'가수 이름==> ', '우주소녀'
'가수 이름==> ', '트와이스'
'가수 이름==> ', '여자친구'
위와 같이 3가지 결과 값을 얻을 수 있다.
하지만 LIMIT는 변수를 사용할 수 없다.
SET @count = 3;
SELECT mem_name, height FROM member ORDER BY height LIMIT @count;
19:53:14 SELECT mem_name, height FROM member ORDER BY height LIMIT @count Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@count' at line 1 0.000 sec
이를 해결하는 것이 PREPARE와 EXECUTE이다. PREPARE는 실행하지 않고 SQL문만 준비해 놓고 EXECUTE에서 실행하는 방식이다.
SET @count = 3;
PREPARE mySQL FROM 'SELECT mem_name, height FROM member ORDER BY height LIMIT ?';
EXECUTE mySQL USING @count;
# mem_name, height
'오마이걸', '160'
'레드벨벳', '161'
'우주소녀', '162'
1-3. 데이터 형 변환
문자를 정수로 바꾸거나 반대로 바꾸는 것을 데이터의 형 변환이라고 한다. 형 변환에는 직접 함수를 사용해서 변환하는 명시적인 변환과 별도의 지시없이 변환하는 암시적인 변환이 있다.
함수를 이용한 명시적인 변환
데이터 형식을 변환하는 함수는 CAST(), CONVERT()이다. 형식만 다를 뿐 동일한 기능을 한다.
CAST (값 AS 데이터형식 [ (길이) ] )
CONVERT (값, 데이터형식 [ (길이) ] )
market_db의 구매 테이블(buy)에서 평균 가격을 구하는 SQL을 확인하면 결과가 실수로 나온다.
SELECT AVG(price) AS '평균 가격' FROM buy;
# 평균 가격
'142.9167'
이를 CAST(), CONVERT()를 사용해서 정수로 변경할 수 있다. 이 두 함수에 올 수 잇는 데이터 형식은 CHAR, SIGNED(부호가 있는 정수), UNSIGNED(부호가 없는 정수), DATE, TIME, DATETIME등이다.
SELECT CAST(AVG(price) AS SIGNED) '평균 가격' FROM buy;
SELECT CONVERT(AVG(price), SIGNED) '평균 가격' FROM buy;
# 평균 가격
'143'
이번에는 날짜를 확인해 보자. 다양한 구분자를 날짜형으로 변경할 수 있다.
SELECT CAST('2022$12$12' AS DATE);
SELECT CAST('2022/12/12' AS DATE);
SELECT CAST('2022%12%12' AS DATE);
SELECT CAST('2022@12@12' AS DATE);
# CAST('2022$12$12' AS DATE)
'2022-12-12'
# CAST('2022/12/12' AS DATE)
'2022-12-12'
# CAST('2022%12%12' AS DATE)
'2022-12-12'
# CAST('2022@12@12' AS DATE)
'2022-12-12'
SQL의 결과를 원하는 형태로 표현하는 경우도 사용할 수 있다. 가격(price)과 수량(amount)을 곱한 실제 구매액을 표시하는 SQL을 아래와 같이 작성할 수도 있다.
SELECT num, CONCAT(CAST(price AS CHAR), 'X', CAST(amount AS CHAR), '=') '가격x수량', price*amount '구매액' FROM buy;
# num, 가격x수량, 구매액
'1', '30X2=', '60'
'2', '1000X1=', '1000'
'3', '200X1=', '200'
'4', '200X5=', '1000'
'5', '50X3=', '150'
'6', '80X10=', '800'
'7', '15X5=', '75'
'8', '15X2=', '30'
'9', '50X1=', '50'
'10', '30X1=', '30'
'11', '15X1=', '15'
'12', '30X4=', '120'
암시적인 변환
암시적인 변환은 위 함수를 사용하지 않고 자연스럽게 형이 변환되는 것을 의미한다.
예를 들어 문자 '100' + '200'을 실행하면 자동으로 숫자로 형을 변환하여 덧셈을 수행한다.
SELECT '100' + '200';
# '100' + '200'
'300'
문자로 연결하려면 CONCAT()을 사용한다.
SELECT CONCAT('100', '200');
# CONCAT('100', '200')
'100200'
위의 의미는 즉 상황에 따라 달라진다는 이야기 이다. CONCAT()을 사용하면 작은 따옴표가 없더라도 문자로 변환하여 연산하고, 일반적인 사항에서 작은따옴표로 문자 + 숫자를 하더라도 자동으로 숫자로 변환하여 연산한다.
SELECT CONCAT(100, '200');
# CONCAT(100, '200')
'100200'
SELECT 100 + '200';
# 100 + '200'
'300'
'혼자공부하는 SQL' 카테고리의 다른 글
4. SQL 고급 문법-3 (0) | 2022.01.29 |
---|---|
4. SQL 고급 문법-2 (0) | 2022.01.28 |
3. SQL 기본 문법-3 (0) | 2022.01.21 |
3. SQL 기본 문법-2 (0) | 2022.01.19 |
3. SQL 기본 문법-1 (0) | 2022.01.17 |