상세 컨텐츠

본문 제목

속성명, 속성코드 모델, 널(Null)

기록 - 프로그래밍/Data

by wjjun 2024. 4. 22. 12:35

본문

속성명

단어 사전을 기반으로 가이드를 따라서 정해야 합니다.

속성명을 정의할 때 표준화에 집중해야 합니다. 속성명에 대한 표준화를 간단하게 표현하면 같은 의미의 속성명은 같게 쓰도록 하는 것입니다. 같은 의미를 다르게 쓰거나 다른 의미를 같게 쓰지 않도록 하는 것이 표준화 입니다.

 

모든 엔티티에서 공통 사용하는 시스템 속성과 중복 속성, 관계(FK)속성은 제외됩니다.

속성명은 의미를 충분히 이해할 수 있을 정도로 구체적이고 가능한 짧아야 합니다.

 

속성 설명은 가능한 간결하게 작성하는 것이 좋습니다.

 

코드

코드는 데이터를 구분하기 위해 사용합니다.

현재는 사용하지 않더라도 사용될 가는ㅇ성이 있는 것은 코드화 해서 관리합니다.

코드를 정의할 때는 엔티티나 속성을 정의할 때와 같이 하나의 코드에 여러 의미가 포함되지 않도록 해야 합니다. 사용 방법이 배타적이라고 여러 종류의 다른 코드를 하나의 코드로 정의해서는 안됩니다. 성질이 다르면 다른 코드로 부여해야 합니다.

 

부서 테이블 - 부서코드 (PK)

고객 테이블 - 고객번호 (PK) / 고객명 / 고객구분코드

 

속성코드와 식별자 코드

코드 속성은 속성 중에서 사전에 약속된 값인 코드값이 사용된 속성을 의미합니다. 흔히 얘기하는 코드는 이런 속성 코드를 의미합니다. 항상 문제가 되는 속성입니다. 코드 속성에서 사용되는 코드값과 코드명은 공통 코드 엔티티에서 통합 관리됩니다. 

 

일반 코드와 식별자 코드는 다른 개념으로 생각해야 합니다. 하나의 독립적인 개체를 의미하는 것이 주 식별자이고 속성명에 ~코드가 붙었을 뿐 코드 엔티티에서 관리하는 코드성 데이터와 다릅니다.

 

만약 부서코드라는 속성명을 부서번호라고 해도 아무런 문제가 되지 않습니다. 부서코드 속성의 가장 큰 역할은 부서 엔티티에서 인스턴스를 유일하게 식별할 수 있도록 하는 것입니다. 부서명이라는 텍스트 값을 더 짧은 상징으로 표현해서 사용하는 것은 부차적인 역할입니다.

 

식별자 코드는 단지 인스턴스 식별을 위해 사용되는 인조 식별자가 대부분입니다. 따라서 주 식별자에 다른 속성이 포함되지 않은 여러 속성으로 구성되지 않고 단독 속성으로 구성됩니다.

 

대표적으로 식별자 코드로 부서코드, 지점코드, 사업장코드, 대리점코드, 사원코드, 상품코드, 종목코드, 서비스 코드 등이 존재합니다. 전부 개별적인 엔티티가 존재해 각각 데이터를 관리하며 해당 엔티티의 단독 주 식별입니다.

 

고객 - 고객 번호(PK) / 고객명 / 주소 / 국가코드 

코드 - 코드유형(FK) / 코드값 / 코드명

 

코드유형 : 한국, 미국, 아르헨티나 ...

 

개별 엔티티로 관리하는 국가코드

국가 - 국가코드 / 국가명 / 영문약어명 / 국가전화번호

 

국가 릴레이션을 사용하면 국가 위에 코드 엔티티에서 국가에 대한 데이터는 삭제해야 합니다.

 

일반코드 속성명 구분법

구분코드 : 성질이나 특징이 다른 코드명이 고정적일 때 사용 (남녀구분코드, 매수매도 구분코드)

유형코드 : 코드명을 성질이나 특징이 공통적인 것끼리 묶어 사용 (거래유형코드)

