데이터베이스 설계에서 정규화(Normalization)와 반정규화(Denormalization)는 데이터 구조를 최적화하기 위한 중요한 개념이다. 이 글에서는 정규화와 반정규화의 개념을 설명한다.
정의:
모든 속성이 원자값을 가져야 하며, 각 열이 하나의 값만을 가져야 한다. 즉, 테이블 내의 각 필드는 단일 값을 가져야 하며, 중첩된 테이블이나 반복되는 그룹이 없어야 한다.
예제:
Oracle:
-- 1NF: 고객 테이블
CREATE TABLE Customers (
CustomerID NUMBER PRIMARY KEY,
CustomerName VARCHAR2(50),
CustomerPhone VARCHAR2(15)
);
MySQL:
-- 1NF: 고객 테이블
CREATE TABLE Customers (
CustomerID INT PRIMARY KEY,
CustomerName VARCHAR(50),
CustomerPhone VARCHAR(15)
);
SQL Server:
-- 1NF: 고객 테이블
CREATE TABLE Customers (
CustomerID INT PRIMARY KEY,
CustomerName NVARCHAR(50),
CustomerPhone NVARCHAR(15)
);
정의:
1NF를 만족하고, 부분 종속성을 제거하여 기본키의 모든 부분집합에 종속적인 속성을 제거한다. 기본키가 단일 속성인 경우 2NF는 자동으로 만족된다.
예제:
Oracle:
-- 2NF: 고객 테이블과 주문 테이블
CREATE TABLE Orders (
OrderID NUMBER PRIMARY KEY,
OrderDate DATE,
CustomerID NUMBER,
FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID)
);
MySQL:
-- 2NF: 고객 테이블과 주문 테이블
CREATE TABLE Orders (
OrderID INT PRIMARY KEY,
OrderDate DATE,
CustomerID INT,
FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID)
);
SQL Server:
-- 2NF: 고객 테이블과 주문 테이블
CREATE TABLE Orders (
OrderID INT PRIMARY KEY,
OrderDate DATE,
CustomerID INT,
FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID)
);
정의:
2NF를 만족하고, 이행 종속성을 제거한다. 즉, 기본키가 아닌 모든 속성이 기본키에만 의존해야 하며, 다른 비기본키 속성에 종속되어서는 안 된다.
예제:
Oracle:
-- 3NF: 주문 테이블과 제품 테이블
CREATE TABLE Products (
ProductID NUMBER PRIMARY KEY,
ProductName VARCHAR2(50),
Price NUMBER
);
CREATE TABLE OrderDetails (
OrderDetailID NUMBER PRIMARY KEY,
OrderID NUMBER,
ProductID NUMBER,
Quantity NUMBER,
FOREIGN KEY (OrderID) REFERENCES Orders(OrderID),
FOREIGN KEY (ProductID) REFERENCES Products(ProductID)
);
MySQL:
-- 3NF: 주문 테이블과 제품 테이블
CREATE TABLE Products (
ProductID INT PRIMARY KEY,
ProductName VARCHAR(50),
Price DECIMAL(10, 2)
);
CREATE TABLE OrderDetails (
OrderDetailID INT PRIMARY KEY,
OrderID INT,
ProductID INT,
Quantity INT,
FOREIGN KEY (OrderID) REFERENCES Orders(OrderID),
FOREIGN KEY (ProductID) REFERENCES Products(ProductID)
);
SQL Server:
-- 3NF: 주문 테이블과 제품 테이블
CREATE TABLE Products (
ProductID INT PRIMARY KEY,
ProductName NVARCHAR(50),
Price DECIMAL(10, 2)
);
CREATE TABLE OrderDetails (
OrderDetailID INT PRIMARY KEY,
OrderID INT,
ProductID INT,
Quantity INT,
FOREIGN KEY (OrderID) REFERENCES Orders(OrderID),
FOREIGN KEY (ProductID) REFERENCES Products(ProductID)
);
반정규화는 정규화된 데이터베이스 구조를 성능 향상 또는 특정 비즈니스 요구를 충족시키기 위해 의도적으로 중복을 허용하는 구조로 변경하는 과정이다. 반정규화는 데이터베이스의 읽기 성능을 향상시키지만, 데이터 무결성을 유지하는 것이 더 어려워질 수 있다. 일반적으로 데이터 읽기 성능을 높이기 위해 반정규화를 적용한다.
Oracle:
-- 반정규화: 고객과 주문 정보를 하나의 테이블에 저장
CREATE TABLE CustomerOrders (
CustomerID NUMBER,
CustomerName VARCHAR2(50),
CustomerPhone VARCHAR2(15),
OrderID NUMBER,
OrderDate DATE,
ProductID NUMBER,
ProductName VARCHAR2(50),
Quantity NUMBER,
PRIMARY KEY (OrderID, ProductID)
);
MySQL:
-- 반정규화: 고객과 주문 정보를 하나의 테이블에 저장
CREATE TABLE CustomerOrders (
CustomerID INT,
CustomerName VARCHAR(50),
CustomerPhone VARCHAR(15),
OrderID INT,
OrderDate DATE,
ProductID INT,
ProductName VARCHAR(50),
Quantity INT,
PRIMARY KEY (OrderID, ProductID)
);
SQL Server:
-- 반정규화: 고객과 주문 정보를 하나의 테이블에 저장
CREATE TABLE CustomerOrders (
CustomerID INT,
CustomerName NVARCHAR(50),
CustomerPhone NVARCHAR(15),
OrderID INT,
OrderDate DATE,
ProductID INT,
ProductName NVARCHAR(50),
Quantity INT,
PRIMARY KEY (OrderID, ProductID)
);
정규화는 데이터베이스 설계의 기본 원칙으로, 데이터 무결성과 중복 최소화를 목표로 한다. 그러나 때로는 성능 향상이나 특정 비즈니스 요구를 위해 반정규화가 필요할 수 있다. 이러한 방법을 잘 활용하면 효율적이고 성능 좋은 데이터베이스 시스템을 구축할 수 있다.