Notes
DB 02. 관계 모델과 무결성
관계 데이터 모델의 기본 개념, 릴레이션의 특성, 키의 종류, 무결성 제약조건을 정리한 데이터베이스 학습 노트
- Published
- Updated
- Area
- Databases
- Type
- concept
- Series
- Database Systems
- Category
- Notes
개요
관계 데이터 모델은 데이터를 relation, 즉 2차원 테이블의 형태로 표현하는 데이터 모델이다. 핵심은 데이터를 복잡한 pointer나 link 구조로 연결하지 않고, key 값의 일치를 통해 논리적으로 연결한다는 점이다.
이 글은 관계 데이터 모델의 기본 용어, relation의 특성, key의 종류, 그리고 데이터 일관성을 유지하기 위한 integrity constraint를 정리한다.
1. 관계 데이터 모델의 기본 관점
관계 데이터 모델은 IBM 연구소의 E. F. Codd가 1970년에 제안한 모델이다. 이후 IBM의 System R 같은 관계 DBMS 시제품을 통해 실제 DBMS 구현의 기반이 되었다.
관계 데이터 모델이 널리 사용되는 이유는 다음과 같다.
- 데이터를 단순한 table 구조로 표현한다.
- 중첩된 복잡한 구조가 없다.
- 집합 중심으로 데이터를 처리한다.
- 이론적 기반이 잘 정립되어 있다.
- declarative query language, 특히 SQL과 잘 맞는다.
- 사용자는 원하는 데이터가 무엇인지, 즉
what만 명시하면 된다. - 데이터를 어떻게 찾을지, 즉
how는 DBMS가 처리한다.
예를 들어 다음 SQL은 부서번호가 3인 사원의 이름을 조회한다.
SELECT EMPNAME
FROM EMPLOYEE
WHERE DNO = 3;
사용자는 “부서번호가 3인 사원의 이름”이라는 결과만 명시한다. DBMS가 table scan을 할지, index를 사용할지, 어떤 실행 계획을 사용할지는 사용자가 직접 지정하지 않는다.
2. link나 pointer가 아니라 foreign key로 연결한다
관계 데이터 모델의 중요한 특징은 다음 문장으로 요약된다.
논리적으로 연관된 데이터를 연결하기 위해 link나 pointer를 사용하지 않는다.
관계형 데이터베이스에서는 table과 table을 물리적 pointer로 연결하지 않는다. 대신 primary key와 foreign key의 값 일치를 통해 연결한다.
예를 들어 다음 두 relation을 보자.
DEPARTMENT(DEPTNO, DEPTNAME, FLOOR)
EMPLOYEE(EMPNO, EMPNAME, TITLE, DNO, SALARY)
DEPARTMENT.DEPTNO가 부서 relation의 primary key이고, EMPLOYEE.DNO가 이를 참조한다면 다음 관계가 성립한다.
EMPLOYEE.DNO → DEPARTMENT.DEPTNO
예시는 다음과 같다.
DEPARTMENT
DEPTNO | DEPTNAME | FLOOR
1 | 영업 | 8
2 | 기획 | 10
3 | 개발 | 9
EMPLOYEE
EMPNO | EMPNAME | DNO
2106 | 김창섭 | 2
3426 | 박영권 | 3
3011 | 이수민 | 1
EMPLOYEE.DNO = 2라는 값은 DEPARTMENT.DEPTNO = 2인 tuple을 참조한다. 이때 실제 메모리 주소나 물리적 pointer를 저장하는 것이 아니라, 같은 domain의 값을 이용해 관계를 표현한다.
3. 기본 용어
관계 데이터 모델의 주요 용어는 다음과 같다.
| 용어 | 의미 | 일반적 표현 |
|---|---|---|
| relation | 2차원 table | table |
| tuple | relation의 한 행 | row, record |
| attribute | relation의 한 열 | column, field |
| domain | attribute가 가질 수 있는 값들의 집합 | data type + 의미적 범위 |
| degree | relation의 attribute 수 | column count |
| cardinality | relation의 tuple 수 | row count |
3.1 Relation
relation은 2차원 table이다.
EMPLOYEE
EMPNO | EMPNAME | TITLE | DNO | SALARY
2106 | 김창섭 | 대리 | 2 | 2000000
3426 | 박영권 | 과장 | 3 | 2500000
3011 | 이수민 | 부장 | 1 | 3000000
3.2 Tuple
tuple은 relation의 한 행이다.
(2106, 김창섭, 대리, 2, 2000000)
실무에서는 record 또는 row라고도 부른다.
3.3 Attribute
attribute는 relation의 열이다.
EMPNO, EMPNAME, TITLE, DNO, SALARY
각 attribute는 이름을 가지며, 해당 열의 의미를 나타낸다.
4. Domain
domain은 한 attribute에 나타날 수 있는 값들의 집합이다. 프로그래밍 언어의 data type과 비슷하지만, 단순한 자료형보다 의미적 제약을 더 포함한다.
예를 들어 DNO와 SALARY가 모두 integer일 수는 있지만, 둘의 domain은 다르다.
DNO : 부서번호 domain
SALARY : 급여 domain
따라서 domain은 다음 요소를 함께 고려한다.
- 값의 자료형
- 가능한 값의 범위
- 값의 의미
- 업무 규칙상 허용되는 값
예를 들어 EMPNAME domain은 다음처럼 이해할 수 있다.
EMPNAME domain = EMPNAME에 나타날 수 있는 모든 사원 이름의 집합
관계 데이터 모델에서는 attribute 값이 atomic value여야 한다. 즉, 한 칸에 여러 값을 넣는 multi-valued attribute는 허용되지 않는다.
잘못된 예시는 다음과 같다.
PHONE
010-1111-1111, 010-2222-2222
올바른 방식은 값을 분리하여 별도 relation으로 표현하는 것이다.
EMPLOYEE
EMPNO | EMPNAME
2106 | 김창섭
EMPLOYEE_PHONE
EMPNO | PHONE
2106 | 010-1111-1111
2106 | 010-2222-2222
5. Degree와 Cardinality
degree는 한 relation에 포함된 attribute의 수이다.
EMPLOYEE(EMPNO, EMPNAME, TITLE, DNO, SALARY)
위 relation의 degree는 5이다.
cardinality는 relation에 포함된 tuple의 수이다. 예를 들어 EMPLOYEE에 4명의 사원이 저장되어 있다면 cardinality는 4이다.
| 구분 | 의미 | 변화 가능성 |
|---|---|---|
| degree | attribute 수 | schema 변경 없이는 잘 변하지 않음 |
| cardinality | tuple 수 | insert/delete에 따라 자주 변함 |
6. Null value
NULL은 값이 0이거나 빈 문자열이라는 뜻이 아니다. NULL은 다음과 같은 상태를 표현한다.
- 알려지지 않음
- 아직 결정되지 않음
- 적용할 수 없음
- 값이 없음
예를 들어 신입 사원의 부서가 아직 결정되지 않았다면 DNO에 NULL이 들어갈 수 있다.
EMPNO | EMPNAME | DNO
5001 | 홍길동 | NULL
주의할 점은 NULL, 0, ''는 서로 다르다는 것이다.
| 값 | 의미 |
|---|---|
0 | 숫자 값 0이 존재함 |
'' | 빈 문자열 값이 존재함 |
NULL | 값이 없거나 알려지지 않음 |
SQL에서 NULL 여부를 검사할 때는 =가 아니라 IS NULL을 사용한다.
SELECT *
FROM EMPLOYEE
WHERE DNO IS NULL;
7. Relation schema와 Relation instance
7.1 Relation schema
relation schema는 relation의 구조를 의미한다.
EMPLOYEE(EMPNO, EMPNAME, TITLE, DNO, SALARY)
relation schema는 relation의 이름과 attribute들의 집합으로 구성된다. 기본 키 attribute는 보통 밑줄로 표시한다.
relation schema는 intension이라고도 한다. 이는 실제 데이터 값이 아니라 데이터의 구조와 의미를 나타낸다.
7.2 Relation instance
relation instance는 특정 시점에 relation에 들어 있는 tuple들의 집합이다.
2106 | 김창섭 | 대리 | 2 | 2000000
3426 | 박영권 | 과장 | 3 | 2500000
3011 | 이수민 | 부장 | 1 | 3000000
relation instance는 extension이라고도 한다. instance는 insert, delete, update에 따라 계속 변한다.
| 구분 | 의미 | 예 |
|---|---|---|
| schema | relation의 구조 | EMPLOYEE(EMPNO, EMPNAME, TITLE, DNO, SALARY) |
| instance | 현재 저장된 tuple들의 집합 | 현재 EMPLOYEE table의 실제 행들 |
8. Relational database schema와 instance
하나의 database는 여러 relation으로 구성된다.
DEPARTMENT(DEPTNO, DEPTNAME, FLOOR)
EMPLOYEE(EMPNO, EMPNAME, TITLE, DNO, SALARY)
이처럼 하나 이상의 relation schema들의 모임을 relational database schema라고 한다.
반대로 각 relation에 실제로 저장된 tuple들의 모임을 relational database instance라고 한다.
9. Relation의 특성
relation은 단순한 표가 아니라 몇 가지 논리적 특성을 만족해야 한다.
| 특성 | 설명 |
|---|---|
| 하나의 record type만 포함 | 한 relation에는 같은 종류의 tuple만 저장 |
| attribute 값의 type 일관성 | 한 attribute 내 값들은 같은 domain에 속해야 함 |
| attribute 순서 무관 | column 위치보다 attribute 이름이 중요 |
| 동일 tuple 중복 불가 | relation은 tuple들의 set이므로 중복 tuple 불가 |
| atomic value | 한 tuple의 각 attribute는 하나의 원자값을 가져야 함 |
| attribute 이름은 relation 내에서 고유 | 같은 relation 안에서 attribute 이름 중복 불가 |
| tuple 순서 무관 | row의 저장 순서는 논리적 의미를 갖지 않음 |
9.1 하나의 relation에는 하나의 record type만 포함된다
EMPLOYEE relation에는 사원 정보만 저장해야 한다. 여기에 부서 정보, 과목 정보, 주문 정보가 섞이면 relation의 의미가 깨진다.
잘못된 예시는 다음과 같다.
EMPLOYEE
EMPNO | EMPNAME | TITLE | DNO | SALARY
2106 | 김창섭 | 대리 | 2 | 2000000
1 | 영업부 | 8층 | |
두 번째 tuple은 사원 정보가 아니라 부서 정보이므로 같은 relation에 들어가면 안 된다.
9.2 한 attribute 내 값들은 같은 domain에 속해야 한다
FLOOR attribute에는 층 정보를 나타내는 값만 들어가야 한다.
DEPARTMENT
DEPTNO | DEPTNAME | FLOOR
1 | 영업 | 8
2 | 기획 | 10
3 | 개발 | 9
다음처럼 숫자, 문자열, 여러 값이 섞이면 domain 일관성이 깨진다.
DEPARTMENT
DEPTNO | DEPTNAME | FLOOR
1 | 영업 | 8
2 | 기획 | 본관
3 | 개발 | 9, 10
9.3 Attribute 순서는 중요하지 않다
다음 두 relation은 attribute 순서만 다를 뿐 같은 의미의 정보를 담고 있다.
DEPARTMENT(DEPTNO, DEPTNAME, FLOOR)
DEPARTMENT(FLOOR, DEPTNO, DEPTNAME)
중요한 것은 column의 위치가 아니라 attribute 이름이다.
9.4 동일한 tuple은 두 개 이상 존재할 수 없다
relation은 tuple들의 set이므로 완전히 동일한 tuple이 중복될 수 없다.
DEPARTMENT
DEPTNO | DEPTNAME | FLOOR
1 | 영업 | 8
1 | 영업 | 8
위 예시는 동일 tuple이 중복되므로 relation의 특성에 어긋난다.
이 특성은 key의 필요성과 연결된다. 각 tuple은 다른 tuple과 구별될 수 있어야 하며, 이를 위해 key가 필요하다.
9.5 각 attribute 값은 atomic value여야 한다
한 칸에 여러 값을 넣으면 안 된다.
잘못된 예시는 다음과 같다.
EMPLOYEE
EMPNO | EMPNAME | PHONE
2106 | 김창섭 | 010-1111-1111, 010-2222-2222
이 경우 전화번호를 별도 relation으로 분리해야 한다.
EMPLOYEE_PHONE
EMPNO | PHONE
2106 | 010-1111-1111
2106 | 010-2222-2222
이 조건은 나중에 배우는 First Normal Form, 즉 1NF와도 연결된다.
9.6 Tuple 순서는 중요하지 않다
relation은 tuple들의 set이므로 row 순서에 논리적 의미가 없다. 원하는 순서가 있다면 반드시 ORDER BY를 사용해야 한다.
SELECT *
FROM DEPARTMENT
ORDER BY DEPTNO;
10. Key의 종류
key는 relation 안의 tuple을 고유하게 식별하기 위한 attribute 또는 attribute들의 집합이다.
| key | 정의 | 핵심 기준 |
|---|---|---|
| superkey | tuple을 고유하게 식별할 수 있는 attribute 집합 | uniqueness |
| candidate key | 최소성을 만족하는 superkey | uniqueness + minimality |
| primary key | 후보 키 중 대표로 선택한 key | 대표 식별자 |
| alternate key | primary key로 선택되지 않은 candidate key | 대체 식별자 |
| foreign key | 다른 relation의 primary key를 참조하는 attribute | relation 간 연결 |
11. Superkey
superkey는 relation 내의 tuple을 고유하게 식별할 수 있는 하나 이상의 attribute 집합이다.
예를 들어 고객 relation이 다음과 같다고 하자.
CUSTOMER(CARDNO, SSN, NAME, ADDRESS)
만약 CARDNO와 SSN이 각각 고객을 고유하게 식별할 수 있다면 다음은 모두 superkey가 될 수 있다.
CARDNO
SSN
CARDNO + ADDRESS
SSN + NAME
주의할 점은 superkey가 불필요한 attribute를 포함할 수 있다는 것이다. CARDNO만으로 이미 고객을 식별할 수 있다면 CARDNO + ADDRESS에서 ADDRESS는 고유 식별에 꼭 필요하지 않다.
12. Candidate key
candidate key는 tuple을 고유하게 식별하는 최소한의 attribute 집합이다.
candidate key가 되려면 다음 두 조건을 만족해야 한다.
| 조건 | 의미 |
|---|---|
| uniqueness | 각 tuple을 고유하게 식별할 수 있어야 함 |
| minimality | 불필요한 attribute를 포함하지 않아야 함 |
예를 들어 CARDNO만으로 고객을 식별할 수 있다면 CARDNO는 candidate key이다. 하지만 CARDNO + ADDRESS는 superkey일 수는 있어도 candidate key는 아니다. ADDRESS가 없어도 식별이 가능하기 때문이다.
13. Composite key
candidate key가 두 개 이상의 attribute로 구성될 수 있다. 이런 key를 composite key라고 한다.
수강 relation을 예로 들 수 있다.
ENROLL
STUDENT_ID | COURSE_ID | GRADE
11002 | CS310 | A0
11002 | CS313 | B+
24036 | CS345 | B0
24036 | CS310 | A+
STUDENT_ID만으로는 tuple을 식별할 수 없다. 한 학생이 여러 과목을 수강할 수 있기 때문이다.
COURSE_ID만으로도 tuple을 식별할 수 없다. 한 과목을 여러 학생이 수강할 수 있기 때문이다.
따라서 다음 조합이 candidate key가 된다.
(STUDENT_ID, COURSE_ID)
14. Primary key와 Alternate key
한 relation에 candidate key가 두 개 이상 있을 수 있다. 이 중 설계자 또는 DBA가 대표 식별자로 선택한 key가 primary key이다.
예를 들어 고객 relation에서 CARDNO와 SSN이 모두 candidate key라면 둘 중 하나를 primary key로 선택할 수 있다.
primary key : CARDNO
alternate key: SSN
alternate key는 primary key로 선택되지 않은 candidate key이다.
primary key는 다음 조건을 만족해야 한다.
- 중복될 수 없다.
NULL이 될 수 없다.- tuple을 대표적으로 식별한다.
자연스러운 primary key를 찾기 어렵다면 인위적인 key attribute를 추가할 수 있다. 예를 들어 USER_ID, ORDER_ID, BOARD_ID 같은 surrogate key를 사용할 수 있다.
USER
USER_ID | NAME | EMAIL
1 | 김민수 | a@example.com
2 | 김민수 | b@example.com
15. Foreign key
foreign key는 어떤 relation의 primary key를 참조하는 attribute이다. relation 사이의 관계를 표현하기 위해 사용된다.
EMPLOYEE.DNO → DEPARTMENT.DEPTNO
여기서 EMPLOYEE.DNO는 foreign key이고, DEPARTMENT.DEPTNO는 참조되는 primary key이다.
중요한 점은 foreign key와 참조 대상 primary key의 이름이 같을 필요는 없다는 것이다.
EMPLOYEE.DNO
DEPARTMENT.DEPTNO
이름은 다르지만 둘 다 부서번호라는 같은 domain을 가지므로 foreign key 관계가 성립할 수 있다.
반대로 이름이 같아도 의미와 domain이 다르면 foreign key로 부적절할 수 있다.
EMPLOYEE.ID → DEPARTMENT.ID
두 attribute 이름이 모두 ID이더라도 하나는 사원 ID, 다른 하나는 부서 ID라면 같은 domain이 아니다.
16. Foreign key의 유형
16.1 다른 relation의 primary key를 참조하는 foreign key
가장 일반적인 형태이다.
EMPLOYEE.DNO → DEPARTMENT.DEPTNO
EMPLOYEE가 DEPARTMENT를 참조하여 사원이 소속된 부서를 표현한다.
16.2 자기 relation의 primary key를 참조하는 foreign key
같은 relation 안에서 다른 tuple을 참조하는 경우이다.
EMPLOYEE
EMPNO | EMPNAME | MANAGER | DNO
2106 | 김창섭 | 3426 | 2
3426 | 박영권 | 3011 | 3
3011 | 이수민 | NULL | 1
여기서 MANAGER는 같은 EMPLOYEE relation의 EMPNO를 참조한다.
EMPLOYEE.MANAGER → EMPLOYEE.EMPNO
이 구조는 조직도, category tree, 댓글과 대댓글 구조 등에 사용할 수 있다.
16.3 Primary key의 구성요소가 되는 foreign key
다대다 관계를 표현하는 중간 relation에서 자주 나타난다.
STUDENT(STUDENT_ID, NAME)
COURSE(COURSE_ID, COURSE_NAME)
ENROLL(STUDENT_ID, COURSE_ID, GRADE)
ENROLL.STUDENT_ID는 STUDENT.STUDENT_ID를 참조하고, ENROLL.COURSE_ID는 COURSE.COURSE_ID를 참조한다.
ENROLL.STUDENT_ID → STUDENT.STUDENT_ID
ENROLL.COURSE_ID → COURSE.COURSE_ID
동시에 ENROLL의 primary key는 다음과 같다.
(STUDENT_ID, COURSE_ID)
즉, 두 attribute는 각각 foreign key이면서 동시에 composite primary key의 구성요소이다.
17. Key 포함 관계
key의 포함 관계는 다음처럼 정리할 수 있다.
superkey
└─ candidate key
├─ primary key
└─ alternate key
정확히 말하면 candidate key는 superkey 중 minimality를 만족하는 key이고, primary key와 alternate key는 candidate key 중에서 역할에 따라 나뉜다.
18. Data integrity
data integrity는 데이터의 정확성과 유효성을 의미한다. 데이터베이스가 일관된 상태를 유지하도록 정의한 규칙이 integrity constraint이다.
DBMS는 insert, delete, update가 발생할 때 integrity constraint를 검사한다. 따라서 application code가 모든 일관성 검사를 직접 구현하지 않아도 된다.
대표적인 integrity constraint는 다음과 같다.
| 제약조건 | 의미 |
|---|---|
| domain constraint | attribute 값이 domain에 속해야 함 |
| key constraint | key 값이 중복되면 안 됨 |
| entity integrity constraint | primary key는 NULL이 될 수 없음 |
| referential integrity constraint | foreign key는 참조 대상 primary key와 일관되어야 함 |
19. Domain constraint
domain constraint는 attribute 값이 정해진 domain을 벗어나지 않도록 제한한다.
예를 들어 나이가 18 이상이어야 한다면 다음처럼 CHECK를 사용할 수 있다.
CREATE TABLE Persons (
ID int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int CHECK (Age >= 18)
);
여러 attribute에 걸친 constraint도 지정할 수 있다.
CREATE TABLE Persons (
ID int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int,
City varchar(255),
CONSTRAINT CHK_Person CHECK (Age >= 18 AND City = 'Sandnes')
);
DBMS별 CHECK, CREATE DOMAIN 지원 방식은 다를 수 있으므로 실제 사용 시에는 사용 중인 DBMS 버전에서 확인이 필요하다.
20. Key constraint
key constraint는 key attribute에 중복된 값이 존재하지 못하게 하는 제약조건이다.
CREATE TABLE Persons (
ID int NOT NULL UNIQUE,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int
);
여러 attribute의 조합에 대해 UNIQUE를 지정할 수도 있다.
CREATE TABLE Persons (
ID int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int,
CONSTRAINT UC_Person UNIQUE (ID, LastName)
);
이 경우 ID 단독이 아니라 (ID, LastName) 조합이 중복되면 안 된다.
21. Entity integrity constraint
entity integrity constraint는 primary key를 구성하는 어떤 attribute도 NULL이 될 수 없다는 제약조건이다.
primary key는 tuple을 식별하는 기준이므로 값이 없으면 tuple을 고유하게 식별할 수 없다.
잘못된 예시는 다음과 같다.
EMPLOYEE
EMPNO | EMPNAME
NULL | 김창섭
2106 | 박영권
EMPNO가 primary key라면 NULL을 허용할 수 없다.
primary key의 핵심 조건은 다음과 같다.
| 조건 | 의미 |
|---|---|
| unique | 중복 불가 |
| not null | NULL 불가 |
22. Referential integrity constraint
referential integrity constraint는 foreign key와 참조 대상 primary key 사이의 일관성을 유지하는 제약조건이다.
예를 들어 다음 관계가 있다고 하자.
EMPLOYEE.DNO → DEPARTMENT.DEPTNO
이 경우 EMPLOYEE.DNO 값은 다음 중 하나여야 한다.
DEPARTMENT.DEPTNO에 실제로 존재하는 값NULL
단, foreign key가 자신이 속한 relation의 primary key 구성요소라면 NULL이 될 수 없다. primary key의 일부는 entity integrity constraint 때문에 NULL을 허용하지 않기 때문이다.
예를 들어 EMPLOYEE.DNO가 일반 foreign key라면 NULL이 가능할 수 있다.
EMPNO | EMPNAME | DNO
5001 | 홍길동 | NULL
하지만 ENROLL(STUDENT_ID, COURSE_ID, GRADE)에서 (STUDENT_ID, COURSE_ID)가 primary key라면 다음은 불가능하다.
STUDENT_ID | COURSE_ID | GRADE
11002 | NULL | A0
23. Foreign key SQL 예시
foreign key는 다음처럼 선언할 수 있다.
CREATE TABLE EMPLOYEE (
EMPNO int primary key,
EMPNAME varchar(100),
DNO int,
CONSTRAINT EMPLOYEE_DNO_FK
FOREIGN KEY (DNO) REFERENCES DEPARTMENT(DEPTNO)
);
이 선언은 다음을 의미한다.
EMPNO는EMPLOYEE의 primary key이다.DNO는DEPARTMENT.DEPTNO를 참조하는 foreign key이다.EMPLOYEE.DNO값은DEPARTMENT.DEPTNO에 존재해야 한다.DNO가NULL을 허용하는지는 column 정의에 따라 달라진다.
24. Integrity constraint의 유지
데이터베이스 갱신 연산은 크게 세 가지이다.
| 연산 | 의미 |
|---|---|
| insert | tuple 삽입 |
| delete | tuple 삭제 |
| update | attribute 값 수정 |
DBMS는 각 갱신 연산에 대해 integrity constraint가 위배되지 않도록 필요한 조치를 취한다.
다음 관계를 기준으로 설명할 수 있다.
EMPLOYEE.DNO → DEPARTMENT.DEPTNO
여기서 DEPARTMENT는 참조되는 relation이고, EMPLOYEE는 참조하는 relation이다.
| 역할 | relation | 설명 |
|---|---|---|
| referenced relation | DEPARTMENT | primary key가 참조됨 |
| referencing relation | EMPLOYEE | foreign key를 가짐 |
25. Insert 시 제약조건
25.1 참조되는 relation에 insert
DEPARTMENT에 새 부서를 삽입하는 것은 일반적으로 referential integrity를 위배하지 않는다.
DEPARTMENT에 (4, 홍보, 8) 삽입
새로운 참조 대상이 생기는 것이므로 기존 EMPLOYEE의 foreign key 관계가 깨지지 않는다.
다만 다음 제약조건은 여전히 검사해야 한다.
- domain constraint
- key constraint
- entity integrity constraint
예를 들어 이미 DEPTNO = 3이 있는데 또 DEPTNO = 3을 삽입하면 key constraint 위반이다.
25.2 참조하는 relation에 insert
EMPLOYEE에 새 사원을 삽입할 때는 referential integrity를 위반할 수 있다.
EMPLOYEE에 (4325, 오혜원, 6) 삽입
만약 DEPARTMENT에 DEPTNO = 6이 없다면 이 insert는 거절되어야 한다.
EMPLOYEE.DNO = 6
하지만 DEPARTMENT.DEPTNO = 6 없음
26. Delete 시 제약조건
26.1 참조하는 relation에서 delete
EMPLOYEE tuple을 삭제하는 것은 일반적으로 referential integrity를 위반하지 않는다. 참조하던 tuple이 사라질 뿐이므로 참조 대상인 DEPARTMENT에는 문제가 생기지 않는다.
26.2 참조되는 relation에서 delete
문제는 DEPARTMENT tuple을 삭제할 때 발생할 수 있다.
예를 들어 DEPARTMENT에서 3번 부서를 삭제한다고 하자.
DEPARTMENT
DEPTNO | DEPTNAME
3 | 개발
그런데 EMPLOYEE에 DNO = 3인 사원이 있다면 문제가 된다.
EMPLOYEE
EMPNO | EMPNAME | DNO
3426 | 박영권 | 3
3427 | 최종철 | 3
이 상태에서 3번 부서를 삭제하면 두 사원은 존재하지 않는 부서를 참조하게 된다. 따라서 referential integrity가 깨진다.
27. Referential action 옵션
참조 대상 tuple을 delete할 때 DBMS는 여러 옵션을 제공할 수 있다.
| 옵션 | 의미 |
|---|---|
NO ACTION / RESTRICT | 참조 중이면 delete 거절 |
CASCADE | 참조하는 tuple도 함께 delete |
SET NULL | foreign key 값을 NULL로 변경 |
SET DEFAULT | foreign key 값을 default value로 변경 |
27.1 NO ACTION 또는 RESTRICT
위배를 야기하는 delete를 단순히 거절한다.
DEPARTMENT에서 DEPTNO = 3 삭제 시도
→ EMPLOYEE에서 DNO = 3인 tuple 존재
→ 삭제 거절
27.2 CASCADE
참조 대상 tuple을 삭제하면서 이를 참조하는 tuple도 함께 삭제한다.
DEPARTMENT.DEPTNO = 3 삭제
→ EMPLOYEE.DNO = 3인 tuple들도 함께 삭제
CASCADE는 강력하지만 실수로 많은 데이터를 삭제할 수 있으므로 주의가 필요하다.
27.3 SET NULL
참조 대상 tuple을 삭제하고, 이를 참조하던 foreign key 값을 NULL로 바꾼다.
DEPARTMENT.DEPTNO = 3 삭제
→ EMPLOYEE.DNO = 3이던 값들을 NULL로 변경
단, foreign key column이 NOT NULL이면 사용할 수 없다.
27.4 SET DEFAULT
참조 대상 tuple을 삭제하고, 이를 참조하던 foreign key 값을 default value로 바꾼다.
CREATE TABLE EMPLOYEE (
EMPNO int primary key,
EMPNAME varchar(100),
DNO int DEFAULT 1,
CONSTRAINT EMPLOYEE_DNO_FK
FOREIGN KEY (DNO) REFERENCES DEPARTMENT(DEPTNO)
ON DELETE SET DEFAULT
);
위 예시에서는 참조 대상 부서가 삭제될 때 DNO가 default value인 1로 바뀐다.
28. Update 시 제약조건
UPDATE는 수정 대상 attribute가 무엇인지에 따라 영향이 달라진다.
| 수정 대상 | referential integrity 영향 |
|---|---|
| 일반 attribute | 보통 영향 없음 |
| foreign key | 참조 대상 존재 여부를 다시 검사해야 함 |
| primary key | 이를 참조하는 foreign key들이 영향을 받을 수 있음 |
28.1 일반 attribute 수정
사원의 급여나 이름을 수정하는 것은 보통 참조 무결성에 영향을 주지 않는다.
UPDATE EMPLOYEE
SET SALARY = 3000000
WHERE EMPNO = 2106;
28.2 Foreign key 수정
사원의 부서번호를 존재하지 않는 부서번호로 수정하면 referential integrity 위반이다.
UPDATE EMPLOYEE
SET DNO = 6
WHERE EMPNO = 2106;
DEPARTMENT.DEPTNO = 6이 없다면 이 update는 거절되어야 한다.
28.3 Primary key 수정
참조되는 relation의 primary key를 수정하는 것은 delete 후 insert와 유사하게 볼 수 있다.
UPDATE DEPARTMENT
SET DEPTNO = 30
WHERE DEPTNO = 3;
이때 EMPLOYEE.DNO = 3인 tuple들이 존재한다면 참조 관계가 깨질 수 있다.
일부 DBMS는 ON UPDATE CASCADE 같은 옵션을 지원하지만, DBMS별 지원 방식은 확인 필요하다. 실무적으로 primary key는 한 번 정해지면 변경하지 않는 방향으로 설계하는 것이 안전하다.
29. 자칫 실수하기 쉬운 부분
29.1 Foreign key와 primary key의 이름이 같아야 한다는 오해
foreign key와 참조 대상 primary key의 이름은 같을 필요가 없다.
EMPLOYEE.DNO → DEPARTMENT.DEPTNO
중요한 것은 이름이 아니라 같은 domain을 가지는지, 그리고 참조 대상 값이 실제로 존재하는지이다.
29.2 Superkey와 candidate key 혼동
superkey는 불필요한 attribute를 포함할 수 있다.
CARDNO + ADDRESS
하지만 candidate key는 minimality를 만족해야 한다.
CARDNO
29.3 Primary key와 alternate key 혼동
candidate key 중 선택된 하나가 primary key이고, 선택되지 않은 candidate key가 alternate key이다.
candidate key: CARDNO, SSN
primary key : CARDNO
alternate key: SSN
29.4 NULL과 0 또는 빈 문자열 혼동
NULL은 값이 없는 상태이다. 0이나 ''와 다르다.
WHERE DNO IS NULL
29.5 Tuple 순서에 의존하는 설계
relation은 tuple들의 set이므로 tuple 순서에는 논리적 의미가 없다. 정렬이 필요하면 ORDER BY를 사용해야 한다.
30. 핵심 요약
관계 데이터 모델은 데이터를 relation으로 표현한다. relation은 tuple들의 set이고, 각 tuple은 attribute 값들로 구성된다.
관계 데이터 모델의 핵심 연결 방식은 pointer가 아니라 key 값의 일치이다.
EMPLOYEE.DNO → DEPARTMENT.DEPTNO
key의 종류는 다음과 같이 구분한다.
| key | 핵심 |
|---|---|
| superkey | 고유 식별 가능 |
| candidate key | 고유 식별 + 최소성 |
| primary key | candidate key 중 대표 |
| alternate key | primary key가 아닌 candidate key |
| foreign key | 다른 relation의 primary key 참조 |
integrity constraint는 데이터의 정확성과 일관성을 유지하기 위한 규칙이다.
| constraint | 핵심 |
|---|---|
| domain constraint | 값의 domain 제한 |
| key constraint | key 중복 방지 |
| entity integrity | primary key의 NULL 금지 |
| referential integrity | foreign key와 참조 대상 primary key의 일관성 유지 |
결론적으로 관계형 데이터베이스는 table 형태의 단순한 구조를 사용하지만, 그 내부에는 key와 integrity constraint를 통해 데이터의 식별성, 연결성, 일관성을 유지하는 엄격한 규칙이 존재한다.