0

저는이 사실을 잘 이해하지 못합니다. 나는 인터넷에서 많은 예를 보지만 이유에 대한 설명이 부족하다. 예를 들어 애플리케이션, 고객 및 관리자에 두 종류의 사용자가 있습니다. 사용자 테이블에 "user_type"열을 통합하는 대신 별도의 "user_type"테이블을 만드는 이점은 무엇입니까? 또 다른 예는 제품 테이블에 범주 필드를 넣는 대신 제품 카테고리에 대해 별도의 테이블을 작성하는 것입니다. 나는이 문제에 대해 정말로 머리를 쓰지 못한다. db 정규화의 이점은 무엇입니까? 그리고 데이터베이스의 중복 데이터의 단점은 무엇입니까?데이터베이스 정규화의 이점은 무엇입니까?

+1

단일 열 대신에 user_type 테이블을 생성하는 것은 정규화와 아무 관련이 없습니다. – sqlvogel

답변

0

정규화의 명시된 목적은 비정상적인 데이터가 데이터베이스에 들어 가지 않도록 방지하는 것입니다.

같은 매우 간단한 사용자 엔티티를 가지고 : 관리자 (M) 또는 페온 (P) :

create table Users(
    ID  int auto_generated primary key, 
    LastName varchar(16) not null, 
    FirstName varchar(16) not null 
); 

은 이제 두 가지 유형의 사용자가있을 수 있습니다 밝혀졌습니다. 또한 관리자의 경우, 얼마나 많은 사람들이 자신에게 직접보고하고 있는지, 그리고 peons에 관해서는 포크 리프트 라이센스가 있는지 알아야합니다. 테이블에 그냥 던지겠습니다 :

create table Users(
    ID   int auto_generated primary key, 
    LastName  varchar(16) not null, 
    FirstName varchar(16) not null, 
    UserType  char(1) not null, 
    DirectReps int, 
    HasFLLicense boolean 
); 

이렇게하면 모든 종류의 알람이 시작됩니다. 무엇이 잘못 될 수 있습니까?

  • 이 시점에서 UserType의 유효한 값은 'M'또는 'P'뿐입니다. 그러나이 필드에는 단일 문자가 포함될 수 있습니다. 이 칼럼에 "check"를 만들 수 있지만, 그것은 나중에 다룰 다른 문제를 만들 것입니다.
  • DirectReps 및 HasFLLicense 필드는 UserType 필드에 각각 'M'또는 'P'가 포함 된 경우에만 사용할 수 있습니다. 내부적으로이를 시행 할 방법이 없습니다. 트리거 및/또는 앱 코드를 사용하여 수행해야합니다.

이러한 새로운 제약 조건을 적용하는 쉬운 방법은 없습니다. 그리고 우리는 조심스럽게 우리가 조만간 'M'또는 'P'이외의 UserType 값 및/또는 DirectReps 또는 HasFLLicense의 값을 부적절하게 가질 것이라는 것을 알고 있습니다. 이것은 비정상적인 데이터입니다.

필드를 자세히 보면 LastName, FirstName 및 UserType 필드는 ID에만 기능적으로 종속됩니다. 그러나 DirectReps 및 HasFLLicense는 UserType에도 종속됩니다. 이 새 테이블은 2nf가 아닙니다.

이 테이블을 정규화하는 방법은 여러 가지가 있으므로 여기서는 다루지 않을 것입니다. (Here은 오늘 발표 한 한 가지 방법입니다.) UserType 값이 'M'이고 UserType 값이 'P'가 아니면 HasFLLicense 값이 존재하지 않으면 DirectReps 값이 존재할 수 없도록 최종 결과가 수행되어야합니다. .

이제 막 정규화 된 테이블을 살펴 보자 :

또한 테이블에서 UserType 필드를 제거하지만,의 지금 여기를 떠나게되는 일부 정규화 방법이 있습니다
create table Users(
    ID   int auto_generated primary key, 
    LastName  varchar(16) not null, 
    FirstName varchar(16) not null, 
    UserType  char(1) check(UserType in('M', 'P') 
); 

.다음 위치에 관계없이 다음 사항이 적용됩니다.

머지 않아 세 번째 유형이 필요할 것이라고 생각하면 문제가 나타납니다. 그리고 다른 점에서 또 다른 점에서 또 다른 점에서 당신은 아이디어를 얻습니다. 매번 점검 제한 조건을 다시 쓰기 위해 alter table 명령을 발행해야합니다. 이것은 거실 소파를 대체하기 위해 집을 완전히 철거하고 재건하는 것과 같습니다. 이 테이블 (뷰 포함)에 액세스하는 모든 코드는 최소한 재 컴파일되어야하며 재 작성되어야합니다. 그것을 직시하자. alter table은 사소한 작업이다.

모든 사용자 유형에 대한 기록을 포함하는 조회 테이블이 방법 훨씬 더 : 그런 다음 UserType 필드가 정의 될 수

create table UserTypes(
    ID  char(1) not null primary key, -- 'M' or 'P' or whatever 
    Name varchar(16) not null, -- "Manager" or "Peon" or whatever 
    ...  -- other possible attributes 
); 

:

UserType  char(1) not null references UserTypes(ID) 

지금 유형을 추가하는 'A'또는 'F'또는 UserTypes 테이블에 레코드를 삽입하기 만하면됩니다. 기존 코드는 영향을받지 않습니다. 물론 앱 코드는 궁극적으로 새로운 유형을 처리하기 위해 변경되어야하지만 앱 개발자는 지금 여가 시간에이 작업을 수행 할 수 있습니다.

현재 요구 사항에 맞게 설계하지 마십시오. 또한 합리적으로 예상되는 미래 요구 사항에 맞게 설계하십시오.

1

중복 데이터의 단점은 데이터의 모든 복사본이 어디에 있는지 기억하고 정보가 변경 될 때 모두 업데이트해야한다는 것입니다. 정규화는 별도의 테이블을 만드는 것보다 중복 제거에 관한 것입니다.

예를 들어 user_type의 경우 user 테이블의 열에 넣을 수 있습니다. 사용자가 여러 사용자 유형을 가질 수있는 경우 추가 표가 편리합니다.

관련 문제