사전 정규화
용어함정

정규화

gabury1

정규화는 데이터를 미리 정해 둔 기준에 맞춰 바꾸는 일입니다. 무엇을 어떤 기준에 맞추는지는 쓰는 자리마다 다릅니다. 테이블을 쪼개는 일도 정규화라고 부르고, 문자열의 표기를 하나로 모으는 일도 정규화라고 부릅니다.

상세

관계형 데이터베이스와 유니코드와 URI(Uniform Resource Identifier, 통합 자원 식별자) 세 맥락은 뼈대를 공유합니다. 같은 것을 나타내는 표기가 여럿일 때, 그중 하나를 정해 두고 거기로 모읍니다. 갈리는 자리는 무엇을 무엇의 정해진 형태로 만드는가입니다. 그 정해진 형태에 붙는 이름도 맥락마다 다릅니다. 관계형 데이터베이스 쪽은 지켜야 할 규칙 하나하나를 정규형(normal form)이라고 부릅니다. 유니코드 쪽은 정해진 변환 하나하나에 이름을 붙입니다. 그 이름이 정규화 형식(Normalization Form)입니다.

관계형 데이터베이스에서 모아지는 것은 테이블의 모양입니다. Microsoft 의 데이터베이스 정규화 문서는 정규화를 데이터베이스에서 데이터를 조직하는 과정이라고 적습니다. 테이블을 만들고 그 테이블들 사이에 관계를 세우는 일입니다. 그 규칙들은 데이터를 지키면서 중복과 불일치 의존을 없애 데이터베이스를 더 유연하게 만들도록 설계된 것이라고 적습니다.

유니코드에서 모아지는 것은 문자열의 표기입니다. UAX(Unicode Standard Annex, 유니코드 표준 부속서) #15 는 유니코드 정규화 형식을 유니코드 문자열의 정규화라고 정의합니다. 두 유니코드 문자열이 서로 동등한지 판정할 수 있게 해 주는 것이라고 적습니다. 구현이 문자열을 정규화한 형태로 들고 있으면 동등한 문자열이 유일한 이진 표현을 갖는다고 보장할 수 있다고도 적습니다.

URI 에서 모아지는 것은 식별자의 표기입니다. RFC(Request for Comments) 3986 은 URI 에 가장 흔히 하는 연산 가운데 하나가 단순 비교라고 적습니다. 두 URI 가 동등한지를 그 자원에 접근하지 않고 판정하는 일입니다. 그런데 같은 자원을 가리키면 동등하다는 정의는 실무에서 쓸모가 적다고 적습니다. 구현이 두 자원을 견주려면 그 자원을 전부 알거나 통제해야 하기 때문입니다. 그래서 동등성 판정은 문자열 비교에 기반한다고 적습니다. 정규화는 그 문자열 비교가 어긋나지 않도록 표기를 맞추는 절차입니다.

통계와 머신러닝 쪽은 이 뼈대를 공유하지 않습니다. scikit-learn 사용자 안내서는 정규화를 개별 샘플이 단위 노름을 갖도록 스케일링하는 과정이라고 적습니다. 이 문서는 정규형이라는 말을 한 번도 쓰지 않습니다. 정해진 표기로 모으는 일이 아니라 값의 크기를 옮기는 일입니다.

어느 뜻이 원래 뜻인지는 이 문서들이 적지 않습니다. 그래서 정규화라는 말만으로는 무엇을 어디로 모으는지가 정해지지 않습니다. 맥락 이름을 먼저 대야 뜻이 섭니다.

맥락별 뜻

맥락 뜻 출처
관계형 데이터베이스 중복과 불일치 의존을 없애는 규칙에 따라 데이터를 테이블로 조직하는 과정 Microsoft 데이터베이스 정규화 문서, "Description of normalization"
유니코드 두 문자열이 동등한지 판정할 수 있게 정해진 형식으로 바꾸는 것 Unicode Standard Annex #15, 1.2 Normalization Forms
URI 표기가 다른 URI 를 문자열 비교로 견줄 수 있게 맞추는 절차 RFC 3986, 6.2 Comparison Ladder · 6.2.2 · 6.2.3
통계·머신러닝 개별 샘플이 단위 노름을 갖도록 스케일링하는 것 scikit-learn User Guide, 6.3.4 Normalization

관계형 데이터베이스

데이터베이스 정규화에는 몇 가지 규칙이 있습니다. 규칙 하나하나를 정규형이라고 부릅니다. 첫 규칙을 지키면 그 데이터베이스는 제1정규형에 있다고 말합니다. 앞의 세 규칙을 지키면 제3정규형에 있다고 봅니다. 다른 수준의 정규화도 가능하지만, 대부분의 애플리케이션에는 제3정규형이 필요한 가장 높은 수준으로 여겨진다고 문서는 적습니다.

