MySQL은 다양한 숫자 데이터 타입을 제공함.

0과 1로 이루어진 비트만을 저장함. 컴퓨터는 0과 1의 비트로 이루어져 있고 0과 1로 모든 값을 저장/처리 함.
비트는 컴퓨터가 데이터를 저장하는 기본단위라고 할 수 있음.
BIT(M)에서 M은 몇 비트를 쓸지를 의미. 1이 기본 값이고 64까지 가능.
ex) M = 4 이면, 0000, 0001, 0010 이런식으로 4개의 값을 담게 됨
매우 작은 정수를 담을 때 사용.
기존 INT 타입에 비해 작은 저장공간을 차지함.
8비트까지 사용할 수 있고 범위는 -127 ~ 127 또는 0 ~ 255.
참/거짓을 담기 위해 사용.
BOOL은 TINYINT(1)와 같음. 이 값이 0이면 False, 1이면 True.
대략 6만개의 정수를 표현할 수 있는 정수 데이터 타입.
16비트까지 사용 가능.
대략 1670만개의 정수를 표현할 수 있음.
24비트까지 사용 가능.
일반적으로 사용하는 정수를 표현할 수 있음.
32비트까지 사용 가능하며 약 42억 9천만 정수를 표현할 수 있음.
INT 타입보다 2배 많은 비트를 사용.
BIGINT 중 부호가 없는 걸 SERIAL이라고 부름.
고정 소수점 타입.
M은 숫자 전체 자리 수, D는 소수점 이하 자리 수
소수점 이하 자리 수를 미리 고정하고 고정된 자리 수로만 소수점을 표현함.
부동 소수점 타입.
4 바이트, 즉 32비트 사용.
FLOAT보다 더 큰 부동 소수점 타입.
8 바이트, 즉 64 비트 사용.
현업에서는 디테일하게 나누어서 사용하지는 않음.
BOOLEAN, INT, DOUBLE을 자주 사용.
(실습)
1. 우선, IF문 활용해서 숫자와 TRUE, FALSE 간의 관계를 확인해봄.

0은 FALSE로 간주되기 때문에 FALSE가 반환됨.
1이면 TRUE로 간주되기 때문에 TRUE가 반환됨. 1 아닌 다른 수 넣어도 참으로 간주해서 TRUE가 반환(음수 넣어도 동일).
조건이 2=TRUE이면 2=1이라고 쓴 것과 동치이기 때문에 FALSE 반환.
2.기존에 실습했던 products 테이블에서 price는 원래 INT 타입이었으나 이번에는 TINYINT로 바꿔서 해봄

이렇게 작성하면 오류남. price에 들어간 값들이 양수라 하더라도 범위가 255까지인데 그걸 넘기 때문.
따라서 넣어주는 값을 조정하면 스키마 빌드 에러 x


