정규화
테이블 및 테이블 간 관계를 포함하여 데이터베이스의 논리적 디자인은 최적화된 관계형 데이터베이스의 핵심 부분입니다. 논리적 데이터베이스의 디자인이 확실하면 데이터베이스를 최적화하며 프로그램의 성능을 높일 수 있습니다. 논리적 데이터베이스 디자인이 조악하면 전체 시스템의 성능이 떨어질 수 있습니다.
논리적 데이터베이스 디자인 정규화에는 형식적인 방법을 사용하여 데이터를 여러 개의 관련 테이블로 분리하는 작업이 포함됩니다. 열 개수가 적은 좁은 테이블 여러 개로 구성되는 것이 정규화된 데이터베이스의 특징입니다. 정규화되지 않은 데이터베이스는 열 개수가 많은 여러 개의 넓은 테이블로 구성되어 있습니다.
적절하게 정규화된 데이터베이스는 성능이 향상됩니다. 유용한 인덱스가 있는 경우 SQL Server 쿼리 최적화 프로그램을 사용하면 신속하고 효율적인 테이블 간의 조인을 효과적으로 선택할 수 있습니다.
정규화의 장점은 다음과 같습니다.
- 정렬과 인덱스 생성 속도가 빨라집니다.
- 클러스터형 인덱스가 많아집니다. 자세한 내용은 클러스터형 인덱스 디자인 지침을 참조하십시오.
- 인덱스가 좁아지고 압축됩니다.
- 테이블당 인덱스 수가 적어집니다. 그 결과 INSERT, UPDATE 및 DELETE 문의 성능이 향상됩니다.
- Null 값이 적어지고 불일치가 발생하는 상황이 줄어듭니다. 그 결과 데이터베이스 압축성이 증가합니다.
정규화가 증가할수록 데이터를 검색하는 데 필요한 조인 수와 복잡성도 따라서 증가합니다. 너무 많은 테이블 간에 복잡한 관계 조인을 너무 많이 사용하면 성능에 문제가 생길 수 있습니다. 적절하게 정규화되면 정기적으로 실행되는 쿼리에서 5개 이상의 테이블을 포함하는 조인을 사용하는 경우는 거의 없습니다.
때때로 논리적 데이터베이스 디자인이 이미 정해져 있어서 전체적으로 다시 디자인하는 것은 현실적이지 않을 수 있습니다. 그런 경우에도 큰 테이블을 선택적으로 여러 개의 작은 테이블로 정규화할 수 있습니다. 저장 프로시저를 통해 데이터베이스에 액세스하는 경우 응용 프로그램에 영향을 주지 않고 이 스키마를 변경할 수 있습니다. 그렇지 않은 경우 뷰를 만들어 응용 프로그램으로부터 스키마 변경을 숨길 수 있습니다.
잘 디자인된 데이터베이스 만들기
관계형 데이터베이스 디자인 이론에서는 정규화 규칙을 통해 잘 디자인된 데이터베이스에 있거나 없어야 되는 특정 특성을 파악할 수 있습니다. 정규화 규칙에 대한 자세한 설명은 이 항목에서는 다루지 않습니다. 그러나 데이터베이스를 확실하게 디자인하는 데 도움이 되는 몇 가지 규칙이 있습니다.
- 테이블에는 식별자가 있어야 합니다.
데이터베이스 디자인 이론의 기본 규칙은 각 테이블에 고유한 행 식별자, 즉 한 레코드를 테이블의 다른 모든 레코드와 구별하는 데 사용되는 한 열 또는 열 집합이 있어야 한다는 것입니다. 테이블마다 ID 열이 있어야 하며 두 레코드가 같은 ID 값을 공유할 수 없습니다. 테이블의 고유한 행 식별자 역할을 수행하는 열이나 열 집합은 테이블의 기본 키가 됩니다. AdventureWorks 데이터베이스에서 각 테이블에는 ID 열이 기본 키 열로 포함되어 있습니다. 예를 들어 VendorID는 Purchasing.Vendor 테이블의 기본 키입니다. - 테이블은 단일 엔터티 유형의 데이터만 저장해야 합니다.
테이블에 너무 많은 정보를 저장하면 테이블의 데이터를 효율적이고 안정적으로 관리할 수 없습니다. AdventureWorks 예제 데이터베이스에서 판매 주문 및 고객 정보는 각각 개별 테이블에 저장됩니다. 판매 주문과 고객 모두에 대한 정보를 포함하는 열이 단일 테이블에 있도록 디자인할 수 있으나 몇 가지 문제가 발생합니다. 각 판매 주문에 대해 고객 정보, 이름 및 주소를 중복하여 추가하고 저장해야 합니다. 따라서 데이터베이스 저장 공간이 추가로 사용됩니다. 고객 주소가 변경되면 각 판매 주문에 대해 이 변경 내용을 적용해야 합니다. 또한 Sales.SalesOrderHeader 테이블에서 고객의 이전 판매 주문이 제거되면 해당 고객의 정보도 없어집니다. - 테이블에서 Null 허용 열을 피해야 합니다.
테이블에 Null 값을 허용하도록 정의된 열이 있을 수 있습니다. Null 값은 값이 없다는 뜻입니다. 일부 경우에는 Null 값을 허용하는 것이 유용할 수도 있으나, 일반적으로 Null 값 사용을 자제해야 합니다. 이는 복잡한 데이터 작업이 가중되는 특별한 처리가 필요하기 때문입니다. 테이블에 Null 값을 허용하는 열이 몇 개 있고 이러한 열에 Null 값이 들어 있는 행이 몇 개 있는 경우 이러한 열은 기본 테이블과 연결된 다른 테이블에 넣으십시오. 데이터를 두 테이블에 따로 저장하면 기본 테이블의 디자인이 단순해짐은 물론 이러한 정보를 저장해야 하는 경우도 처리할 수 있습니다. - 테이블에 반복 값이나 열이 포함되지 않아야 합니다.
데이터베이스의 항목에 대한 테이블에는 특정 정보에 대해 값이 여러 개 있으면 안 됩니다. 예를 들어 AdventureWorks 데이터베이스의 제품은 여러 공급업체에서 구입할 수 있습니다. Production.Product 테이블에 공급업체 이름에 대한 열이 있는 경우 문제가 발생합니다. 한 가지 해결 방법은 모든 공급업체 이름을 하나의 열에 저장하는 것입니다. 그러나 이렇게 하면 개별 공급업체 목록을 표시하기 어렵습니다. 다른 해결 방법은 테이블 구조를 변경하여 두 번째 공급업체의 이름을 저장할 다른 열을 추가하는 것입니다. 그러나 이 경우 두 개의 공급업체만 허용됩니다. 또한 장부에 세 번째 공급업체가 있으면 또 다른 열을 추가해야 합니다.
하나의 열에 값 목록을 저장해야 하거나 단일 데이터에 대해 TelephoneNumber1 및 TelephoneNumber2와 같이 여러 개의 열이 있는 경우 중복 데이터를 기본 테이블과 연결된 다른 테이블에 넣으십시오. AdventureWorks 데이터베이스에는 제품 정보에 대한 Production.Product 테이블, 공급업체 정보에 대한 Purchasing.Vendor 테이블 및 세 번째 테이블인 Purchasing.ProductVendor가 있습니다. 이 세 번째 테이블에는 제품에 대한 ID 값과 제품 공급업체의 ID만 저장됩니다. 이렇게 디자인하면 테이블 정의를 수정하지 않고 또한 단일 공급업체의 여러 제품에 대해 불필요한 저장 공간을 할당하지 않고도 제품의 공급업체를 무제한으로 추가할 수 있습니다.
참고 항목
관련 자료
AdventureWorks 예제 OLTP 데이터베이스
데이터베이스 디자인