데이터베이스 모델링

데이터베이스 모델링 1-1. data type

홍보살 2024. 12. 18. 17:10

실전 데이터베이스를 시작한다.

예전 튜너로 근무하던 중 자바 개발자와 이런 대화를 나눈 기억이 있다.

 

나 : "**님 정말 모델링 힘드시죠?"

개발자 : "아뇨 전 모델링이 너무 쉽고 재미있던데요"

나 : "대단하세요. 전 20년을 해도 여전히 어렵던데...."

 

정말 놀라운 대답이었다.

상황마다 정답이 없는 모델링이 가장 쉽다고 하니...

누적되는 건수는 얼마나 예상되는지에 따라 파티션도 고려해야할지

EAV를 적용할지 넓혀야 할지(OLTP와 OLAP에 따라 다르다)

화면상 조회 조건 parameter는 어떤식으로 받는게 유용할지등등...

진심 부러웠지만 실상 테이블들을 보고는 무척 당황스러웠다.

메야 !!!!!!!!!!!!

 

 

다양한 RDBMS가 존재하고 조금은 상이하나 기준은 MS SQL server를 기준으로 설명하겠다.

가급적 Oracle, Postgresql, Mysql등등과 비교는 하겠으나 편의상(현재 MS SQL server DBA 몸팔고 있다.) 양해 바란다.

이를 위해서 SSMS는 필히 설치를 하길 바란다.

(MS SQL server의 경우 SSMS에서는 casting에러를 잡아내지만 근래 많이 사용하는 DBeaver의 경우 오류 이전까지 row 를 dataset으로 오류없이 반환한다.

참고로 postgresql의 경우 정밀한 플랜을 보려면 PGAdmin4를 Oracle은 토드나 오렌지도 좋다.)

DDL시에 아주 기초적인 부분임에도 실상 정확히 인지하지 못하는 경우가 많은것이 data type 설정이다.

데이터베이스 실전 데이터 타입

간략하게 정의해 보자.

[문자형]

CHAR(n) :

고정형 문자열 컬럼에 사용되며 최대 길이는 8000까지 가능하다.

중요한것은 ASCII 코드내 문자열만을 가리키며 1byte를 기본으로 한다.

용도는 보통 자리수가 정해진 코드값 정도에서 주로 사용된다.

중요한건 VARCHAR와 달리 공란의 경우 N자리수만큼 space로 채워진다.

분명히 말하지만 '' 와  ' ' 는 다르다.

(default 로 공백문자('') 를 설정한다해도 char(4) 컬럼에 'ABC'를 insert 한다해도

뒤쪽에 ' ' 가 붙어있게 된다.) 

가변형(variant) 문자인 경우 절대 사용을 하면 안된다.

이유는 해당 컬럼에 대해 필터링이 존재할 경우(인덱스 존재) MS SQL server 기준으로 casting이 발생하고

옵티마이저의 parameter sniffing의 원인이 될 수 있어 최적의 플랜 작성이 안될 수 있고

실제로 그렇다.

인덱스 컬럼(포함열 제외)에 casting은 B-tree 구조상 인덱스 정렬에 대한 판별구조를 무너뜨리기 때문이다.

상세한 내용은 SSMS 상 실행계획내 속성에서 상세히 확인할 수 있다.

그럼에도 불구하고 CHAR(n) 을 사용하는 이유는 데이터의 무결성을 유지하기 위함이다.

DBMS의 사용의 동인 중 최우선은 정확성이기 때문이다. 

 

NCHAR(n) :

CHAR(n) 과 동일하며 4000자 까지 가능하다.(결국 8000byte까지라는 얘기와 동일하다.)

중요한것은 ASCII 코드외 유니코드 문자열을 가리키며 2byte를 기본으로 한다.

용도는 비슷하나 CHAR와 비슷하게 사용되며 할당되는 사이즈만 다르다고 생각하면 된다. 

특별한 경우가 아니라면 굳이 사용할 이유가 없다.

 

VARCHAR(n) :

variant + character 라고 보면 된다. 

가변형 문자열이며 자유롭다. 최대 2GB까지 가능하다.

코드값과 같은 고정형 문자가 아니라면 기본적으로 VARCHAR(n)을 사용하는게 맞다.

단 데이터의 무결성 차원에서 정확히 문자열의 수가 정해진 경우 CHAR(n) 을 사용해서 무결성을 지키는 게 중요하다.

이 무결성 유지를 위한것이 아니라면 VARCHAR(n)이 유연할 뿐만 아니라 여러모로  유리하다.

가령 VARCHAR(64)로 지정하고 빈문자열 입력하는 경우 page(오라클등의 block) 할당시 최소 사이즈로 공간을 잡는다.

참고로 오라클의 varchar2는 varchar와 동일하며 ANSI표준을 위해 표현될 뿐 실제는 varchar2를 사용한다.

 

NVARCHAR(n) :