종류코드 : 고정적이지 않고 지속적으로 늘어날 수 있는 코드명을 나열할 때 사용 (서비스 종류코드)

 

 

코드 모델

코드 엔티티는 일반적인 엔티티 성격과 다릅니다. 데이터 성격을 파악해 엔티티를 도출하는 것이 아닌 미리 약속된 코드를 관리하기 쉬운 방법, 어플리케이션에서 사용하기 편한 방법을 도출해서 사용해야 합니디.

 

모델 구조뿐만 아니라 데이터를 어떻게 발생시켜 관리할 것인지도 중요합니다.

코드유형 엔티티는 코드로 관리할 종류를 관리합니다. 코드 유형이 100개 이상 존재하면 3자리를 사용해서 코드 엔티티에서는 코드유형별 코드값과 코드명을 관리합니다.

 

일반적인 코드 모델

코드 유형 테이블 - 코드유형번호(PK) / 코드 유형명)

코드 테이블 - 코드유형번호(FK) / 코드값(FK) / 코드명

 

만약 화면에서 매도와 매수 종류를 선택하는 리스트 박스가 존재하면 다음 쿼리를 사용할 수 있습니다.

SELECT 코드값, 코드명

FROM [코드]

WHERE 코드유형번호 = '001' /*매수 매도 구분 코드*/

 

데이터를 보여주는 목록 화면이나 상세 화면에서는 아래 쿼리를 사용하게 됩니다.

아래 쿼리는 123456 계좌에서 거래한 내역을 보여주며 여러 데이터 중 매수와 매도 부분만 표현한 것입니다.

SELECT A.계좌번호, B.코드명

FROM [거래내역] A, [코드] B

WHERE A.매수매도구분코드 = B.코드값

    AND B.코드유형번호 = '001'

    AND A.계좌번호 = '123456';

 

쿼리에 상수를 지정한 '코드유형번호 = 001' 이라는 구문이 항상 사용되는 것은 쿼리를 복잡하게 만들 수 있어 아래와 같이 뷰(View)를 사용할 수 있습니다.

 

CREATE OR REPLACE VIEW VW_매수매도구분

AS

SELECT 코드값, 코드명

FROM [코드]

WHERE 코드유형번호 = '001' 

 

위에 생성한 뷰는 개별 코드 엔티티 역할을 하게 됩니다. 

 

SELECT A.계좌번호, B.코드명

FROM [거래내역] A, VW_매수매도구분 B

WHERE A.매수매도구분코드 = B.코드값

    AND A.계좌번호 = '123456';

 

 

Null 널

Null은 속성의 값을 알 수 없을 때 사용합니다. 데이터가 입력되는 시점을 기준으로 값을 알 수 없을때 널 값을 사용합니다.

값을 알 수 없는 이유는 다양합니다. 값을 모르거나 입력 당시 기록되지 않을 수도 있고 오류 때문일 수도 있습니다.

아예 값이 적용되지 않을 수도 있습니다.

 

예를들어 개인과 법인을 함께 관리한다면 법인은 설립일자 속성에만 입력되고 생년월일은 null 속성으로 유지도리 것입니다.

이런 속성이 존재하면 엔티티에서 제외해서 일대일 관계로 분리하는 것이 원칙입니다. 하지만 이보다 데이터 통합이 우선해서 해당 사항 없는 값이 존재하는 속성도 사용되기도 합니다.

 

속성 값의 의미를 더 명확히 하려면 적용할 수 없는 값과 넓(Null) 값을 구분해서 관리할 필요가 있습니다. 특히 코드명 중에 적용할 수 없음, 해당없음을 의미하는 코드값을 추가해서 사용해야 하는 예시가 있습니다.

 

주문상태 코드가 있고 주문상태코드, 주문취소사유코드가 있을 때

취소 사유를 반드시 취득할 수 있는 것이 아니므로 모르거나 기타를 의미하는 9(모름) 값을 정해서 사용할 수 있습니다.

아직 주문 취소가 불가능한 상태일 때는 0(해당없음) 의미로 사용하여 구분시킬 수 있습니다.

 

