8. 테이블 설계의 기초
테이블의 개념과 정규형
- 테이블 설계
- 정규형
- 체크포인트
🧐 관계형 데이터베이스가 주류가 된 이유는 무엇일까?
❗️ Garbage in, Garbage out 이라는 말이 있듯이, 데이터베이스에서 데이터 저장은 매우 중요함
- 데이터베이스에서 데이터의 정합성은 매우 높은 단계로 요구됨
- 관계형 데이터베이스가 데이터의 정합성을 높이기 위한 설계 노하우가 매우 발달함
테이블 설계
테이블
- 데이터를 관리하는 그릇
- 열과 행으로 구성된 데이터 구조 (엑셀)
- 유니크한 기본키를 가지는 공통 속성을 가진 것의 집합
- 현실 세계의 개념이나 집합을 나타낸 것
서버나 스토리지 같은 물리층과 관계없이 독립적으로 작성하는 것이 가능해서 '논리 설계'라고도 부름
원칙
테이블이란 공통점을 가진 사물의 집합을 나타낸 것이다
테이블명은 반드시 복수형이나 집합명사로 표현해야 한다
테이블 설계의 어려움
인간의 자유로운 사고를 반영하기 때문에 테이블의 구성 패턴이 달라질 수 있다.
데이터 관리는 등록한 그 시점에만 정합성이 있어야 하는 것이 아닌 장기적으로 정합성을 얻는 노력을 해야 한다.
→ 데이터가 '정적'이지 않고 '동적'임을 전제로 생각해야 한다.
해결방법
도메인 주도 설계 DDD - 현실 세계와 관계형 모델의 세계를 잇는 다리 역할
속성이 필요한지 생각할 때 결정해야 할것 이름 : 데이터 = 도메인(데이터형- 속성이 취할 수 있는 값의 집합)
속성(칼럼)의 이름:
ID를 설계한다는 개념 = DB에 저장된 ID는 현실 세계의 물체나 개념
🔑 기본키
데이터를 고유하게 식별할 수 있는 것
데이터베이스 사용 여부와 관계없이 기본키 할당은 데이터 관리의 기본!
필수 요건
- 기본키는 한 개의 테이블에 반드시 한 개만 존재해야 함
- 기본키의 컬럼 명에 밑줄을 그어 표시하는 것이 일반적임
- 기본키 열에 NULL은 불가
- 변경 가능성이 있거나 중복될 수 있는 값이 있다면 불가
- 변경 후 값의 유일성을 보증할 수 없고 과거 데이터와의 매칭이 어려움
정규형
데이터의 갱신이 발생한 경우에도 부정합이 발생하기 어려운 테이블의 형태
→ 쉽게 말해서 데이터베이스의 중복을 없애는 작업
정규화 논리 - 함수 종속성
DB 설계 = DB에 포함된 모든 테이블이나 오브젝트의 설계라는 의미
정규화 = 관계형 모델을 보완하는 이론
변칙을 방지할 수 있다.
- 정규화 안된 db는 릴레이션의 설계가 상식적이지 않을 수 있다. ex) 학생과 수업의 이수관계를 나타내는 릴레이션에 학년이라는 속성이 포함된 것이 이상하다
변칙의 원인은 중복
중요 : BCNF, 5NF
제1정규형(1NF)
테이블이어야 할것
→ 칼럼이나 행의 순서가 없다 : ROWID나 ObjectID 같은 걸 쓰지말아야한다
→ 중복되는 행을 제거
→ NULL이 포함되면 안된다.
→ 값의 원자성
함수 종속성(FD) 2NF~BCNF 는 함수 종속성에 관한 정의
제2정규형(2NF)
후보키의 진부분집합에서 키가 아닌 속성에 함수 종속성을 제거하는 작업
제3정규형
보이스코드 정규형 (BCNF)
자명하지 않은 함수 종속성이 모두 제거된 상태
- 제1~5정규형까지 있지만 실무에서는 제3정규형까지 알면 충분하다.
결합 종속성 (JD)
4,5,6 정규형
릴레이션의 직교성 : 여러 개의 릴레이션 사이의 중복에 관한 개념
NULL과의 싸움
- 릴레이션에는 NULL 이라는 개념이 존재하지 않는다. (NULL 값은 비어)
- NULL은 관계형 모델에는 존재하지 않고 SQL의 테이블에만 존재한다. NULL을 가진 테이블은 1NF의 요건을 만족하지 않는다.
- NULL ≠ 공집합 (공집한은 요소가 0개인 실재하는 집합)
- SQL의 NULL은 C언어의 NULL 포인트와도 다르다.
- NULL은 값이 아니라서 값처럼 비교할 수 없다 (= 이 아닌 IS)
- NULL은 연산을 망친다. 검색 결과가 의도하지 않은 결과가 될 가능성
- NULL은 옵티마이저 구현에도 악영향이 있다. → 쿼리의 성능을 개선해도 결과가 다르면 의미가 없다.
NULL의 대책
- 테이블 정규화
- 잘못된 NULL 대책 - 특별한 값이 히트하지 않도록 주의 - 로컬 규칙은 테이블 정의에 보이지 않는다.
- NULL을 피하고자 편의상 NULL이 아닌 NULL과 같은 의미가 있는 기본값을 사용하는 것은 테이블 설계를 악화
- → COALESCE 함수: NVL의 확장, 인수 중에 가장 처음에 나오는 NULL이 아닌 것을 반환 - 다이나믹 SQL
체크포인트 (SQL 코딩의 기술 참조)
데이터 모델 설계
- 모든 테이블에 기본키가 있는지 확인하자
- 기본 키의 요건: 유일한 값, NOT NULL, 안정성(=갱신 불필요), 간단(ex. 정수)
- 기본 키는 비즈니스 로직과 독립적인 값을 사용해야 한다. (비즈니스 정책 변경으로인해 기본 키가 갱신되면 안 되기 때문)
- 중복으로 저장된 데이터 항목을 제거하자
- 반복 그룹을 제거하자 → 정규화
- 컬럼당 하나의 특성만 저장하자
- 원자성, 한 컬럼에 여러 특성 포함하면 검색이나 그루핑이 어려움
- 쿼리할 때 쪼개는 것은 어렵지만, 합치는 것은 쉽다! (주소, 전화번호 등)
- 왜 계산 데이터를 저장하면 좋지 않은지 이해하자 (정합성)
- 다른 테이블의 값으로 계산되는 컬럼이 있다면, 다른 테이블의 로우가 변경, 삽입, 삭제될 때마다 값을 재계산해야하므로, 부하가 걸릴뿐더러 데이터 무결성을 유지하기 어렵다
- 비결정적 함수일 경우에는 인덱스를 걸 수 없다
- 계산 컬럼 : 얻는 혜택 > 부하 비용 일 때만 사용
결정적 함수와 비결정적 함수
* 결정적(Deterministic) 함수 : 입력이 같으면 결과가 같은 함수
* 비결정적(Nondeterministic) 함수 : 입력이 같아도 매번 호출할 때마다 결과가 달라지는 함수. 인덱스 불가
- 테이블 간 관계를 명확히 하자
- 데이터 모델의 정확성 유무를 규정하는 것은 비즈니스 규칙이므로, 애플리케이션에 맞춰 데이터 모델을 설계해야 한다
- 테이블 A의 변경에 따른 테이블 B의 영향을 생각해서 설계한다
- 제3정규화로도 부족하다면 더 정규화하자
참고
https://www.sunny-son.space/MySQL/RDBMstart07/