NCHAR(n) 과 동일하다고 보면 된다.

 

TEXT & NTEXT : 

MS SQL server의 경우 VARCHAR(MAX) 혹은 NVARCHAR(MAX)로 대체하면 된다.

2GB까지 체울 수 있으며 간혹 기존 사용하던 데이터 타입이 TEXT인 컬럼과 조인등의 이슈가 예상되는 경우

casting 대신 TEXT를 사용할 수 있다.

그 외에는 2016버전 이후 사용할 이유가 없다.

비슷한 유형을 다른 DBMS에서는 아래와 같이 big size 문자열을 다룬다.

ㄴ Oracle, Db2 : CLOB

ㄴ PostgreSQL, Mysql, SQLite : TEXT

 

[숫자형]

INT:
크기: 4 바이트 정수
범위: -2,147,483,648 ~ 2,147,483,647


SMALLINT:
크기: 2 바이트 정수
범위: -32,768 ~ 32,767


TINYINT:
크기: 1 바이트 정수
범위: 0 ~ 255


BIGINT:
크기: 8 바이트 정수
범위: -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807

파티션이 필요할 정도의 big row count가 예상되지 않는다면 비추이며

seq, IDENTITY 에서 많이 사용된다.

 


FLOAT:
크기: 8 바이트 실수
범위: -1.79E+308 ~ 1.79E+308 (배정도는 15자리의 정밀도)

소수점 이하 자리수를 고정하기 곤한할 때 사용하지만 가급적 지양하는게 좋다.


REAL:
크기: 4 바이트 실수
범위: -3.40E+38 ~ 3.40E+38
정밀도: 약 7자리

 


DECIMAL(p, s) 또는 NUMERIC(p, s):
크기: 최대 17 바이트 실수이며 둘은 서로 호환된다.
p: 전체 자릿수 (0에서 38까지)
s: 소수점 이하 자릿수 (0에서 p까지)
실수의 데이터 무결성을 위해 float 보다 지향한다.

 

실제 숫자형 데이터 타입의 경우 가장 이슈는 역시나 실수와 정수의 구분이다.

실수와 정수를 계산할 수 없는 것이 원칙이다.

확실하게 구분해서 사용해야 한다.

예를 들어 개수는 정수 amount등에서는 실수를 사용할 수 있다.

실전에서 종종 일시(getdate, sysdate, now)를 숫자로 casting 하는 경우가 많다.

주관적 경험상 고정 문자열로 변환하는게 무결성 원칙과 casting 비용 (숫자는 자리수가 유동적이다) 면에서 우월하다.

 

첫번째 실전강의부터 너무 지겹게 느껴지지 않았는지 모르겠다.

무심코... 구차니즘...

혹은 투사(Projection) 로 정당화 하는 것은 아닌지 곰곰히 생각해 보자. 

 

지금 당장 서둘러 오픈하고 다시 뜯어내고

고도화라는게 일상적이긴 하지만 처음부터 조금은 느린 속도라도 정확하게 만드는게 어떨까?

모델링은 뼈대다. 순살 아파트가 회자되는 근래 분위기가 남의 일처럼 보이지 않는다.

비용측면에서 보면 후자가 항상 우월했던 것 같다.

배보다 배꼽이 더 커지는 경우라고 할까 ^^

 

손실회피가 최 우선순위인  오너 입장이라면 이러한 행태에 분명 반대할 것이다.

혈성지공까지는 아닐지라도 기초를 무시하지 말자.

기초부족 아가리파이터들의 부화방종이 얼마나 낮뜨거운가 ㅠㅠ

 

새로운 혹은 낯선 분야에 대한 학습은 과학적으로 쉽지않다는 이론이 있다.

우선 학습(學習) 이란 단어를 뜯어보면 깨우치고 익힌다의 개념으로  여기서 두번째 음절 습(習)의 경우 반복적 인지라고 볼 수 있다.

우리의 뇌는 수면(특히나 램수면)시 비수면시에 있었던 기억들을 복합적으로 재구성한다.

이때 과거의 기억(경험)과 최근 기억을 융합하는데 버릴것은 버리고 재구성하며 인상깊었던 것만 새롭게 보관한다.

이때 과거 기억과 현재 기억의 조합시 중요하다 판단되는 부분은 강화 후 아카이빙한다.

 

처음에 새로운 것을 배우는 일은 뇌속에 각인되기 쉽지 않다.(학습이라는 단어의 어원이 중요한 이유다.)

대충 안다고 생각했던 부분도 사실 몰랐던 부분이 더 많았을 수 있다.

이때 인지가 잘 안되는 것을 이상하게 여길 필요는 없다.

너무도 당연하다.

다만 과학적으로 보아도 지식의 누적과 문해력 및 습득속도는 비례할 것이다.

 

이 글은 이비니어스( www.evinious.co.kr )의 소유이며 불펌은 허락하지 않습니다.