상세 컨텐츠

본문 제목

Oracle - 정규화 과정

IT/DBMS

by TMI1 2025. 7. 8. 16:39

본문

--○ 정규화란? 
--   한 마디로 데이터베이스 서버의 메모리 낭비를 막기 위해
--   어떤 하나의 테이블을... 식별자를 가지는 여러 개의 테이블로
--   나누는 과정을 말한다. 


--○ 제 1 정규화
-->  어떤 하나의 테이블에 반복되어 나오는 컬럼 값들이 존재한다면
--   갑들이 반복되어 나오는 컬럼을 분리하여
--   새로운 테이블을 만들어 준다. 
--   아래와 같이 나누어준 형태가 제 1 정규화

-->  제 1 정규화를 수행하는 과정에서 분리된 테이블은
--   반드시 부모 테이블과 자식 테이블의 관계를 갖게 된다. 

-->  제 1 정규화를 수행하는 과정에서 
--   부모 테이블의 PRIMARY KEY 는
--   항상 자식 테이블의 FOREIGN KEY 로 전이된다.
--   부모 테이블 → 참조받는 컬럼 → PRIMARY KEY(제약조건)
--   그것이 바로 회사아이디 
--   자식 테이블 → 참조하는 컬럼 → FOREIGN KEY(제약조건)

-->  참조받는 컬럼이 갖는 특징(부모 테이블)
--   - 반드시 고유한 값(데이터)이 들어와야 한다.
--   - 즉, 중복된 값(데이터)이 없어야 한다.
--   - NULL 이어서는 안된다.(비어있어서는 안된다.)
--     즉, NOT NULL 이어야 한다. 

-->  참조하는 컬럼이 갖는 특징(자식 테이블)
--   - 부모 테이블의 참조받는 컬럼이 갖는 데이터들 중 
--     하나인 데이터를 참조해야 한다. 
--   EX) 채원이 회사코드가 50이면 어느회사다니는지 찾을 수 없음

--   PRIMARY KEY - 고유한 값 
--   제약조건(단, 이렇게 해야해 라는 강제사항) 

