กรณีศึกษา: ออกแบบฐานข้อมูลสำหรับระบบห้องสมุด
ในบทเรียนนี้ เราจะนำความรู้ทั้งหมดที่ได้เรียนรู้มาประยุกต์ใช้ในการออกแบบฐานข้อมูลสำหรับระบบห้องสมุด ซึ่งเป็นตัวอย่างที่ค่อนข้างซับซ้อนแต่ก็เข้าใจง่าย ช่วยให้เห็นภาพรวมของการออกแบบฐานข้อมูลได้ชัดเจนยิ่งขึ้น
1. วิเคราะห์ความต้องการของระบบห้องสมุด
ก่อนที่เราจะลงมือออกแบบฐานข้อมูล เราต้องทำความเข้าใจก่อนว่าระบบห้องสมุดต้องการอะไรบ้าง โดยทั่วไปแล้ว ระบบห้องสมุดควรมีความสามารถดังนี้:
- จัดการข้อมูลหนังสือ: ชื่อหนังสือ, ผู้แต่ง, ISBN, สำนักพิมพ์, ปีที่พิมพ์, หมวดหมู่, จำนวนหนังสือที่มี
- จัดการข้อมูลสมาชิก: ชื่อ, ที่อยู่, เบอร์โทรศัพท์, วันที่สมัครสมาชิก
- จัดการการยืม-คืนหนังสือ: บันทึกการยืม, วันที่ยืม, วันที่กำหนดส่งคืน, วันที่คืนจริง, ค่าปรับ (ถ้ามี)
- ค้นหาหนังสือ: ค้นหาตามชื่อหนังสือ, ผู้แต่ง, ISBN, หมวดหมู่
- รายงาน: สรุปจำนวนหนังสือที่มี, สรุปจำนวนหนังสือที่ถูกยืม, สรุปค่าปรับที่ได้รับ
นอกจากนี้ เราอาจพิจารณาเพิ่มความสามารถอื่นๆ เช่น:
- การจองหนังสือ: สมาชิกสามารถจองหนังสือที่ถูกยืมไปแล้วได้
- การจัดการผู้ดูแลระบบ: กำหนดสิทธิ์การเข้าถึงข้อมูลต่างๆ
- การแจ้งเตือน: แจ้งเตือนเมื่อหนังสือที่ยืมใกล้ถึงกำหนดส่งคืน
ในการออกแบบฐานข้อมูล เราจะเน้นความสามารถพื้นฐานที่กล่าวมาข้างต้นก่อน และอาจขยายเพิ่มเติมในอนาคตได้
2. สร้าง ERD สำหรับระบบห้องสมุด
จากความต้องการของระบบห้องสมุด เราสามารถสร้าง Entity Relationship Diagram (ERD) ได้ดังนี้:
Entities:
- หนังสือ (Book): ข้อมูลเกี่ยวกับหนังสือแต่ละเล่ม
- สมาชิก (Member): ข้อมูลเกี่ยวกับสมาชิกแต่ละคน
- การยืม (Loan): ข้อมูลเกี่ยวกับการยืมหนังสือ
- หมวดหมู่ (Category): ข้อมูลเกี่ยวกับหมวดหมู่ของหนังสือ
Relationships:
- หนังสือ (Book) มี หมวดหมู่ (Category) (One-to-Many: หนังสือหนึ่งเล่มอยู่ในหมวดหมู่เดียว, หมวดหมู่หนึ่งมีหนังสือได้หลายเล่ม)
- สมาชิก (Member) ยืม หนังสือ (Book) (Many-to-Many: สมาชิกหนึ่งคนสามารถยืมหนังสือได้หลายเล่ม, หนังสือหนึ่งเล่มสามารถถูกยืมโดยสมาชิกหลายคน) - Relationship นี้จะถูกแก้ให้เป็นตาราง Loan
- การยืม (Loan) เกี่ยวข้องกับ หนังสือ (Book) (Many-to-One: การยืมหนึ่งครั้งเกี่ยวข้องกับหนังสือหนึ่งเล่ม, หนังสือหนึ่งเล่มสามารถถูกยืมได้หลายครั้ง)
- การยืม (Loan) เกี่ยวข้องกับ สมาชิก (Member) (Many-to-One: การยืมหนึ่งครั้งเกี่ยวข้องกับสมาชิกหนึ่งคน, สมาชิกหนึ่งคนสามารถยืมหนังสือได้หลายครั้ง)
Attributes:
- หนังสือ (Book): ISBN (PK), ชื่อหนังสือ, ผู้แต่ง, สำนักพิมพ์, ปีที่พิมพ์, หมวดหมู่ (FK), จำนวนหนังสือที่มี
- สมาชิก (Member): MemberID (PK), ชื่อ, ที่อยู่, เบอร์โทรศัพท์, วันที่สมัครสมาชิก
- การยืม (Loan): LoanID (PK), MemberID (FK), ISBN (FK), วันที่ยืม, วันที่กำหนดส่งคืน, วันที่คืนจริง, ค่าปรับ
- หมวดหมู่ (Category): CategoryID (PK), ชื่อหมวดหมู่
คำอธิบาย:
- (PK) หมายถึง Primary Key ซึ่งเป็น attribute ที่ใช้ระบุ record แต่ละ record ในตารางนั้นๆ
- (FK) หมายถึง Foreign Key ซึ่งเป็น attribute ที่ใช้เชื่อมโยงไปยัง Primary Key ของตารางอื่น
เหตุผลเชิงออกแบบ:
- Relationship Many-to-Many ระหว่าง Member และ Book ถูกแก้ให้เป็นตาราง Loan เนื่องจากเราต้องการเก็บข้อมูลเพิ่มเติมเกี่ยวกับการยืม เช่น วันที่ยืม, วันที่กำหนดส่งคืน, และค่าปรับ
- เราใช้ ISBN เป็น Primary Key ของตาราง Book เนื่องจาก ISBN เป็น unique identifier ของหนังสือแต่ละเล่ม
3. ทำ Normalization ให้กับฐานข้อมูล
หลังจากที่เราได้ ERD แล้ว เราต้องทำการ Normalization เพื่อลดความซ้ำซ้อนของข้อมูลและปรับปรุงความถูกต้องของข้อมูล
ตารางที่ได้หลัง Normalization:
- Books: ISBN (PK), Title, Author, Publisher, PublicationYear, CategoryID (FK), Quantity
- Members: MemberID (PK), Name, Address, PhoneNumber, RegistrationDate
- Loans: LoanID (PK), MemberID (FK), ISBN (FK), LoanDate, DueDate, ReturnDate, Fine
- Categories: CategoryID (PK), CategoryName
เหตุผลเชิงออกแบบ:
- ตาราง Books เก็บข้อมูลเกี่ยวกับหนังสือ โดยมี ISBN เป็น Primary Key และ CategoryID เป็น Foreign Key ที่เชื่อมโยงไปยังตาราง Categories
- ตาราง Members เก็บข้อมูลเกี่ยวกับสมาชิก โดยมี MemberID เป็น Primary Key
- ตาราง Loans เก็บข้อมูลเกี่ยวกับการยืม โดยมี LoanID เป็น Primary Key, MemberID เป็น Foreign Key ที่เชื่อมโยงไปยังตาราง Members, และ ISBN เป็น Foreign Key ที่เชื่อมโยงไปยังตาราง Books
- ตาราง Categories เก็บข้อมูลเกี่ยวกับหมวดหมู่ของหนังสือ โดยมี CategoryID เป็น Primary Key
ข้อดีของการทำ Normalization:
- ลดความซ้ำซ้อนของข้อมูล: ข้อมูลที่ไม่จำเป็นจะไม่ถูกเก็บไว้ซ้ำๆ ในหลายตาราง
- ปรับปรุงความถูกต้องของข้อมูล: เมื่อมีการแก้ไขข้อมูล จะแก้ไขเพียงที่เดียว ทำให้ข้อมูลมีความสอดคล้องกัน
- เพิ่มประสิทธิภาพในการสืบค้นข้อมูล: การสืบค้นข้อมูลจะทำได้รวดเร็วขึ้น เนื่องจากข้อมูลถูกจัดเก็บอย่างเป็นระบบ
4. เลือก Data Types ที่เหมาะสม
ขั้นตอนสุดท้ายคือการเลือก Data Types ที่เหมาะสมสำหรับแต่ละ attribute ในแต่ละตาราง
ตาราง Books:
- ISBN: VARCHAR(20) (เก็บ ISBN ที่เป็นตัวเลขและตัวอักษร)
- Title: VARCHAR(255) (เก็บชื่อหนังสือ)
- Author: VARCHAR(255) (เก็บชื่อผู้แต่ง)
- Publisher: VARCHAR(255) (เก็บชื่อสำนักพิมพ์)
- PublicationYear: YEAR (เก็บปีที่พิมพ์)
- CategoryID: INT (เก็บ CategoryID ที่เป็นตัวเลข)
- Quantity: INT (เก็บจำนวนหนังสือที่มี)
ตาราง Members:
- MemberID: INT AUTO_INCREMENT (เก็บ MemberID ที่เป็นตัวเลขและเพิ่มขึ้นอัตโนมัติ)
- Name: VARCHAR(255) (เก็บชื่อสมาชิก)
- Address: TEXT (เก็บที่อยู่สมาชิก)
- PhoneNumber: VARCHAR(20) (เก็บเบอร์โทรศัพท์สมาชิก)
- RegistrationDate: DATE (เก็บวันที่สมัครสมาชิก)
ตาราง Loans:
- LoanID: INT AUTO_INCREMENT (เก็บ LoanID ที่เป็นตัวเลขและเพิ่มขึ้นอัตโนมัติ)
- MemberID: INT (เก็บ MemberID ที่เป็นตัวเลข)
- ISBN: VARCHAR(20) (เก็บ ISBN ที่เป็นตัวเลขและตัวอักษร)
- LoanDate: DATE (เก็บวันที่ยืม)
- DueDate: DATE (เก็บวันที่กำหนดส่งคืน)
- ReturnDate: DATE (เก็บวันที่คืนจริง, อาจเป็น NULL ถ้ายังไม่คืน)
- Fine: DECIMAL(10,2) (เก็บค่าปรับ)
ตาราง Categories:
- CategoryID: INT AUTO_INCREMENT (เก็บ CategoryID ที่เป็นตัวเลขและเพิ่มขึ้นอัตโนมัติ)
- CategoryName: VARCHAR(255) (เก็บชื่อหมวดหมู่)
เหตุผลเชิงออกแบบ:
- เราใช้ VARCHAR สำหรับเก็บข้อมูลที่เป็นข้อความ เนื่องจาก VARCHAR สามารถเก็บข้อความที่มีความยาวแตกต่างกันได้
- เราใช้ INT สำหรับเก็บข้อมูลที่เป็นตัวเลข เนื่องจาก INT สามารถเก็บตัวเลขจำนวนเต็มได้
- เราใช้ DATE สำหรับเก็บข้อมูลที่เป็นวันที่
- เราใช้ DECIMAL สำหรับเก็บข้อมูลที่เป็นตัวเลขทศนิยม เช่น ค่าปรับ
- เราใช้ AUTO_INCREMENT สำหรับ Primary Key ที่เป็นตัวเลข เพื่อให้ระบบสร้าง ID ให้อัตโนมัติ
- เราใช้ TEXT สำหรับเก็บข้อมูลที่ต้องการความยาวมากๆ เช่น ที่อยู่
- เราใช้ YEAR สำหรับเก็บปีที่พิมพ์ เพื่อประหยัดพื้นที่และเหมาะสมกับข้อมูล
ตัวอย่าง SQL Script สำหรับสร้างฐานข้อมูล:
CREATE TABLE Categories (
CategoryID INT AUTO_INCREMENT PRIMARY KEY,
CategoryName VARCHAR(255)
);
CREATE TABLE Books (
ISBN VARCHAR(20) PRIMARY KEY,
Title VARCHAR(255),
Author VARCHAR(255),
Publisher VARCHAR(255),
PublicationYear YEAR,
CategoryID INT,
Quantity INT,
FOREIGN KEY (CategoryID) REFERENCES Categories(CategoryID)
);
CREATE TABLE Members (
MemberID INT AUTO_INCREMENT PRIMARY KEY,
Name VARCHAR(255),
Address TEXT,
PhoneNumber VARCHAR(20),
RegistrationDate DATE
);
CREATE TABLE Loans (
LoanID INT AUTO_INCREMENT PRIMARY KEY,
MemberID INT,
ISBN VARCHAR(20),
LoanDate DATE,
DueDate DATE,
ReturnDate DATE,
Fine DECIMAL(10,2),
FOREIGN KEY (MemberID) REFERENCES Members(MemberID),
FOREIGN KEY (ISBN) REFERENCES Books(ISBN)
);
สรุป:
ในบทเรียนนี้ เราได้นำความรู้ทั้งหมดที่ได้เรียนรู้มาประยุกต์ใช้ในการออกแบบฐานข้อมูลสำหรับระบบห้องสมุด ซึ่งประกอบด้วยการวิเคราะห์ความต้องการ, การสร้าง ERD, การทำ Normalization, และการเลือก Data Types ที่เหมาะสม หวังว่าบทเรียนนี้จะเป็นประโยชน์ในการเริ่มต้นออกแบบฐานข้อมูลของคุณ