[TIL - 1024] MySQL 데이터타입, 정규화(1)
MySQL
데이터 타입
- 성능을 위해서 꼭 맞는 데이터를 고르기 : 공간 낭비(읽어오는 시간, 공간까지도 낭비)
- 숫자
- unsigned : 양수(+)만
타입 | 크기 | 참고 |
---|---|---|
BIT(N) | 1 ~ 64bit까지 지정 | 크게 잡고 작은 수를 넣을 경우 0으로 채워짐 |
TINYINT | 1byte | |
SMALLINT | 2byte | |
INT | 4byte | |
BIGINT | 8byte | |
FLOAT | 4byte | |
DOUBLE | 8byte | |
DECIMAL | 지정 시 : (M, N), Mbyte(정확한 소수점을 저장할 때 사용) | M 길이로 N개 남은 수부터는 소수점으로, |
- 문자
타입 | 크기 | 참고 |
---|---|---|
CHAR(N) | Nbyte 고정 | 크기만큼의 데이터가 아니라면 공백으로 채움 |
VARCHAR(N) | 가변 길이 | 데이터 크기만큼 사용 |
TEXT | 최대 65535byte | TINY(255byte), MEDIUM(16777215byte), LONGTEXT(4294…..;;)도 있음 |
- 시간
타입 | 참고 |
---|---|
DATE | |
TIME | |
DATETIME | DATE + TIME |
YEAR | |
TIMESTAMP | 수정에 맞춰 자동으로 데이터 변경 |
- boolean 타입 저장하기 : tinyint(1) - 1비트로도 충분히 표현가능하지만 mysql에서는 1바이트를 요구
키 종류
- 슈퍼키 : 고유하게 식별되는 애트리뷰트 집합(후보키 + 일반 애트리뷰트 == 슈퍼키)
- 후보키 : 슈퍼키 부분 집합, 하나라도 제거되면 슈퍼키가 아닌 것(슈퍼키 - X == 일반키 라면 후보키)
- 여기서 하나를 선택해서 PK(기본키)로 사용함
- 여기서 하나를 선택하지않고 임의적으로 만든 키를 사용할 수 있음 : 인공키(아무런 의미없지만 식별가능하도록 유일하면서 NOT NULL인)
정규화
잘 설계된 테이블
- 다른 개체의 속성값을 가져오는 것은 FK를 통해 참조를 한다
- CRUD가 자유롭지 못함 - 디펜던시를 깊게 가져 코드 변경을 자유롭게 하지 못하는 코드와 같음
- 한 테이블에 서로 다른 정보를 저장하는 것은 좋지않음 : 역할에 따라 객체 분리하듯 데이터도 구분(관심사끼리 분리라는 표현을 쓰더라)되는 것끼리 따로 저장하는 것이 좋음
정규화
- 분해를 잘하는 것 : 문제점을 줄일 수 있도록 테이블을 설계
- 함수적 종속성 : 생각해본 내용을 옮기자면 X의 값으로 Y를 식별해낼 수는 있지만(함수적 종속성을 가짐), Y는 X를 식별해낼 수 없음(X가 무엇인지 결정할 수 없음)
- 한 쪽은 유일하고, 한 쪽은 같은 데이터가 있을 수도 있고 아닐 수도 있음
- 위의 상황을 X는 함수적으로 Y를 결정한다라고 함, Y가 달라지면 X는 무조건 달라짐
- 정규형 모델 : 조금 더 알아보자
- 1NF(1차 정규화 - 기본) : 테이블에는 키(PK)가 있어야함, 애트리뷰트는 원자성을 가져야함(주소와 같이 쪼갤 수 있는 애트리뷰트를 가지면 안됨, 하나의 로우에 여러 값을 저장X)
- 2NF
- 3NF
- BCNF
정규화의 한계
- 무조건적으로 정규형으로 맞출 수 없는 것이 실무에서는 FK JOIN으로 인한 성능 저하를 막고 한 번에 테이블의 값을 가져오기위해서 한 곳에 몰아서 데이터를 저장하기도 함
- 테이블의 한계를 자바 코드에 그대로 가져와서 고통을 받기보다 JPA를 사용하여 프로세스 메모리 상에서는 객체를 분리하여 사용할 것 : 한번 다뤘던 주제 - 블로그 다시 읽어보기