아우터 조인(Outer join)을 수행한 릴레이션에서 보이는 널 값은 모르는 값이나 해당하지 않는 값을 의미하지 않고 단순히 없는 값을 의미합니다.

 

모델링을 수행할 때 속성에 널(Null)을 허용할 것이지 고민하는 경우가 많습니다. 이에 대한 기본적인 판단은 데이터 입력 시점에 입력할 값을 모르면 널(Null)을 허용하는 것이 원칙입니다.  

 

하지만 가능한 Null 값을 피하는게 좋다. 널(Null)도 하나의 고유한 값이므로 간혹 쿼리에서 뜻하지 않게 사용될 수 있다. 넓 값은 보통 인덱스에 포함되지 않으므로 인덱스 효율성을 고려해 널 허용 여부를 결정해야 할 때도 있습니다.

 

널 정의를 원칙적으로 적용하면 널(Null)을 허용하는 때가 많을 것이지만 데이터베이스 특성을 고려하면 널 값의 사용을 최소화 하는 것이 바람직할 수 있습니다.

 

널 값을 허용하지 않으면 실제로 모르는 값에 대해서는 기본 값을 사용하게 됩니다. 기본 값은 다양하게 존재할 수 있지만 ""를 사용하는 것보다 보편적입니다. 모르는 값을 의미하는데 '0'이나 'x'등의 다른 문자가 사용되면 혼란스러울 수 있습니다. 그런 의미에서 ~와 같은 특수문자를 사용하는 것도 하나의 방법입니다.

 

널 값에 해당하는 인스턴스 개수가 적다면 빈문자나, ~ 등으로 값을 채워서 인덱스 스캔을 하도록 하는 것도 방법입니다. 즉 널로 조회되는 요건이 있다면 기본 값을 사용해야 인덱스 사용에 효율적입니다.

 

반면 속성 중 널에 해당하는 값이 많다면 인덱스 스캔은 도움이 되지 않으므로 테이블 풀 스캔을 유도하기 위해 실제 널을 사용할 수도 있습니다. 널이 허용된 속성으로 시작되는 인덱스를 생성하면 널 값은 인덱스에 포함되지 않으므로 테이블 풀 스캔을 한다는 점은 고려할 사항입니다.

 

분포도가 낮은 속성은 인덱스 범위 스캔이 되지 않도록 널 값을 사용하는 것을 고려하고 분포도가 높은 속성은 기본 값을 사용해 테이블 풀 스캔이 되지 않도록 고려해야 합니다.

 

또한 널 값이 허용된 속성을 조회하려고 NVL구문을 사용하면 인덱스를 사용할 수 없게 됩니다.

 

참조 무결성 제약도 널 사용과 관련 있습니다. 외래 식별자 속성이 업무적으로 Null이 가능하면 널이 허용돼야 합니다. 참조 무결성 제약이 존재하므로 상위 엔티티에 존재하지 않는 '~' 와 같은 기본 값을 사용할 수가 없기 때문입니다.

 

외래 식별자 속성에 널 값이 존재할 때는 아웃터 조인을 항상 염두해야 합니다. 무심코 조인하면 원하지 않는 결과가 나올 수 있습니다.

 

널 값에 조인에 참여하면 일반 조인과 아웃터 조인이 다른 결과를 나타내는 점에 유의해야 합니다.

 

기존 마이그레이셔 할 때도 널 값을 고려해야 합니다. 기존 데이터에는 널 값이 사용되었는데 마이그레이션 해야 하는 속성에는 널이 허용되지 않아 기본값을 사용해야 하는 문제가 발생할 수도 있습니다.

 

널 값을 허용하지 않고 기본 값을 사용해야 하는 원칙이 있다면 운영중인 대용량 엔티티에 속성이 추가되는 상황도 고려해야 합니다.

속성을 추가하고 기본 값으로 업데이트 해야 하는데 많은 시간이 소요될 수 있습니다.

 

속성의 특성에 맞도록 널 허용 여부를 결정해야 하지만 대체로 널 값을 허용하면 좋지 않은 속성 종류가 있습니다. 코드나 여부, 유무 속성일 때는 Not Null로 지정하는 것이 좋습니다.

 

관련글 더보기

댓글 영역