세 규칙은 이렇습니다. 제1정규형은 개별 테이블에서 반복 그룹을 없앱니다. 서로 관련된 데이터 집합마다 테이블을 따로 만들고, 각 집합을 기본 키로 식별합니다. 제2정규형은 여러 레코드에 걸쳐 쓰이는 값 집합을 별도 테이블로 빼고 그 테이블들을 외래 키로 잇습니다. 레코드는 테이블의 기본 키 말고 다른 것에 딸리면 안 됩니다. 기본 키가 복합 키여야 한다면 그렇게 잡습니다. 제3정규형은 키에 딸리지 않는 필드를 없앱니다. 레코드의 키에 속하지 않는 값은 그 테이블에 있을 자리가 아니라고 적습니다.

문서는 학생 테이블 하나를 예로 들어 이 단계를 밟아 보입니다.

flowchart TD
    A["정규화 안 된 테이블"] --> B["제1정규형 · 반복 그룹 없애기"]
    B --> C["제2정규형 · 중복 데이터 없애기"]
    C --> D["제3정규형 · 키에 안 딸린 데이터 없애기"]

이 규칙들이 겨냥하는 것은 둘입니다. 중복 데이터는 디스크 공간을 낭비하고 유지보수 문제를 만듭니다. 한 곳 넘게 있는 데이터를 고쳐야 하면 모든 자리에서 똑같은 방식으로 고쳐야 하기 때문입니다. 불일치 의존은 데이터에 닿는 길이 없거나 끊겨 있어 접근을 어렵게 만들 수 있습니다. 문서는 예를 하나 듭니다. 손님의 주소를 손님 테이블에서 찾는 것은 자연스럽습니다. 그 손님을 담당하는 직원의 급여를 거기서 찾는 것은 말이 안 될 수 있습니다. 급여는 직원에 딸린 값이므로 직원 테이블로 옮겨야 한다고 적습니다.

대가도 같은 문서가 적어 둡니다. 제3정규형을 지키는 것은 이론적으로는 바람직해도 언제나 실용적이지는 않습니다. 일반적으로 정규화는 테이블을 더 요구합니다. 이것을 번거롭게 여기는 고객도 있다고 적습니다. 작은 테이블이 많으면 성능이 떨어지거나 열린 파일과 메모리 용량을 넘을 수 있습니다. 그래서 자주 바뀌는 데이터에만 제3정규형을 적용하는 편이 더 실현 가능할 수 있다고 적습니다.

더 높은 정규형도 이름은 있습니다. 제4정규형은 보이스코드 정규형이라고도 불립니다. 제5정규형도 있습니다. 다만 이 둘은 실무 설계에서 거의 고려되지 않는다고 적습니다.

유니코드

정규화 형식은 네 가지입니다. 정준 동등과 호환 동등 중 무엇을 쓰는지, 그리고 분해에서 멈추는지 결합까지 가는지로 갈립니다.

형식 하는 일
NFD(Normalization Form D) 정준 분해
NFC(Normalization Form C) 정준 분해 뒤에 정준 결합
NFKD(Normalization Form KD) 호환 분해
NFKC(Normalization Form KC) 호환 분해 뒤에 정준 결합

동등성 두 가지의 뜻은 UAX #15 가 정의합니다. 정준 동등은 문자 또는 문자열 사이의 근본적 동등성입니다. 같은 추상 문자를 나타내는 것들이고, 올바로 표시하면 언제나 같은 시각적 모양과 동작을 가져야 합니다. 호환 동등은 같은 추상 문자를 나타내지만 시각적 모양이나 동작이 다를 수 있는, 더 약한 종류의 동등성입니다. 어느 쪽을 쓰느냐에 따라 같다고 판정되는 범위가 달라집니다.

유니코드 정규화 알고리즘이 하는 일 자체는 본질적으로 결합 표시를 모두 정해진 순서로 놓는 것이라고 적혀 있습니다.

URI

RFC 3986 은 URI 동등성을 재는 방법이 하나가 아니라고 적습니다. 실제로 쓰이는 방법들은 필요한 처리량과 거짓 음성 확률을 얼마나 줄이는가에 따라 범위를 이룹니다. 그 범위를 이 문서는 비교 사다리라고 부릅니다. 구문 기반 정규화는 그중 한 칸입니다. URI 구문은 두 URI 를 견주기 전에 파싱을 요구하는 문법을 정의하기 때문입니다.

