1 저장소 데이터 모델 설계 원칙
메타데이터 저장소의 데이터 모델은 일반 업무 시스템 DB 설계와 다른 특수한 요구사항을 갖는다.
이력 보존 필수 스키마 변경, 표준 변경, 품질 진단 결과는 모두 시점 이력을 보존해야 한다. 단순히 현재 상태만 저장하면 “이 칼럼이 언제 추가되었는가”, “표준이 왜 바뀌었는가”를 추적할 수 없다.
다중 환경 지원 동일 테이블이 개발/스테이징/운영 환경에 각각 다른 버전으로 존재할 수 있다. 환경 구분자(env_type)를 스키마 메타데이터의 핵심 키로 설계해야 한다.
다중 DBMS 추상화 Oracle의 NUMBER, MySQL의 INT, PostgreSQL의 INTEGER는 개념적으로 동일하지만 물리적 표현이 다르다. 저장소에서는 표준화된 데이터 타입으로 정규화할지, 원본 타입을 그대로 보존할지 결정해야 한다. 권장하는 방식은 원본 타입을 그대로 보존하고, 표준 타입 매핑 테이블을 별도로 관리하는 것이다.
| 원칙 | 이유 | 미적용 시 문제 |
|---|---|---|
| 이력 보존 | 변경 추적, 감사 대응 | “언제 바뀌었는가” 추적 불가 |
| 다중 환경 | dev/staging/prod 갭 분석 | 환경 간 불일치 감지 불가 |
| DBMS 추상화 | 이기종 DBMS 통합 관리 | DBMS별 별도 저장소 필요 |
2 핵심 엔티티 설계
2.1 환경 및 연결 정보
TB_CONNECTION (DBMS 연결 정보)
├── conn_id VARCHAR PK 연결 ID
├── conn_name VARCHAR 연결 이름 (예: "운영_Oracle")
├── dbms_type VARCHAR DBMS 종류 (ORACLE/MYSQL/POSTGRESQL/MSSQL/DB2/TIBERO/SYBASE/MARIADB)
├── env_type VARCHAR 환경 구분 (DEV/STAGING/PROD/DW/BCV)
├── host VARCHAR 호스트 주소
├── port INTEGER 포트번호
├── database_name VARCHAR 데이터베이스/서비스명
├── schema_name VARCHAR 기본 스키마명
├── use_yn CHAR(1) 사용 여부
└── collect_cycle INTEGER 수집 주기(분)
env_type은 단순 텍스트가 아니라 코드 테이블로 관리한다. 이후 갭 분석에서 “어떤 환경 쌍을 비교할 것인가”를 쿼리할 때 이 값을 기준으로 조인하기 때문이다.
2.2 스키마 메타데이터 (기술 메타데이터의 핵심)
TB_META_TABLE (테이블 메타데이터)
├── table_id BIGINT PK 테이블 ID (surrogate key)
├── conn_id VARCHAR FK 연결 ID (TB_CONNECTION 참조)
├── owner VARCHAR 스키마 오너 (예: dbo, public)
├── table_name VARCHAR 물리 테이블명
├── table_comment VARCHAR DBMS에 등록된 코멘트
├── table_type VARCHAR TABLE/VIEW/MATERIALIZED_VIEW
├── row_count BIGINT 행 수 (수집 시점 기준)
├── data_size_mb DECIMAL 데이터 크기(MB)
├── collect_dt DATETIME 수집 일시
├── create_dt DATETIME 테이블 생성 일시 (DBMS에서 수집)
├── is_deleted CHAR(1) 삭제 여부 (실제 DBMS에서 사라진 경우)
└── delete_dt DATETIME 삭제 감지 일시
TB_META_COLUMN (칼럼 메타데이터)
├── column_id BIGINT PK 칼럼 ID
├── table_id BIGINT FK 테이블 ID
├── column_name VARCHAR 물리 칼럼명
├── column_order INTEGER 칼럼 순서
├── data_type VARCHAR DBMS 원본 데이터 타입 (예: VARCHAR2, INT)
├── data_length INTEGER 길이
├── data_precision INTEGER 전체 자릿수 (NUMBER 타입 등)
├── data_scale INTEGER 소수점 자릿수
├── nullable_yn CHAR(1) NULL 허용 여부
├── default_value VARCHAR 기본값
├── column_comment VARCHAR DBMS에 등록된 코멘트
├── collect_dt DATETIME 수집 일시
├── is_deleted CHAR(1) 삭제 여부
└── delete_dt DATETIME 삭제 감지 일시
TB_META_INDEX (인덱스 메타데이터)
├── index_id BIGINT PK
├── table_id BIGINT FK
├── index_name VARCHAR
├── index_type VARCHAR UNIQUE/NORMAL/BITMAP/HASH
├── is_pk CHAR(1) PK 구성 인덱스 여부
├── collect_dt DATETIME
└── [TB_META_INDEX_COLUMN] (인덱스 구성 칼럼)
├── index_id BIGINT FK
├── column_id BIGINT FK
└── column_order INTEGER
is_deleted 플래그를 두는 이유는 실제 DBMS에서 테이블이 삭제되더라도 메타데이터 저장소에서 물리 삭제하지 않고 논리 삭제로 처리하기 위해서다. 이렇게 해야 품질 진단 이력, 변경 이력, 비즈니스 메타데이터가 고아 레코드가 되지 않는다.
2.3 비즈니스 메타데이터
기술 메타데이터(TB_META_TABLE, TB_META_COLUMN)는 DBMS에서 자동 수집하지만, 비즈니스 메타데이터는 사람이 직접 입력한다. 이 두 개를 별도 테이블로 분리하는 것이 핵심 설계 결정이다.
TB_BIZ_TABLE (테이블 비즈니스 메타데이터)
├── table_id BIGINT FK TB_META_TABLE 참조 (1:1)
├── logical_name VARCHAR 논리 테이블명 (한글)
├── biz_definition TEXT 업무 정의
├── data_subject VARCHAR 데이터 주제 영역
├── owner_dept VARCHAR 데이터 오너 부서
├── owner_person VARCHAR 데이터 오너 담당자
├── data_lifecycle VARCHAR 데이터 보존 주기 (예: 5년)
├── source_system VARCHAR 데이터 발생 원천 시스템
├── update_cycle VARCHAR 데이터 갱신 주기 (실시간/일배치/월배치)
├── input_person VARCHAR 입력자
├── input_dt DATETIME 입력 일시
├── update_person VARCHAR 최종 수정자
└── update_dt DATETIME 최종 수정 일시
TB_BIZ_COLUMN (칼럼 비즈니스 메타데이터)
├── column_id BIGINT FK TB_META_COLUMN 참조 (1:1)
├── logical_name VARCHAR 논리 칼럼명 (한글)
├── biz_definition TEXT 업무 정의
├── domain_id BIGINT FK 도메인 참조 (TB_STANDARD_DOMAIN)
├── std_term_id BIGINT FK 표준 용어 참조
├── sensitive_grade VARCHAR 중요데이터 등급 (1~5 또는 NULL)
├── is_personal_info CHAR(1) 개인정보 여부
├── sample_value VARCHAR 샘플 값 (예시)
├── input_person VARCHAR
└── input_dt DATETIME
domain_id와 std_term_id는 표준 관리 모듈과의 연결 고리다. 칼럼에 도메인이 매핑되면, 해당 도메인의 규칙을 이용해 자동으로 품질 진단을 실행할 수 있다. 이 외래키가 없으면 표준과 품질이 분리된 고립된 시스템이 된다.
2.4 데이터 표준 (Standard)
TB_STANDARD_TERM (표준 용어)
├── term_id BIGINT PK
├── std_id BIGINT FK 소속 표준 세트 (TB_STANDARD_SET)
├── term_name VARCHAR 표준 용어명 (영문)
├── term_name_ko VARCHAR 표준 용어명 (한글)
├── abbreviation VARCHAR 약어 (칼럼명 생성 규칙에 사용)
├── definition TEXT 정의
├── status VARCHAR ACTIVE/DEPRECATED
├── create_dt DATETIME
└── update_dt DATETIME
TB_STANDARD_WORD (표준 단어)
├── word_id BIGINT PK
├── std_id BIGINT FK
├── word_name VARCHAR 단어 (예: CUSTOMER)
├── word_name_ko VARCHAR 한글 단어 (예: 고객)
├── abbreviation VARCHAR 약어 (예: CUST)
├── domain_id BIGINT FK 기본 도메인 (이 단어로 끝나는 칼럼의 도메인 추론에 사용)
└── status VARCHAR
TB_STANDARD_DOMAIN (도메인)
├── domain_id BIGINT PK
├── std_id BIGINT FK
├── domain_group_id BIGINT FK 도메인 그룹 참조
├── domain_name VARCHAR 도메인명 (예: 금액, 날짜, 코드값)
├── data_type VARCHAR 허용 데이터 타입
├── data_length INTEGER 허용 최대 길이
├── rule_type VARCHAR RANGE/REGEX/CODE/CUSTOM
├── rule_value TEXT 규칙 표현식 또는 코드 도메인 ID
├── description TEXT
└── status VARCHAR
TB_STANDARD_SET (표준 세트 - 복수 표준 관리)
├── std_id BIGINT PK
├── std_name VARCHAR 표준명 (예: "전사 표준", "패키지 표준")
├── std_type VARCHAR PUBLIC/LOCAL/NON_STANDARD
├── description TEXT
└── is_default CHAR(1) 기본 표준 여부
TB_STANDARD_SET을 두는 이유는 하나의 조직에서 전사 표준(Public), 레거시/패키지 시스템의 로컬 표준(Local), 표준 미적용 시스템(Non-Standard)이 공존하기 때문이다. 모든 것을 하나의 표준으로 강제하면 패키지 솔루션이나 인수합병 시스템을 메타데이터 시스템에 등록할 수 없게 된다.
2.5 공통 코드 (Master Code)
TB_CODE_GROUP (코드 그룹)
├── code_group_id VARCHAR PK 예: "GENDER", "ORDER_STATUS"
├── code_group_name VARCHAR 코드 그룹명
├── table_id BIGINT FK 실제 저장 테이블 (TB_META_TABLE)
├── key_column_id BIGINT FK 코드 키 칼럼
├── value_column_id BIGINT FK 코드 값 칼럼
├── description TEXT
├── domain_id BIGINT FK 연결 도메인 (품질 진단에 사용)
└── status VARCHAR
TB_CODE_VALUE (코드 값)
├── code_value_id BIGINT PK
├── code_group_id VARCHAR FK
├── env_type VARCHAR 환경 구분
├── code_key VARCHAR 코드 키 (예: "M")
├── code_value VARCHAR 코드 값 (예: "남성")
├── sort_order INTEGER 정렬 순서
├── effective_from DATE 유효 시작일
├── effective_to DATE 유효 종료일
└── status VARCHAR ACTIVE/INACTIVE
TB_CODE_VALUE에 env_type을 두는 이유는 개발과 운영 환경의 코드 값이 다를 수 있기 때문이다. 개발에서 코드를 추가한 후 운영에 배포하기 전까지 두 환경의 코드 셋이 다른 상태가 된다. 이 갭을 코드 갭 분석 기능에서 탐지해야 한다.
2.6 중요데이터 관리
TB_SENSITIVE_GRADE_STD (등급 기준 정의)
├── grade VARCHAR PK 등급 코드 (1,2,3,4,5,PI)
├── grade_name VARCHAR 등급명 (예: "1등급: 극비")
├── description TEXT 등급 기준 설명
└── mask_rule_default TEXT 기본 비식별화 규칙
TB_SENSITIVE_COLUMN (중요데이터 칼럼)
├── sensitive_id BIGINT PK
├── column_id BIGINT FK TB_META_COLUMN 참조
├── grade VARCHAR FK 등급
├── is_personal_info CHAR(1) 개인정보 여부
├── mask_rule_id BIGINT FK 비식별화 규칙
├── reason TEXT 등급 부여 사유
├── confirmed_yn CHAR(1) 확인 완료 여부
├── confirm_person VARCHAR
└── confirm_dt DATETIME
TB_MASK_RULE (비식별화 규칙)
├── mask_rule_id BIGINT PK
├── rule_name VARCHAR 규칙명
├── rule_type VARCHAR MASKING/ENCRYPTION/GENERALIZATION/SUPPRESSION/NOISE_ADDITION
├── rule_expression TEXT 규칙 표현식 또는 함수
└── example VARCHAR 예시 (원본: 010-1234-5678 -> 마스킹: 010-****-****)
3 핵심 관계 다이어그램
TB_CONNECTION
|
| 1:N
v
TB_META_TABLE ---------------------- TB_BIZ_TABLE
| |
| 1:N |
v v
TB_META_COLUMN -------------------- TB_BIZ_COLUMN
| |-- domain_id --> TB_STANDARD_DOMAIN
| +-- std_term_id -> TB_STANDARD_TERM
| 1:N
v
TB_META_INDEX
|
v
TB_META_INDEX_COLUMN
TB_STANDARD_SET
|-- TB_STANDARD_TERM
|-- TB_STANDARD_WORD
+-- TB_STANDARD_DOMAIN
|
+-- domain_id -> TB_CODE_GROUP (rule_type = CODE인 경우)
TB_SENSITIVE_COLUMN
|-- column_id --> TB_META_COLUMN
+-- mask_rule_id -> TB_MASK_RULE
핵심 관계를 요약하면:
TB_CONNECTION→TB_META_TABLE→TB_META_COLUMN: 기술 메타데이터의 계층 구조TB_META_TABLE↔︎TB_BIZ_TABLE,TB_META_COLUMN↔︎TB_BIZ_COLUMN: 기술-비즈니스 1:1 매핑TB_BIZ_COLUMN→TB_STANDARD_DOMAIN,TB_STANDARD_TERM: 표준과의 연결TB_SENSITIVE_COLUMN→TB_META_COLUMN: 중요데이터 등급 부여
4 이력 테이블 설계
모든 핵심 마스터 테이블은 이력 테이블을 별도로 갖는다. 이력 테이블은 마스터 테이블명에 _HIS를 붙이는 관례를 사용한다.
TB_META_COLUMN_HIS (칼럼 메타데이터 이력)
├── his_id BIGINT PK 이력 ID
├── column_id BIGINT 원본 column_id (FK 아님 - 삭제되더라도 이력은 남아야 함)
├── table_id BIGINT 원본 table_id
├── [모든 TB_META_COLUMN의 칼럼들]
├── change_type VARCHAR INSERT/UPDATE/DELETE
├── changed_by VARCHAR 변경자 (시스템 자동 수집인 경우 SYSTEM)
└── changed_dt DATETIME 변경 일시
이력 테이블에서 FK 제약조건을 제거하는 이유는, 원본 레코드가 삭제된 후에도 이력은 영구 보존해야 하기 때문이다. FK가 있으면 원본 삭제 시 CASCADE 또는 에러가 발생한다.
5 갭 분석을 위한 설계
갭 분석은 두 소스의 동일 객체를 비교해서 불일치를 탐지하는 기능이다. 비교 소스의 종류는 다음과 같다.
| 갭 유형 | 비교 대상 | 사용 시나리오 |
|---|---|---|
| 환경 간 갭 | 개발 DB 스키마 vs 운영 DB 스키마 | 배포 전 불일치 탐지 |
| 모델-DBMS 갭 | ERD 모델 vs 실제 DBMS 스키마 | 설계-구현 일치 검증 |
| 표준-실제 갭 | 표준 명명 규칙 vs 실제 칼럼명 | 표준 준수율 측정 |
갭 분석 결과는 별도 테이블에 저장하거나, 뷰(View)로 실시간 계산한다. 데이터 양이 많으면 배치로 계산해서 결과 테이블에 적재하는 방식이 성능상 유리하다.
TB_GAP_RESULT (갭 분석 결과)
├── gap_id BIGINT PK
├── gap_type VARCHAR ENV_DIFF/MODEL_DIFF/STANDARD_DIFF
├── source_conn_id VARCHAR 소스 연결 ID
├── target_conn_id VARCHAR 타겟 연결 ID
├── object_type VARCHAR TABLE/COLUMN/INDEX/CODE
├── source_object_id BIGINT 소스 객체 ID
├── target_object_id BIGINT 타겟 객체 ID (NULL이면 타겟에 없음)
├── gap_attribute VARCHAR 불일치 속성 (예: "data_type", "data_length")
├── source_value VARCHAR 소스의 값
├── target_value VARCHAR 타겟의 값
├── status VARCHAR OPEN/RESOLVED/IGNORED
├── detected_dt DATETIME 감지 일시
└── analysis_job_id BIGINT FK 분석 작업 ID
6 관련 주제
시리즈 연결
- Part 1: 개념과 범위 정의
- Part 3: 수집과 변경 관리 — 메타데이터 자동 수집, 변경 요청-승인 워크플로
- Part 4: 품질과 보안 — 품질 진단 규칙, 중요데이터 비식별화
- Part 5: 아키텍처와 우선순위 — 전체 시스템 아키텍처, 구축 우선순위
카테고리 내 연결