Normalization คืออะไร? ทำไมต้องทำ Normalization?
จากบทที่แล้ว เราได้เรียนรู้เกี่ยวกับการสร้าง Entity Relationship Diagram (ERD) เพื่อออกแบบโครงสร้างฐานข้อมูลของเรา แต่การมี ERD ที่ดีก็ยังไม่เพียงพอที่จะรับประกันว่าฐานข้อมูลของเราจะมีประสิทธิภาพและปราศจากปัญหา การทำ Normalization คือขั้นตอนสำคัญที่จะช่วยให้เราบรรลุเป้าหมายนั้น
Normalization คืออะไร?
Normalization คือกระบวนการจัดระเบียบข้อมูลในฐานข้อมูลเพื่อลดความซ้ำซ้อน (Redundancy) และกำจัดความไม่สอดคล้องกัน (Inconsistency) ของข้อมูล กล่าวอีกนัยหนึ่งคือ การทำให้มั่นใจว่าข้อมูลแต่ละส่วนถูกเก็บไว้ในที่ที่ควรอยู่เท่านั้น และไม่มีข้อมูลที่ซ้ำซ้อนกันในหลายตาราง
ทำไมต้องทำ Normalization?
การทำ Normalization มีประโยชน์มากมาย ดังนี้:
- ลดความซ้ำซ้อนของข้อมูล: ช่วยลดพื้นที่จัดเก็บข้อมูลโดยการกำจัดข้อมูลที่ซ้ำซ้อน
- ป้องกันความไม่สอดคล้องกันของข้อมูล: เมื่อข้อมูลถูกเก็บไว้ในที่เดียว การแก้ไขข้อมูลจะง่ายขึ้นและลดโอกาสที่ข้อมูลในตารางต่างๆ จะไม่สอดคล้องกัน
- ปรับปรุงความสมบูรณ์ของข้อมูล: ช่วยให้มั่นใจได้ว่าข้อมูลถูกต้องและเชื่อถือได้
- เพิ่มประสิทธิภาพในการสืบค้นข้อมูล: โครงสร้างฐานข้อมูลที่ดีจะช่วยให้การสืบค้นข้อมูลทำได้รวดเร็วและมีประสิทธิภาพมากขึ้น
- ทำให้การบำรุงรักษาง่ายขึ้น: การเปลี่ยนแปลงโครงสร้างฐานข้อมูลจะทำได้ง่ายขึ้นเมื่อฐานข้อมูลถูกออกแบบมาอย่างดี
ลองจินตนาการถึงตารางข้อมูลพนักงานที่เก็บข้อมูลชื่อ, ที่อยู่, แผนก, และชื่อหัวหน้างาน หากข้อมูลหัวหน้างานถูกเก็บไว้ในทุกแถวของพนักงานในแผนกนั้น ข้อมูลจะซ้ำซ้อนอย่างมาก และหากมีการเปลี่ยนแปลงชื่อหัวหน้างาน เราจะต้องแก้ไขข้อมูลในทุกแถวของพนักงานในแผนกนั้น ซึ่งเป็นเรื่องที่ยุ่งยากและมีโอกาสผิดพลาดสูง การทำ Normalization จะช่วยแก้ไขปัญหานี้ได้
รูปแบบ Normal Form ต่างๆ
Normalization มีหลายรูปแบบ (Normal Form) แต่ในระดับเริ่มต้น เราจะเน้นที่ 3 รูปแบบหลักๆ คือ 1NF, 2NF, และ 3NF
1NF (First Normal Form)
ตารางจะอยู่ใน 1NF หากทุกแอตทริบิวต์ (Attribute) มีค่าเป็นอะตอมมิก (Atomic) นั่นคือไม่สามารถแบ่งย่อยได้อีก
ตัวอย่าง:
ตาราง `Products` (ยังไม่เป็น 1NF)
ProductID | ProductName | Categories
----------|-------------|------------------
1 | Laptop | Electronics, Computers
2 | T-Shirt | Clothing, Fashion
ในตารางนี้ แอตทริบิวต์ `Categories` ไม่เป็นอะตอมมิก เพราะมีหลายค่าคั่นด้วยเครื่องหมาย "," เราสามารถแก้ไขให้เป็น 1NF ได้ดังนี้:
ตาราง `Products` (เป็น 1NF)
ProductID | ProductName | Category
----------|-------------|------------
1 | Laptop | Electronics
1 | Laptop | Computers
2 | T-Shirt | Clothing
2 | T-Shirt | Fashion
หรืออีกวิธีที่ดีกว่าคือการสร้างตาราง `Categories` แยกออกมา:
ตาราง `Products` (เป็น 1NF และเตรียมพร้อมสำหรับ Normal Form ที่สูงขึ้น)
ProductID | ProductName
----------|-------------
1 | Laptop
2 | T-Shirt
ตาราง `Categories`
CategoryID | CategoryName
-----------|---------------
1 | Electronics
2 | Computers
3 | Clothing
4 | Fashion
ตาราง `ProductCategories` (ตารางเชื่อมความสัมพันธ์ Many-to-Many)
ProductID | CategoryID
----------|-------------
1 | 1
1 | 2
2 | 3
2 | 4
2NF (Second Normal Form)
ตารางจะอยู่ใน 2NF หากเป็น 1NF และทุกแอตทริบิวต์ที่ไม่ใช่ Primary Key ขึ้นอยู่กับ Primary Key ทั้งหมด
ตัวอย่าง:
ตาราง `OrderDetails` (ยังไม่เป็น 2NF)
OrderID | ProductID | ProductName | Quantity | Price
--------|-----------|-------------|----------|-------
1 | 1 | Laptop | 1 | 1200
1 | 2 | Mouse | 2 | 25
2 | 1 | Laptop | 1 | 1200
ในตารางนี้ Primary Key คือ `(OrderID, ProductID)` แต่ `ProductName` ขึ้นอยู่กับ `ProductID` เพียงอย่างเดียว ไม่ได้ขึ้นอยู่กับ `OrderID` ดังนั้นจึงไม่เป็น 2NF เราสามารถแก้ไขได้ดังนี้:
ตาราง `OrderDetails` (เป็น 2NF)
OrderID | ProductID | Quantity | Price
--------|-----------|----------|-------
1 | 1 | 1 | 1200
1 | 2 | 2 | 25
2 | 1 | 1 | 1200
ตาราง `Products`
ProductID | ProductName
----------|-------------
1 | Laptop
2 | Mouse
3NF (Third Normal Form)
ตารางจะอยู่ใน 3NF หากเป็น 2NF และไม่มีแอตทริบิวต์ที่ไม่ใช่ Primary Key ขึ้นอยู่กับแอตทริบิวต์อื่นที่ไม่ใช่ Primary Key (Transitive Dependency)
ตัวอย่าง:
ตาราง `Employees` (ยังไม่เป็น 3NF)
EmployeeID | EmployeeName | DepartmentID | DepartmentName
-----------|--------------|--------------|----------------
1 | John Doe | 1 | Sales
2 | Jane Smith | 2 | Marketing
ในตารางนี้ `DepartmentName` ขึ้นอยู่กับ `DepartmentID` ซึ่งไม่ใช่ Primary Key ดังนั้นจึงไม่เป็น 3NF เราสามารถแก้ไขได้ดังนี้:
ตาราง `Employees` (เป็น 3NF)
EmployeeID | EmployeeName | DepartmentID
-----------|--------------|--------------
1 | John Doe | 1
2 | Jane Smith | 2
ตาราง `Departments`
DepartmentID | DepartmentName
-------------|----------------
1 | Sales
2 | Marketing
ตัวอย่างการทำ Normalization
สมมติว่าเรามีตาราง `Orders` ที่เก็บข้อมูลการสั่งซื้อสินค้า:
ตาราง `Orders` (ยังไม่ Normalization)
OrderID | CustomerID | CustomerName | CustomerAddress | ProductID | ProductName | Quantity | Price
--------|------------|--------------|-----------------|-----------|-------------|----------|-------
1 | 101 | Alice Smith | 123 Main St | 1 | Laptop | 1 | 1200
2 | 102 | Bob Johnson | 456 Oak Ave | 2 | Mouse | 2 | 25
1 | 101 | Alice Smith | 123 Main St | 2 | Mouse | 1 | 25
เราสามารถทำ Normalization ได้ดังนี้:
- 1NF: ทุกแอตทริบิวต์เป็นอะตอมมิกแล้ว
- 2NF: แยกตาราง `Customers` และ `Products` ออกมา
- 3NF: ไม่มี Transitive Dependency
ตาราง `Orders` (หลัง Normalization)
OrderID | CustomerID
--------|------------
1 | 101
2 | 102
ตาราง `OrderDetails` (หลัง Normalization)
OrderID | ProductID | Quantity | Price
--------|-----------|----------|-------
1 | 1 | 1 | 1200
1 | 2 | 1 | 25
2 | 2 | 2 | 25
ตาราง `Customers` (หลัง Normalization)
CustomerID | CustomerName | CustomerAddress
-----------|--------------|-----------------
101 | Alice Smith | 123 Main St
102 | Bob Johnson | 456 Oak Ave
ตาราง `Products` (หลัง Normalization)
ProductID | ProductName
----------|-------------
1 | Laptop
2 | Mouse
ข้อผิดพลาดที่พบบ่อยในการทำ Normalization
- Over-Normalization: การทำ Normalization มากเกินไปอาจทำให้การสืบค้นข้อมูลซับซ้อนและช้าลง
- Under-Normalization: การไม่ทำ Normalization อาจทำให้เกิดความซ้ำซ้อนของข้อมูลและปัญหาความไม่สอดคล้องกัน
- การไม่เข้าใจความสัมพันธ์ของข้อมูล: การออกแบบฐานข้อมูลที่ดีต้องเข้าใจความสัมพันธ์ของข้อมูลอย่างถูกต้อง
ในบทต่อไป เราจะเรียนรู้เกี่ยวกับการเลือก Data Types ที่เหมาะสมกับข้อมูล เพื่อให้มั่นใจว่าข้อมูลของเราถูกเก็บไว้อย่างถูกต้องและมีประสิทธิภาพ