flowchart TD
    A["원래 URI 표기"] --> B["스킴과 호스트를 소문자로"]
    B --> C["예약되지 않은 문자의 백분율 인코딩을 되돌린다"]
    C --> D["점 세그먼트를 없앤다"]
    D --> E["스킴의 기본 포트면 포트를 뺀다"]
    E --> F["문자열로 비교"]

각 단계를 문서는 이렇게 적습니다. 스킴과 호스트는 대소문자를 가리지 않으므로 소문자로 정규화하기를 권합니다. 예약되지 않은 문자 집합에 드는 옥텟은 백분율 인코딩된 꼴에서 되돌리기를 권합니다. 점 세그먼트 . 과 .. 은 계층적 이름 해석을 위한 것이므로 없애기를 권합니다. 여기까지가 구문만 보고 하는 정규화입니다.

스킴이 더 아는 것이 있으면 한 칸 더 갑니다. 스킴은 기본 포트를 정의할 수 있습니다. http 스킴은 예약된 TCP(Transmission Control Protocol, 전송 제어 프로토콜) 포트 번호에 해당하는 80 을 기본 포트로 정의합니다. URI 를 만들거나 정규화하는 쪽은 포트가 비어 있거나 그 값이 스킴의 기본 포트와 같으면 포트 성분과 앞의 : 를 생략하기를 권합니다.

통계·머신러닝

scikit-learn 은 정규화를 개별 샘플이 단위 노름을 갖도록 스케일링하는 과정이라고 적습니다. 점곱 같은 이차 형식이나 다른 커널로 표본 쌍의 유사도를 잴 계획이라면 이 과정이 쓸모가 있을 수 있다고 적습니다. 전처리 모듈은 함수 한 줄로 부르는 길을 둡니다.

Python
X_normalized = preprocessing.normalize(X, norm='l2')

같은 동작을 트랜스포머 API(Application Programming Interface, 응용 프로그램 인터페이스)로 감싼 Normalizer 클래스도 있습니다. 이 클래스는 상태를 갖지 않습니다. 샘플을 서로 독립으로 다루기 때문에 fit 메서드가 할 일이 없다고 적혀 있습니다.

이 문서 안에서 표준화는 정규화와 다른 절입니다. StandardScaler 는 데이터셋의 특성을 가로질러 평균을 빼고 단위 분산으로 스케일링합니다. 특성 단위로 도는 변환입니다. Normalizer 는 샘플 단위로 돕니다. 축이 다르므로 두 말을 바꿔 쓰면 다른 결과가 나옵니다.

경계

정규 표현식의 정규도 이 표제어의 정규화인가. 아닙니다.

The Open Group Base Specifications 9장은 정규 표현식을 문자열 집합에서 특정 문자열을 골라내는 장치라고 정의합니다. 골라낼 대상을 나타내는 표기법이지, 입력을 정해진 형태로 바꾸는 절차가 아닙니다. 정규화는 값을 바꿔 놓고, 정규 표현식은 값을 그대로 둔 채 고릅니다. 그래서 이름의 정규가 겹쳐도 이 표제어에는 들지 않습니다.

관련 항목

관계형 데이터베이스 정규화가 거치는 정규형 단계

정규형 · 제1정규형 · 제2정규형 · 제3정규형 · 보이스코드 정규형 · 제5정규형

관계형 데이터베이스 정규화가 쓰는 키 종류

기본 키 · 외래 키 · 복합 키

관계형 데이터베이스 정규화가 없애는 문제

반복 그룹 · 중복 데이터 · 불일치 의존

유니코드가 정의하는 정규화 형식

NFC · NFD · NFKC · NFKD

유니코드 정규화 형식을 이루는 연산

정준 분해 · 정준 결합 · 호환 분해 · 유니코드 정규화 알고리즘 · 결합 표시

유니코드 정규화가 가르는 동등성

정준 동등 · 호환 동등 · 추상 문자

URI가 동등성을 재는 비교 사다리

URI 동등성 · 비교 사다리 · 구문 기반 정규화 · 스킴 기반 정규화

URI 구문 기반 정규화가 맞추는 표기

대소문자 정규화 · 백분율 인코딩 · 점 세그먼트

URI 스킴 기반 정규화가 살피는 요소

기본 포트 · 스킴 · 호스트 · http · TCP

통계·머신러닝 정규화가 겨냥하는 척도

단위 노름 · L2 노름 · 특징 스케일링 · 커널

scikit-learn이 정규화 곁에 두는 클래스와 개념

전처리 · Normalizer · StandardScaler · 표준화 · API

정규화 각 맥락의 근거가 되는 문서

Microsoft · UAX · RFC · scikit-learn

정규화와 이름이 겹치는 이웃

정규 표현식

다른 이름: normalization