고정된 길이의 문자열.
선언된 길이보다 짧은 문자열이 들어와도 빈 문자열로 남은 문자열 채움.
변동 가능한 길이의 문자열.
길이 0 ~ 65,535 바이트
이는 MySQL에서 한 행이 가질 수 있는 총 길이와 동일. 다른 컬럼들의 데이터도 저장하려면 한 컬럼이 한 행이 쓸 수 있는 전체 공간을 다 쓰면 안됨.
➡️ 따라서 실제로는 65,535 바이트보다 짧은 문자열이 담겨야 함.
VARCHAR은 데이터가 몇 바이트짜리인지 정보를 담는데 추가적인 바이트를 사용
➡️ 문자열 크기가 255 바이트 이하이면 1바이트 사용, 더 크면 2바이트 사용.
DB마다 다르지만 길이를 초과하는 문자열이 들어오면 일반적으로는 INSERT시 에러가 발생.
변동 가능한 길이의 문자열.
VARCHAR과 다르게 길이 지정 불가능. 최대 길이만 안넘으면 문자열 길이에 상관없이 집어넣는 방식.
쿼리 시 메모리가 아니라 디스크를 사용
➡️ 따라서 CHAR, VARCHAR(메모리 사용)보다 쿼리문 반환이 느림.
TEXT이지만 더 짧은 TEXT 저장.
최대 255 바이트까지 저장 가능.
제한된 값 리스트를 미리 작성하고 그 안에 있는 값만 삽입할 수 있도록 하는 타입(컬럼 타입을 지정할 때부터 들어갈 수 있는 값 리스트를 지정).
없는 값을 테이블에 INSERT 하면 에러 발생(DB설정마다 다르지만 없는 값 넣으면 빈 값 들어가는 경우도 존재).
ENUM은 훨씬 적은 저장소 용량으로 동일한 데이터를 저장할 수 있다는 장점이 있음
ex - 만약 강아지, 고양이, 원숭이 이렇게 3가지 값만 가지는 컬럼이 있다고 할 때, 데이터가 테이블에 들어오면 실제 문자열을 저장하는게 아니라 해당 값에 매핑되는 더 짧은 문자열을 저장(강아지는 0, 고양이는 1, 원숭이는 2 이런식!)
현업에서 사용할 수 있는 경우는 많지 않음(유연성과 확장성이 낮기 때문. 데이터에 변동이 있으면 대응하기가 어려움).
ENUM과 비슷하게 처음 가능한 값 리스트를 제한함. 그러나 ENUM과 다르게 0개 혹은 여러개의 값이 올 수 있음.
ex - 만약 강아지, 고양이, 원숭이 값으로 제한했을 때 빈 문자열이 들어와도 괜찮고 강아지,고양이가 들어와도 괜찮고 고양이, 원숭이도 괜찮음
즉, 가능한 값 리스트의 모든 조합이 올 수 있음(순서는 무시).
(실습)
1. name 컬럼값을 4글자로 제한해보기

2.공백이 저장되는지 확인해보기

공백이 저장되는 것을 확인할 수 있음. 지정된 타입길이 이내이면 공백도 같이 저장됨.
한글은 한글자에 3바이트, 영문은 1바이트 차지. 따라서 한글 두글자에 공백하면 7바이트가 됨.

이진 데이터 타입과 문자 데이터 타입을 나누어서 설명하지만 MySQL 공식 문서에서는 묶어서 설명하고 있음.
ex) BLOB과 TEXT를 같이 설명함(그만큼 비슷해서)
Binary 파일은 데이터를 저장하거나 활용하기 위해 0과 1의 이진 형식으로 인코딩해둔 파일을 의미.
근본적으로는 0과 1로 이루어진 데이터이지만 이진형식을 표시할 때 16진법으로 표시하기도 함. 즉, binary 타입은 다른 데이터 타입을 포함하는 개념.
ex) TEXT 파일은 binary 파일에 포함되지만 binary 파일이라고 꼭 TEXT 파일인 것은 아님. 이미지일수도 있고 숫자일수도 있음.
문자열 뿐만 아니라 데이터 무엇이든 집어넣는 타입.
TEXT와 마찬가지로 최대 길이는 65,535로 기본값은 지정할 수 없음.
BINARY와 VARBINARY는 CHAR과 VARCHAR의 binary 버전.
저장되는 형태와 길이 설정 방식이 다름.
변동 가능한 길이
VARBINARY와 BLOB의 관계는 VARCHAR과 TEXT의 관계랑 비슷함.
(실습)
1. name 컬럼 타입을 binary(6)으로 설정해보면, 에러가 나게 됨.
왜? 괄호 안은 글자수가 아니라 바이트를 의미하기 때문.


2.CAST함수를 써서 name컬럼을 binary에서 char 형태로 바꿀 수 있음.
SELECT CAST(name as char) as str_name
FROM products
배열은 array라고 하며 데이터가 저장된 리스트.
ex) ['a', 'b', 'c'] , [1, 2, 3]
배열에 저장된 각 데이터를 element라고 하며 원소라고 부름.
MySQL에서는 컬럼에 배열 데이터를 저장할 수 있는데, 이 때 JSON 타입을 사용. 이 경우를 JSON ARRAY라고 부름.
JSON 타입으로 저장할 수 있는 데이터 형태가 다양하기 때문에 기본값 설정은 불가능.
입력을 JSON 배열로 반환하는 함수
INSERT, SELECT 구문에서 주로 사용
예시를 보면 options 컬럼을 JSON 타입으로 지정. INSERT 구문을 보면 JSON ARRAY 함수에 배열의 원소가 될 값들을 넣어주었음.