-- ** 테이블을 나누고 중복되는 테이블 제거 그리고 식별자 생성 
-- 테이블명 : 회사 → 부모테이블
/*

--※ 테이블이 분할(분리)되기 이전 상태로 조회

SELECT A.거래처회사명, A.회사주소, A. 회사전화
,   B.거래처직원명,  B.직급,  B.이메일, B.휴대폰
FROM 회사 A, 직원 B
WHERE A.회사아이디= B.회사아이디;
--> 원래의 상태로 조회하는데 이상 없음~!!!

--※ 하나의 테이블에 존재하는 PRIMARYKEY의 최대 갯수는 1개이다.
--   하지만,PRIMARY KEY 를 이루는(구성하는) 컬럼의 갯수는
--   복수(다수, 여러개)인 것이 가능하다.
--   컬럼 1개로만(단일 컬럼) 구성된 PRIMARY KEY를
--   Single PRIMARY KEY 라고 부른다.
--   (→ 단일 프라이머리 키)
--   두 개 이상의 컬럼으로 구성된 PRIMARY KEY를
--   Composite Primary key 라고 부른다.
--   (→ 복합 프라이머리 키)

--○ 제 2 정규화
--> 제 1정규화를 마친 결과물에서 PRIMARY KEY가 SINGLE COLUMN 이라면
--  제 2 정규화는 수행하지 않는다.
--  하지만, PRIMARY KEY 가 COMPOSITE COLUMN 이라면
--  반드시 제 2 정규화를 수행해야 한다.

--> 식별자가 아닌 컬럼은 식별자 전체 컬럼에 대해 의존적이어야 하는데
--  식별자 전체 컬럼이 아닌 일부 식별자 컬럼에 대해서만 의존적이라면
-- 이를 분리하여 새로운 테이블을 생성해 준다. >> 이것이 제 2정규화 

--○ 제 3 정규화
-->  식별자가 아닌 컬럼이 식별자가 아닌 컬럼에 의존적인 상황이라면
--   이를 분리하여 새로운 테이블을 생성해 주어야 한다. 

--※ 관계(Relation)의 종류 

-- 1 : 1 (=일대일)
--> 물리적으로 존재할 수 있는 관계이긴 하지만
--  피할 수 있으면 가급적이면 피해야 할 관계.

-- 1 : 다(many) (=일대다) 
--> 제 1 정규화를 마친 결과물에서 대표적으로 나타나는 바람직한 관계.
--  관계형 데이터베이스를 활용하는 과정에서 추구해야 하는 관계.

-- 다(many) : 다(many) (=다대다)
--> 논리적인 모델링에서는 존재할 수 있지만
--  실제 물리적인 모델링에서는 존재할 수 없는 관계.

--○ 제 4 정규화
--> 위에서 확인한 내용과 같이 『다:다』 관계를 『1:다』 관계로 깨뜨리는 과정이
--  제 4 정규화의 수행과정이다.
--  → 일반적으로 파생 테이블 생성 
--      → 『다:다』 관계를 『1:다』 관계로 깨뜨리는 역할을 수행하게 된다.

-- 정규화의 방향 →
-- 역정규화(비정규화)의 방향 ← 

--○ 역정규화(비정규화, 반정규화) 
/*
A 의 경우 → 역정규화를 수행하지 않는 것이 바람직한 상황~!!!

사이즈는 10BYTE라고 가정하자

테이블명 : 부서               테이블명 : 사원
    10      10    10            10      10  10    10   10       10           10    
---------------------        ----------------------------------------    + ------
부서번호  부서명  주소        사원번호 사원명 직급 급여 입사일 부서번호       부서명
+++++++                      +++++++                        ========(F.K)    
---------------------        ----------------------------------------    + ------
        10개 행                           1,000,000개 행 
---------------------        ----------------------------------------    + ------

>> 업무 분석 상 조회 결과물 
-----------------------
부서명 사원명 직급 급여 << 빈번하게 조회될 아이들 
-----------------------
--> 사원명 직급 급여가 사원테이블에 있으니 부서명만 붙이면 JOIN할 필요없잖아 >> 이게 역정규화 

-- 『부서』 테이블과 『사원』테이블을 JOIN 했을 때의 크기
-- (10*30Byte) + (1000000 * 60Byte) = 300 + 60,000,000 = 60,000,300 Byte

-- 『사원』 테이블을 역정규화 수행한 후 이 테이블만 단독으로 읽어올 때의 크기 
-- 1000000 * 70byte = 70,000,000 byte

B 의 경우 → 역정규화를 수행하는 것이 바람직한 상황~!!! 

테이블명 : 부서               테이블명 : 사원
    10      10    10            10      10  10    10   10       10           10    
---------------------        ----------------------------------------    + ------
부서번호  부서명  주소        사원번호 사원명 직급 급여 입사일 부서번호       부서명
+++++++                      +++++++                        ========(F.K)    
---------------------        ----------------------------------------    + ------
    500,000개 행                           1,000,000개 행 
---------------------        ----------------------------------------    + ------

>> 업무 분석 상 조회 결과물 
-----------------------
부서명 사원명 직급 급여 << 빈번하게 조회될 아이들 
-----------------------
--> 사원명 직급 급여가 사원테이블에 있으니 부서명만 붙이면 JOIN할 필요없잖아 >> 이게 역정규화 

-- 『부서』 테이블과 『사원』테이블을 JOIN 했을 때의 크기
-- (500,000 * 30Byte) + (1000000 * 60Byte) = 15000,000 + 60,000,000 = 75,000,000 Byte

-- 『사원』 테이블을 역정규화 수행한 후 이 테이블만 단독으로 읽어올 때의 크기 
-- 1000000 * 70byte = 70,000,000 byte
*/

1. 관계(relationship, relation)
    - 모든 엔트리(entry)는 단일값을 가진다.
    - 각 열(column)은 유일한 이름을 가지며 순서는 무의미하다.
    - 테이블의 모든 행(row = 튜플 = tuple)은 동일하지 않으며 순서는 무의미하다.
    
2.  속성(attribute)
    - 테이블의 열(column)을 나타낸다.
    - 자료의 이름을 가진 최소 논리적 단위 : 객체의 성질, 상태 기술
    - 일반 파일(file)의 항목(아이템 = item = 필드 = field)에 해당한다.
    - 엔티티(entity)의 특성과 상태를 기술
    - 속성(attribute)의 이름은 모두 달라야 한다.

