안녕하세요. SQLER의 코난 김대우입니다.
이번 강좌에서는, 6-1. 데이터 무결성 - 데이터 무결성 이해를 진행 하겠습니다.
SQLER에서 진행되는, 챗GPT와 함께 배우는 SQL Server 강좌 목록
이번에 진행할 강좌는 데이터 무결성 이해입니다.
TL;DR
데이터 무결성은 관계형 데이터베이스에서 중요한 개념으로, 데이터 값이 정확한 상태를 유지하는 것을 의미합니다. 제약 조건을 통해 이를 보장하며, 여러 무결성 조건으로 상태를 유지합니다.
처음 관계형 데이터베이스를 경험하면서 많이 어려운 부분이죠. 데이터 무결성! 기본 키 제약과 함께 외래 키 제약(Foreign Key)이 어쩌면 데이터베이스가 어려운 이유 Top3 정도는 될 겁니다.
실제 여러 가지 제약들 중 몇 가지는 실무에서 아주 요긴하게 잘 사용됩니다. 정확한 개념만 이해하면 SQL 쿼리 구문은 아주 쉽게 진행하실 거에요. 그럼 시작하겠습니다.
데이터 무결성 종류
데이터 무결성은 네 가지 종류가 있습니다.
- 도메인 무결성(Domain Integrity)
- 엔티티 무결성(Entity Integrity)
- 참조 무결성(Referential Integrity)
- 사용자 정의 무결성(User Define Integrity)
아마도 생소한 단어일 겁니다. 각각 어떤 녀석들인지 같이 보시죠.
제약 이름
|
종류 |
CHECK, RULE, DEFAULT | 도메인 무결성(Domain Integrity) |
Primary Key, Unique Index | 엔티티 무결성(Entity Integrity) |
Foreign Key | 참조 무결성(Referential Integrity) |
Trigger, User Defined Data Type | 사용자 정의 무결성(User Define Integrity) |
이렇게 무결성을 제약으로 풀어서 보면 조금 이해가 쉽습니다.
데이터 무결성 정의
정의 먼저 살펴보겠습니다. 데이터 무결성이란 무엇인가요?
데이터베이스에 저장된 모든 데이터 값이 정확한 상태(State)를 의미. |
조금 바꿔 표현하면, 정확하지 않은 데이터 값이 데이터베이스에 저장된 것을, 데이터 무결성이 위배되었다고 표현합니다. 뻔한 이야기지만, 이런 무결성 기능이 우리가 관계형 데이터베이스를 선택하는 중요한 선택지가 되고, 50년 가까이 데이터 저장소로 사랑받는 이유입니다.
당연히 DB에는 정확한 값(Value)(?)이 들어가지 않나요?
라고 반문하실 수 있습니다. 문제는 현실의 규칙을 관계형 데이터베이스 시스템에 이식할 때 발생합니다.
간단한 예를 들어 보면,
회사에 부장, 과장, 대리, 사원의 직급이 있다고 생각해 보세요. 이럴 경우 회사의 직원은 당연히 부장, 과장, 대리, 사원의 직함을 가진 사람입니다. 그런데, 분명히 우리 회사 사람인데 직급이 주임이라는 존재하지 않는 직급으로 되어 있다면? 우리 회사 사람 맞긴 맞는데, 인사부의 실수로 인해 주임이라는 직급으로 잘 못 입력되는 경우가 발생할 수 있습니다.
데이터를 삽입하는 일을 수행하는 오퍼레이터의 실수, 무엇보다도 사람인 이상 실수는 생길 수밖에 없습니다.
이런 경우 “무결성이 위배되었다”라고 하며 잘못된 값이 입력된 것입니다. 이런 현실의 문제를 시스템으로 어떻게 막을 수 있을까요? 이런 문제들을 해결하기 위해 데이터 무결성 기능이 제공되고, 거의 모든 관계형 데이터베이스 엔진에서 잘못된 값이 삽입될 경우 에러를 발생시키고 처리를 롤백합니다. 무결성을 조금 아시는 분은 “참조 무결성”을 생각하면서 미소를 띠고 계실 겁니다.
도메인 무결성과 엔티티 무결성 차이
그렇다면 도메인 무결성과 엔티티 무결성은 어떤 차이가 있나요? 도메인 무결성은 컬럼에 묶여서 실행되며, 엔티티무결성은 로우에 묶여 실행됩니다.
이미지 - 도메인 무결성과 엔티티 무결성
1. 엔티티 무결성(Entity Integrity)
엔티티 무결성은 “로우(행)로 데이터를 구분”합니다. 당연히 DB에서 로우로 데이터를 구분하지, 뭘로 데이터를 구분합니까? 간단히 아래와 같은 데이터를 생각해 보겠습니다.
제품명
|
가격 |
초코파이 | 1200 |
칸쵸 | 800 |
칸쵸 | 800 |
예를 들어, 누군가의 실수로 이렇게 데이터가 입력되었다고 가정합니다. 데이터를 보면 “칸쵸 - 800원” 두 개의 로우는 전혀 구분을 할 수 없습니다.(물론, 우리 개발자의 시각으로 보면 TOP 1 구문이나 SET ROWCOUMT, 커서 등으로 로우의 서수(ordinal number) 단위 구분은 가능합니다.)
쿼리로 원하는 로우 데이터를 필터링해 가져오려면 어떻게 하나요? 네 맞습니다. 바로 WHERE절을 사용해 구분합니다. 하지만 위의 칸쵸 - 800원 로우들은 구분이 불가합니다. 정확히 중복 데이터입니다. 억지로 중복 데이터를 넣을 경우도 있겠지만 사실 이럴 경우 하나의 컬럼을 더 사용하여 로우(행) 단위 구분을 하는 게 효과적인 방법입니다.
제품 번호
|
product_name | price |
1 | 초코파이 | 1200 |
2 | 칸쵸 | 800 |
3 | 칸쵸 | 800 |
이렇게 제품 번호 컬럼을 추가하면 로우를 식별할 수 있습니다.
근본적으로 구분이 불가능한 데이터가 들어올 경우 제약으로 막을 수는 없을까?라는 의문이 생깁니다. 이런 제약이 엔티티 무결성이며 UNIQUE 제약이나 기본키(PRIMARY KEY) 제약으로 개별 로우 구분 제약을 만들 수 있습니다. 이제 ‘로우 단위 구분자”가 조금 감이 잡힐 거에요.
2. 도메인 무결성(Domain Integrity)
도메인 무결성은 컬럼(열)에 적용됩니다. 데이터 형식으로 입력되는 데이터의 유형을 제한하거나, CHECK 제약 및 RULE을 이용해 입력값을 제한할 수도 있고, DEFAULT 제약과 NULL값 제약으로 입력 가능한 값의 범위를 제한할 수도 있습니다.
예를 들어, 2015년부터 5자리로 변경된 우편번호를 입력받아야 하는데, 6자리 우편번호로 입력이 들어오거나, 문자가 들어오면 데이터 형식이나 유형을 체크해 오류를 발생시켜야겠죠. 이렇게 컬럼의 값을 검사하는 제약이 도메인 무결성입니다.
3. 참조 무결성(Referential Integrity)
참조 무결성을 공부하기 전에 예제 먼저 살펴보겠습니다.
직급 테이블
직급코드
|
직급명 |
1 | 과장 |
2 | 대리 |
3 | 사원 |
사원 테이블
사원ID
|
사원명 | 직급코드 |
konan | 김대우 | 3 |
psj | 박서준 | 1 |
ktr | 김태리 | 2 |
사원 테이블의 직급코드는 직급 테이블의 직급코드를 바라보고(참조하고) 있습니다.
만약 사원테이블에 직급코드가 존재하지 않는 “4”로 값이 들어간다면 참조하는 값이 없으니 에러가 생겨야만 데이터의 무결성이 위배되지 않습니다.
부장이라는 직급이 새롭게 추가된다면, 먼저 직급 테이블에 4 - 부장 값을 추가한 후 사원 테이블에 직급코드가 4 - 부장인 직원 정보를 추가하면 문제없이 삽입이 됩니다.
이렇게 사원테이블의 직급 코드처럼 값을 다른 테이블로부터 참조하는 제약을 “외래 키 제약(Foreign Key Constraint)”이라고 부르며, 관계형 데이터베이스에서는 이런 제약을 “참조 무결성 제약”이라고 합니다. 프로젝트에서는 거의 모든 테이블이 이렇게 관계로 이어져 있습니다. 중요한 내용이니 꼭 이해하고 넘어가세요.
4. 사용자 정의 무결성(User Define Integrity)
사용자 정의 무결성은 사용자 정의 데이터형(User Defined Data Type), 트리거(Trigger)와 같이 사용자가 특수한 방식으로 데이터 무결성을 유지하기 위해 생성하는 제약입니다.
이렇게 네 가지 데이터 무결성을 살펴보았습니다. 여러 무결성 제약 중, 참조 무결성 제약은 현업에서 거의 모든 테이블에 사용되고, 테이블 간 관계 정립에 필수적으로 사용되는 중요한 제약이니 꼭 이해하고 진행하세요.
SQL 강좌 책 구매
강좌가 도움이 되셨다면, 책으로 구매 가능합니다. 책 판매 수익금은 전액 코딩 교육 사회공헌 활동에 기부되며, 아래 링크에서 구매하시면 더 많은 금액이 기부됩니다.