JSON ARRAY 안쓰고 다른 방식으로 배열 데이터 넣을 수도 있음
➡️ 직접 '["빨강", "파랑"]' 으로 넣어주는 방식
INSERT INTO 'products' ('product_id', 'category', 'name', 'price', 'options') VALUES
(0, '키즈', '어린이칫솔 ', 1500, '["빨강", "파랑"]'),
(1, '스포츠', '손목보호대', 10000, '["S", "M", "L"]'),
(2, '주방용품', '밥그릇', 2000, '["소", "중", "대"]'),
(3, '디지털', '마우스', 15000, NULL);
(실습)
배열안에 원소에 배열이 들어가는 경우 ➡️ Nested Array
CREATE TABLE IF NOT EXISTS 'products' (
'product_id' int unsigned NOT NULL,
'category' varchar(40) NOT NULL,
'name' varchar(10) NOT NULL,
'price' int unsigned NOT NULL,
'options' JSON NULL,
PRIMARY KEY ('product_id')
);
INSERT INTO 'products' ('product_id', 'category', 'name', 'price', 'options') VALUES
(0, '키즈', '어린이칫솔 ', 1500, JSON_ARRAY("빨강", "파랑")),
(1, '스포츠', '손목보호대', 10000, JSON_ARRAY("S", "M", "L")),
(2, '주방용품', '밥그릇', 2000, JSON_ARRAY("소", "중", "대")),
(3, '디지털', '마우스', 15000, JSON_ARRAY(JSON_ARRAY("흰색", "파랑"), JSON_ARRAY("초록", "보라"), JSON_ARRAY("갈색", "검정")));
JSON 데이터 타입을 반환하는 함수
위의 실습을 JSON TYPE을 써서 확인해보기

array 내부의 데이터에 접근할 수 있음.
배열 내부의 데이터에 인덱스를 통해 접근하는 것을 인덱싱이라고 함.
첫번째 예시는 JSON 타입의 options 컬럼에서 모든 값을 꺼내오는 예시
SELECT options, JSON_EXTRACT(options, '$') AS all_elements
FROM products

두번째 예시는 원하는 인덱스의 값만 꺼내오는 예시
SELECT options, JSON_EXTRACT(options, '$[0]') AS idx_elements
FROM products
key-value 데이터는 key와 value로 이루어진 데이터를 의미.
ex) {'이름' : '홍길동', '부서' : '개발팀', '직책' : '팀장', '근무지' : '판교'}
key는 데이터를 찾을 수 있는 기준이 되는 값, value는 key에 대응되는 값.
예시에서 이름은 key값, 홍길동은 value값.
MySQL에서는 key-value도 JSON 타입으로 저장하고 관리함.
key-value 입력값을 JSON 객체로 반환하는 함수
array에서 JSON ARRAY 사용한거와 유사하게 사용.
주로 INSERT, SELECT 구문에서 사용함.
JSON_OBJECT 입력시에는 key, value 순으로 입력
ex) JSON_OBJECT(키1, 값1, 키2, 값2, ...)
(실습)

array에서 인덱싱 할 때는 $[인덱스] 해서 사용
key-value에서 JSON EXTRACT 써서 값 가져올 때는 $.key이름 하면 해당 키 값에 해당하는 value값 가져옴.
(실습)
위 예시에서 키 값이 off에 대응하는 value값을 불러옴.

결과값이 array인데, 여기에 대해서 인덱싱 가능.
SELECT JSON_EXTRACT(info, '$.off[0]') as off_idx
FROM managers_v2

(실습)
managers_v2 테이블에서 info 컬럼에 새로운 key-value 삽입
UPDATE managers_v2 SET info = JSON_INSERT(info, '$.education_time', JSON_ARRAY(5, 10))

(실습)
새로운 key인 education_time에 대응하는 value값들을 update 함.
UPDATE managers_v2 SET info = JSON_REPLACE(info, '$.education_time', JSON_ARRAY(0, 10))

마지막으로, key에 대응되는 value로 array뿐만 아니라 key-value가 올 수도 있음(key-value에서 value에 해당되는 부분에 또 다른 key-value가 오는 형태).

여기서 JSON_EXTRACT를 적용하면 안쪽 key에 대응되는 value값 추출 가능.