3.  튜플 = tuple = 엔티티 = entity 
    - 테이블의 행(row)
    - 연관된 몇 개의 속성(attribute)으로 구성
    - 개념 정보 단위
    - 일반 파일(file)의 레코드(record)에 해당한다.
    - 튜플 변수(tuple variable)
     튜플 변수(tuple variable)
     : 튜플(tuple)을 가리키는 변수, 모든 튜플 집합을 도메인으로 하는 변수
     
4. 도메인(domain)
   - 각 속성(attribute)이 가질 수 있도록 허용된 값들의 집합
   - 속성 명과 도메인 명이 반드시 동일할 필요는 없음.
   - 모든 릴레이션에서 모든 속성들의 도메인은 원자적(atomic)이어야 함.
   - 원자적 도메인
     : 도메인의 원소가 더 이상 나누어질 수 없는 단일체일 때를 나타냄.

5. 릴레이션(relation)
    - 파일 시스템에서 파일(file)과 같은 개념
    - 중복된 튜플(tuple = entity = 엔티티)을 포함하지 않는다.
      → 모두 상이함(튜플의 유일성)
    - 릴레이션 = 튜플(엔티티 = entity)의 집합. 따라서 튜플의 순서는 무의미하다.
    - 속성(attribute) 간에는 순서가 없다.
    
    --■■■ 무결성(Integrity) ■■■--
/*
1. 무결성에는 개체 무결성(Entity Integrity)
             참조 무결성(Relation Integrity)
             도메일 무결성(Domain Integrity)이 있다.

2. 개체 무결성(Entity integrity)
   개체 무결성은 릴레이션에서 저장되는 튜플(tuple)의
   유일성을 보장하기 위한 제약조건이다.
   (EX : SMITH의 사원정보 튜플(레코드, 행)은 하나여야 함.)
   
3. 참조 무결성(Relational Integrity)
   참조 무결성은 릴레이션 간의 데이터 일관성을
   보장하기 위한 제약조건이다.
   (EX : 가영 사원의 부서번호 60 → 그러나, DEPT 테이블에 그 부서번호가 없다.)

4. 도메인 무결성(Domain Integrity)
   도메인 무결성은 허용 가능한 값의 범위를
   지정하기 위한 제약조건이다.
   (컬럼에 대한 데이터 타입.)
   (EX : HIREDATE에 DATE 타입이 아닌 1234 NUMBER 타입이 들어가 있으면 안 된다.)
   (DATE 타입이 아닌 데이트는 INSERT 되지 않도록 막아야 한다.)
   (또한, DATE 타입이라 할지라도 13월, 57일 이런 형식의 데이터도 막아야 한다.

5. 제약조건의 종류
    -PRIMARY KEY(PK:P) →  부모 테이블의 참조받는 컬럼 → 기본키, 식별자
     해당 컬럼의 값은 반드시 존재해야 하며, 유일해야 한다.
     (UNIQUE 와 NOT NULL 이 결합된 형태) 
     
      (REFERENCE : 참조) 
    - FOREIGN KEY(FK:F:R) → 외래키, 외부키, 참조키
      해당 컬럼의 값은 참조되는 테이블의 컬럼 데이터들 중 하나와
      일치하거나 NULL 을 가진다.

    - UNIQUE(UK:U)
      테이블 내에서 해당 컬럼의 값은 항상 유일해야 한다.

    - NOT NULL(NN:CK:C)
      해당 컬럼은 NULL 을 포함할 수 없다.
      
    - CHECK(CK:C)
      해당 컬럼에 저장 가능한 데이터의 범위나 조건을 지정한다.

'IT > DBMS' 카테고리의 다른 글

Oracle - FOREIGN KEY 설정 실습  (0) 2025.07.09
Oracle - PRIMARY KEY 설정 실습  (0) 2025.07.09
Oracle- INTERSECT, MINUS(교집합/ 차집합)  (0) 2025.07.08
Oracle - UNION / UNION ALL  (1) 2025.07.08
Oracle - TABLE JOIN  (1) 2025.07.08

관련글 더보기

댓글 영역