🎯 Mục tiêu bài học
Sau bài học này, bạn sẽ:
✅ Hiểu Database là gì, RDBMS hoạt động ra sao và tại sao dùng nó
✅ Phân biệt các Data Types phổ biến trong SQL Server
✅ Nắm vững Primary Key, Foreign Key, Composite Key và Relationships
✅ Áp dụng Constraints để bảo vệ tính toàn vẹn dữ liệu
✅ Hiểu Normalization (1NF → 2NF → 3NF) để thiết kế database tốt
✅ Đọc hiểu Schema và Data Dictionary của một database thực tế
Thời gian: 1.5 giờ | Độ khó: Beginner | Yêu cầu: Không
📖 Bảng Thuật Ngữ Quan Trọng
| Thuật ngữ | Tiếng Việt | Mô tả |
|---|---|---|
| Database | Cơ sở dữ liệu | Kho chứa dữ liệu có tổ chức |
| RDBMS | Hệ quản trị CSDL quan hệ | Phần mềm quản lý database theo mô hình bảng |
| Table | Bảng | Cấu trúc lưu dữ liệu theo hàng và cột |
| Row (Record) | Hàng (Bản ghi) | Một đối tượng/thực thể trong bảng |
| Column (Field) | Cột (Trường) | Một thuộc tính của đối tượng |
| Primary Key (PK) | Khóa chính | Cột định danh duy nhất mỗi row |
| Foreign Key (FK) | Khóa ngoại | Cột tham chiếu đến PK bảng khác |
| Constraint | Ràng buộc | Quy tắc bắt buộc dữ liệu phải tuân theo |
| Data Type | Kiểu dữ liệu | Loại giá trị cột có thể chứa (INT, VARCHAR...) |
| Schema | Lược đồ | Nhóm logic để tổ chức các bảng |
| Normalization | Chuẩn hóa | Quy trình loại bỏ dữ liệu dư thừa |
| Data Dictionary | Từ điển dữ liệu | Tài liệu mô tả cấu trúc database |
| ERD | Sơ đồ quan hệ thực thể | Biểu đồ thể hiện tables và relationships |
Checkpoint
Database = "kho chứa dữ liệu có tổ chức". RDBMS = "phần mềm quản lý kho đó". Bạn phân biệt được 2 khái niệm này chưa?
💡 1. Database là gì?
📚 Định nghĩa
Database (Cơ sở dữ liệu) là tập hợp dữ liệu được tổ chức, lưu trữ và quản lý một cách có hệ thống để có thể truy xuất, cập nhật và phân tích dễ dàng.
💡 Ý nghĩa — Tại sao cần Database?
Hãy tưởng tượng bạn quản lý thông tin 10,000 khách hàng:
| Không có Database | Có Database |
|---|---|
| Lưu trong Excel, dễ trùng lặp | Mỗi khách hàng có ID duy nhất |
| Nhiều file rời rạc, không liên kết | Các bảng liên kết chặt chẽ qua Keys |
| Ai cũng sửa được, không kiểm soát | Phân quyền truy cập, có ràng buộc dữ liệu |
| Chậm khi tìm kiếm | Index giúp truy vấn hàng triệu records trong milliseconds |
| Không thể phân tích phức tạp | SQL cho phép phân tích đa chiều |
🏢 Ứng dụng thực tế
- 🏦 Ngân hàng: Quản lý tài khoản, giao dịch, khoản vay
- 🛒 E-commerce: Sản phẩm, đơn hàng, khách hàng, thanh toán
- 🏥 Bệnh viện: Hồ sơ bệnh nhân, lịch khám, đơn thuốc
- 📊 Data Analytics: Data warehouse cho phân tích kinh doanh
1.4 RDBMS — Relational Database Management System
RDBMS là phần mềm quản lý database theo mô hình quan hệ (relational model):
- Dữ liệu được tổ chức thành tables (bảng)
- Các bảng liên kết với nhau qua keys (khóa)
- Truy vấn bằng ngôn ngữ SQL (Structured Query Language)
| RDBMS | Nhà phát triển | Đặc điểm |
|---|---|---|
| SQL Server | Microsoft | Enterprise-grade, tích hợp Azure, T-SQL |
| PostgreSQL | Open Source | Mạnh mẽ, mở rộng tốt, ANSI SQL |
| MySQL | Oracle | Phổ biến nhất, phù hợp web apps |
| Oracle DB | Oracle | Enterprise, banking, telco |
Khóa này dùng SQL Server vì: (1) Tích hợp BI tools mạnh (SSRS, SSAS, SSIS), (2) T-SQL có nhiều functions hữu ích cho analytics, (3) Azure-ready cho cloud analytics, (4) Được dùng rộng rãi trong doanh nghiệp Việt Nam.
Checkpoint
RDBMS lưu dữ liệu theo bảng (tables). Các bảng liên kết qua khóa (keys). Truy vấn bằng SQL. Ba khái niệm này là nền tảng — bạn ghi nhớ chưa?
📊 2. Table, Row, Column — Cấu trúc cơ bản
📚 Định nghĩa
Một Table (bảng) là đơn vị lưu trữ chính trong RDBMS:
| EmpID (INT) | FirstName (VARCHAR) | LastName (VARCHAR) | Department (VARCHAR) | Salary (MONEY) |
|---|---|---|---|---|
| 1 | Nguyễn | Văn A | IT | 25,000,000 |
| 2 | Trần | Thị B | HR | 20,000,000 |
| 3 | Lê | Minh C | Sales | 22,000,000 |
↑ Mỗi cột (Column) là 1 thuộc tính — Mỗi hàng (Row) là 1 bản ghi (Record)
2.2 Các khái niệm
| Khái niệm | Tương đương Excel | Ý nghĩa |
|---|---|---|
| Table | Sheet | Bảng chứa dữ liệu về 1 chủ đề |
| Row (Record) | Dòng | 1 bản ghi / 1 đối tượng |
| Column (Field) | Cột | 1 thuộc tính của đối tượng |
| Cell | Ô | 1 giá trị cụ thể tại giao (row, column) |
💡 Ý nghĩa
Table/Row/Column là ngôn ngữ chung của mọi relational database. Khi ai đó nói “table Customers có 50,000 rows”, bạn hiểu ngay: có 50,000 khách hàng. Hiểu cấu trúc này giúp bạn:
- Đọc bất kỳ database nào (SQL Server, PostgreSQL, MySQL)
- Hiểu ERD và Data Dictionary ngay lập tức
- Viết SQL chính xác (biết SELECT lấy columns nào, FROM table nào)
🏢 Ứng dụng
| Hệ thống | Tables chính | Rows (quy mô) |
|---|---|---|
| E-commerce | Customers, Products, Orders | Hàng triệu |
| Ngân hàng | Accounts, Transactions | Hàng tỷ |
| Bệnh viện | Patients, Appointments, Prescriptions | Hàng trăm nghìn |
| HR | Employees, Departments, Payroll | Hàng nghìn |
2.3 Ví dụ thực tế — Database E-commerce
Cấu trúc Database E-commerce
- Table: danh từ số nhiều (Customers, Products, Orders)
- Column: mô tả rõ ràng (FirstName thay vì FN, OrderDate thay vì Date)
- Tránh: khoảng trắng, ký tự đặc biệt, từ khóa SQL (SELECT, FROM...)
Checkpoint
Table = bảng, Row = hàng (1 bản ghi), Column = cột (1 thuộc tính). Một table "Orders" với 200,000 rows nghĩa là có 200,000 đơn hàng. Bạn thấy logic chưa?
🔍 3. Data Types — Kiểu dữ liệu
📚 Định nghĩa
Data Type quy định loại giá trị mà một column có thể chứa. Chọn đúng data type giúp:
- Tiết kiệm bộ nhớ (INT 4 bytes vs BIGINT 8 bytes)
- Đảm bảo tính đúng đắn (không thể nhập text vào cột kiểu INT)
- Tối ưu hiệu suất (query trên INT nhanh hơn trên VARCHAR)
💡 Ý nghĩa
Chọn sai data type là lỗi thiết kế phổ biến nhất và rất khó sửa sau khi database đã có dữ liệu:
- Dùng
VARCHARcho tiếng Việt → mất dấu (“Nguyễn” → “Nguy?n”) - Dùng
FLOATcho tiền → sai số tích lũy (0.1 + 0.2 ≠ 0.3) - Dùng
VARCHARcho số → không thể SUM, không sort đúng (“9” > “10” vì so chuỗi)
🏢 Ứng dụng
| Lĩnh vực | Ví dụ cần chọn đúng |
|---|---|
| Tài chính | Tiền → DECIMAL(18,2) (tuyệt đối không FLOAT) |
| HR | Tên tiếng Việt → NVARCHAR (không VARCHAR) |
| E-commerce | SĐT → VARCHAR(15) (text, có thể có +84, dấu -) |
| IoT/Sensors | Timestamp → DATETIME2(3) (chính xác millisecond) |
3.2 Các Data Types phổ biến trong SQL Server
Số (Numeric)
| Data Type | Kích thước | Phạm vi | Khi nào dùng |
|---|---|---|---|
| INT | 4 bytes | -2.1 tỷ → 2.1 tỷ | ID, số lượng, tuổi |
| BIGINT | 8 bytes | Rất lớn | ID hệ thống lớn |
| SMALLINT | 2 bytes | -32,768 → 32,767 | Giá trị nhỏ (tháng, ngày) |
| TINYINT | 1 byte | 0 → 255 | Trạng thái, rating 1-5 |
| DECIMAL(p,s) | 5-17 bytes | Chính xác | Tiền, tỷ lệ phần trăm |
| MONEY | 8 bytes | Tiền tệ | Giá sản phẩm, lương |
| FLOAT | 4-8 bytes | Xấp xỉ | Tính toán khoa học |
1-- Ví dụ2CREATE TABLE Products (3 ProductID INT, -- ID sản phẩm: số nguyên4 Price DECIMAL(10, 2), -- Giá: 10 chữ số, 2 sau dấu thập phân5 Weight FLOAT, -- Cân nặng: số thập phân xấp xỉ6 Rating TINYINT -- Đánh giá: 1-5 stars7);Dùng DECIMAL cho tiền và giá trị cần chính xác tuyệt đối. FLOAT có sai số nhỏ — 0.1 + 0.2 ≠ 0.3 trong FLOAT! Không bao giờ dùng FLOAT cho tiền.
Chuỗi (String)
| Data Type | Kích thước | Ý nghĩa | Khi nào dùng |
|---|---|---|---|
| CHAR(n) | n bytes cố định | Chuỗi cố định | Mã quốc gia (VN), giới tính (M/F) |
| VARCHAR(n) | Thay đổi, max n | Chuỗi thay đổi | Tên, email, địa chỉ |
| VARCHAR(MAX) | Đến 2GB | Chuỗi rất dài | Mô tả sản phẩm, nội dung bài viết |
| NVARCHAR(n) | 2× bytes, Unicode | Hỗ trợ Unicode | Tiếng Việt, tiếng Nhật, emoji |
| NCHAR(n) | 2n bytes cố định | Unicode cố định | Mã Unicode cố định |
1-- Ví dụ2CREATE TABLE Customers (3 CustomerID INT,4 FirstName NVARCHAR(50), -- Unicode cho tiếng Việt5 Email VARCHAR(100), -- Email chỉ có ASCII6 Gender CHAR(1), -- 'M' hoặc 'F' — luôn 1 ký tự7 Bio NVARCHAR(MAX) -- Giới thiệu bản thân — độ dài tùy ý8);Dữ liệu tiếng Việt (có dấu) bắt buộc dùng NVARCHAR. VARCHAR không lưu đúng được "Nguyễn", "Phạm", "Trần". Quy tắc: dữ liệu có thể chứa tiếng Việt → NVARCHAR.
Ngày giờ (Date/Time)
| Data Type | Ý nghĩa | Ví dụ | Khi nào dùng |
|---|---|---|---|
| DATE | Chỉ ngày | 2026-01-15 | Ngày sinh, ngày đặt hàng |
| TIME | Chỉ giờ | 14:30:00 | Giờ bắt đầu ca, deadline |
| DATETIME | Ngày + giờ | 2026-01-15 14:30:00 | Timestamp chung |
| DATETIME2 | Chính xác hơn | 2026-01-15 14:30:00.1234567 | Audit logs |
Logic và khác
| Data Type | Ý nghĩa | Khi nào dùng |
|---|---|---|
| BIT | 0 hoặc 1 | Cờ: IsActive, IsDeleted |
| UNIQUEIDENTIFIER | GUID | ID phân tán, không đoán được |
3.3 Chọn Data Type đúng — Checklist
| Câu hỏi | → Data Type |
|---|---|
| Là số nguyên? | INT (hoặc BIGINT nếu > 2 tỷ) |
| Là tiền? | DECIMAL(p,s) hoặc MONEY |
| Là text tiếng Việt? | NVARCHAR(n) |
| Là text ASCII only? | VARCHAR(n) |
| Là ngày (không giờ)? | DATE |
| Là ngày + giờ? | DATETIME2 |
| Là True/False? | BIT |
| Là mã cố định? | CHAR(n) hoặc NCHAR(n) |
Checkpoint
Tiền → DECIMAL (không phải FLOAT). Tiếng Việt → NVARCHAR (không phải VARCHAR). True/False → BIT. Ba quy tắc này sẽ giúp bạn tránh 90% lỗi data type!
🔑 4. Keys — Khóa trong Database
📚 Định nghĩa
Key (khóa) là column hoặc tổ hợp columns dùng để định danh duy nhất mỗi row và liên kết các bảng với nhau. Keys là xương sống của relational database.
4.2 Primary Key (PK) — Khóa chính
Định nghĩa: Column (hoặc tổ hợp columns) có giá trị duy nhất cho mỗi row, dùng để định danh row đó.
💡 Ý nghĩa: PK là “số CMND” của mỗi row — nhờ PK, bạn có thể tìm chính xác 1 row trong hàng triệu rows. Không có PK, bạn không thể phân biệt 2 “Nguyễn Văn A” khác nhau.
Quy tắc:
- ✅ Mỗi bảng chỉ có 1 Primary Key
- ✅ Giá trị phải duy nhất (unique) — không trùng
- ✅ Không được NULL — luôn phải có giá trị
- ✅ Thường là cột ID tự tăng (IDENTITY)
1-- Ví dụ tạo bảng với Primary Key2CREATE TABLE Departments (3 DepartmentID INT IDENTITY(1,1) PRIMARY KEY, -- Tự tăng: 1, 2, 3...4 Name NVARCHAR(100) NOT NULL,5 GroupName NVARCHAR(100) NOT NULL6);Ứng dụng: Khi bạn nói "nhân viên số 102", PK EmployeeID = 102 xác định chính xác 1 người duy nhất.
4.3 Foreign Key (FK) — Khóa ngoại
Định nghĩa: Column trong bảng này tham chiếu đến Primary Key của bảng khác, tạo mối quan hệ (relationship) giữa 2 bảng.
Ý nghĩa: FK đảm bảo dữ liệu tham chiếu luôn hợp lệ — không thể có đơn hàng của khách hàng không tồn tại.
1-- Orders có FK tham chiếu đến Customers2CREATE TABLE Orders (3 OrderID INT IDENTITY(1,1) PRIMARY KEY,4 CustomerID INT NOT NULL, -- FK → Customers.CustomerID5 OrderDate DATE NOT NULL,6 TotalAmount DECIMAL(12,2),7 FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID)8);Customers (Bảng cha)
| CustomerID (PK) | Name |
|---|---|
| 1 | Nguyễn A |
| 2 | Trần B |
| 3 | Lê C |
Orders (Bảng con) — CustomerID là FK tham chiếu đến Customers.CustomerID
| OrderID (PK) | CustomerID (FK) | OrderDate |
|---|---|---|
| 101 | 1 ← Nguyễn A | 2026-01-01 |
| 102 | 1 ← Nguyễn A | 2026-01-05 |
| 103 | 2 ← Trần B | 2026-01-10 |
❌ OrderID 104, CustomerID = 99 → LỖI! (CustomerID 99 không tồn tại)
🏢 Ứng dụng: FK được dùng trong mọi database có nhiều bảng: đơn hàng → khách hàng, nhân viên → phòng ban, bài viết → tác giả. Khi viết JOIN (bài sau), bạn sẽ luôn join qua FK.
4.4 Composite Key — Khóa tổ hợp
Định nghĩa: Primary Key gồm nhiều columns kết hợp — khi 1 column không đủ để định danh duy nhất.
1-- OrderDetails: mỗi row là 1 sản phẩm trong 1 đơn hàng2-- Composite PK: (OrderID, ProductID) — cùng đơn hàng + cùng sản phẩm = unique3CREATE TABLE OrderDetails (4 OrderID INT,5 ProductID INT,6 Quantity INT NOT NULL,7 UnitPrice DECIMAL(10,2) NOT NULL,8 PRIMARY KEY (OrderID, ProductID), -- Composite Key9 FOREIGN KEY (OrderID) REFERENCES Orders(OrderID),10 FOREIGN KEY (ProductID) REFERENCES Products(ProductID)11);💡 Ý nghĩa: Composite Key xuất hiện phổ biến trong các bảng trung gian (junction tables) của mối quan hệ Many-to-Many, và trong bảng chi tiết (OrderDetails, EnrollmentDetails).
🏢 Ứng dụng: OrderDetails dùng Composite Key (OrderID, ProductID) — nghĩa là cùng 1 đơn hàng + cùng 1 sản phẩm chỉ xuất hiện 1 lần.
4.5 Relationships — Các loại quan hệ
| Quan hệ | Ý nghĩa | Ví dụ |
|---|---|---|
| One-to-One (1:1) | 1 row bên A ↔ 1 row bên B | Employee ↔ EmployeeDetail |
| One-to-Many (1:N) | 1 row bên A ↔ nhiều rows bên B | Customer → nhiều Orders |
| Many-to-Many (M:N) | Nhiều rows ↔ nhiều rows, qua bảng trung gian | Students ↔ Courses (qua Enrollments) |
One-to-Many (phổ biến nhất):
| Customers (1) | Orders (N) | |
|---|---|---|
| PK: CustID | ─── 1:N ───▶ | FK: CustID |
| 1 khách hàng | nhiều đơn hàng |
Many-to-Many (qua bảng trung gian):
| Students | Enrollments | Courses | ||
|---|---|---|---|---|
| PK: StuID | ── M ──▶ | FK: StuID, FK: CrsID | ◀── N ── | PK: CrsID |
| PK: (StuID, CrsID) |
Checkpoint
PK = định danh duy nhất 1 row. FK = liên kết đến PK bảng khác. Composite Key = PK từ nhiều columns. Mối quan hệ 1:N là phổ biến nhất (1 khách hàng → nhiều đơn hàng).
🛡️ 5. Constraints — Ràng buộc dữ liệu
📚 Định nghĩa
Constraint (ràng buộc) là quy tắc áp dụng lên column hoặc table để đảm bảo tính toàn vẹn dữ liệu — ngăn chặn dữ liệu sai hoặc không hợp lệ được insert vào database.
💡 Ý nghĩa — Tại sao cần Constraints?
Không có constraints, dữ liệu có thể bị:
- Nhập email trùng cho 2 khách hàng khác nhau
- Đặt tuổi = -5 hoặc giá sản phẩm âm
- Để trống tên khách hàng
- Tham chiếu đến sản phẩm không tồn tại
5.3 Các loại Constraints
| Constraint | Ý nghĩa | Ví dụ |
|---|---|---|
| NOT NULL | Không được để trống | Tên khách hàng bắt buộc |
| UNIQUE | Giá trị phải duy nhất | Email không được trùng |
| PRIMARY KEY | NOT NULL + UNIQUE | ID định danh mỗi row |
| FOREIGN KEY | Tham chiếu hợp lệ | OrderID phải tồn tại trong Orders |
| CHECK | Điều kiện logic | Tuổi >= 0, Giá > 0 |
| DEFAULT | Giá trị mặc định | Status mặc định = 'Active' |
5.4 Ví dụ tổng hợp
1CREATE TABLE Employees (2 -- PRIMARY KEY: định danh duy nhất3 EmployeeID INT IDENTITY(1,1) PRIMARY KEY,45 -- NOT NULL: bắt buộc nhập6 FirstName NVARCHAR(50) NOT NULL,7 LastName NVARCHAR(50) NOT NULL,89 -- UNIQUE: không trùng10 Email VARCHAR(100) NOT NULL UNIQUE,1112 -- CHECK: kiểm tra điều kiện13 Age INT CHECK (Age >= 18 AND Age <= 100),14 Salary DECIMAL(12,2) CHECK (Salary > 0),1516 -- DEFAULT: giá trị mặc định17 Status VARCHAR(20) DEFAULT 'Active',18 CreatedDate DATETIME2 DEFAULT GETDATE(),1920 -- FOREIGN KEY: tham chiếu bảng khác21 DepartmentID INT NOT NULL,22 FOREIGN KEY (DepartmentID) REFERENCES Departments(DepartmentID)23);5.5 Constraint trong thực tế
1-- ✅ Hợp lệ2INSERT INTO Employees (FirstName, LastName, Email, Age, Salary, DepartmentID)3VALUES (N'Nguyễn', N'Văn A', 'a.nguyen@company.com', 25, 15000000, 1);45-- ❌ LỖI: Age < 18 → vi phạm CHECK constraint6INSERT INTO Employees (FirstName, LastName, Email, Age, Salary, DepartmentID)7VALUES (N'Trần', N'Thị B', 'b.tran@company.com', 15, 10000000, 1);89-- ❌ LỖI: Email trùng → vi phạm UNIQUE constraint10INSERT INTO Employees (FirstName, LastName, Email, Age, Salary, DepartmentID)11VALUES (N'Lê', N'Minh C', 'a.nguyen@company.com', 30, 20000000, 2);1213-- ❌ LỖI: DepartmentID = 99 không tồn tại → vi phạm FOREIGN KEY14INSERT INTO Employees (FirstName, LastName, Email, Age, Salary, DepartmentID)15VALUES (N'Phạm', N'Đức D', 'd.pham@company.com', 28, 18000000, 99);Luôn thêm constraints khi thiết kế bảng. Phát hiện lỗi dữ liệu ở đầu vào dễ hơn rất nhiều so với sửa dữ liệu sai đã nằm trong database.
🏢 Ứng dụng thực tế
| Hệ thống | Constraint | Mục đích |
|---|---|---|
| E-commerce | CHECK (Quantity > 0) | Không cho đặt số lượng âm |
| Banking | CHECK (Balance >= 0) | Tài khoản không âm |
| HR | UNIQUE (Email) | Mỗi nhân viên 1 email duy nhất |
| Hospital | NOT NULL (PatientName) | Bắt buộc có tên bệnh nhân |
Checkpoint
NOT NULL = bắt buộc. UNIQUE = không trùng. CHECK = điều kiện logic. DEFAULT = giá trị mặc định. Tất cả đều giúp ngăn dữ liệu xấu vào database.
📐 6. Normalization — Chuẩn hóa Database
📚 Định nghĩa
Normalization là quy trình tổ chức dữ liệu trong database để:
- Loại bỏ dữ liệu dư thừa (redundancy)
- Tránh bất thường khi INSERT/UPDATE/DELETE (anomalies)
- Đảm bảo tham chiếu toàn vẹn (data integrity)
💡 Ý nghĩa — Tại sao cần Normalization?
Bảng chưa chuẩn hóa:
| OrderID | CustomerName | CustomerPhone | ProductName | Price | Qty |
|---|---|---|---|---|---|
| 1 | Nguyễn A | 0901234567 | Laptop Dell | 25tr | 1 |
| 2 | Nguyễn A | 0901234567 | Chuột Logitech | 500k | 2 |
| 3 | Trần B | 0912345678 | Laptop Dell | 25tr | 1 |
Vấn đề:
- 🔴 Dư thừa: "Nguyễn A" và SĐT lặp lại 2 lần
- 🔴 Update anomaly: Đổi SĐT Nguyễn A phải sửa ở nhiều rows
- 🔴 Delete anomaly: Xóa đơn hàng 3 → mất luôn thông tin Trần B
- 🔴 Insert anomaly: Không thể thêm khách mới chưa có đơn hàng
6.3 First Normal Form (1NF)
Quy tắc: Mỗi cell chỉ chứa 1 giá trị duy nhất (atomic values). Không có cột lặp lại.
❌ Vi phạm: Nhiều giá trị trong 1 cell!
| OrderID | Products |
|---|---|
| 1 | Laptop, Chuột, Bàn phím |
✅ Đạt 1NF: Mỗi cell chỉ 1 giá trị
| OrderID | Product |
|---|---|
| 1 | Laptop |
| 1 | Chuột |
| 1 | Bàn phím |
6.4 Second Normal Form (2NF)
Quy tắc: Đã đạt 1NF + mọi non-key column phải phụ thuộc vào toàn bộ Primary Key (không chỉ 1 phần).
❌ Vi phạm (PK: OrderID + ProductID):
| OrderID | ProductID | CustomerName | ProductName | Qty |
|---|
CustomerName chỉ phụ thuộc OrderID, không phụ thuộc ProductID!
✅ 2NF — Tách thành 2 bảng:
| Orders: OrderID, CustID | OrderDetails: OrderID, ProductID, Qty |
|---|
6.5 Third Normal Form (3NF)
Quy tắc: Đã đạt 2NF + không có phụ thuộc bắc cầu (transitive dependency).
❌ Vi phạm:
| EmpID | DeptID | DeptName | DeptLocation |
|---|
DeptName và DeptLocation phụ thuộc vào DeptID, không phải EmpID! (EmpID → DeptID → DeptName: phụ thuộc bắc cầu)
✅ 3NF — Tách Department ra:
| Employees: EmpID, DeptID | Departments: DeptID, DeptName, DeptLocation |
|---|
6.6 Ví dụ chuẩn hóa hoàn chỉnh
Bảng gốc (chưa chuẩn hóa):
| OrderID | CustName | CustPhone | ProductName | Price | Qty | Total |
Sau khi chuẩn hóa (3NF):
Chuẩn hóa 3NF — E-commerce
- 1NF: Mỗi cell = 1 giá trị (không nhồi list vào 1 ô)
- 2NF: Non-key columns phụ thuộc toàn bộ PK
- 3NF: Non-key columns chỉ phụ thuộc PK, không phụ thuộc lẫn nhau
🏢 Ứng dụng
| Chuẩn | Ứng dụng thực tế |
|---|---|
| 1NF | Tách “skills: Python, SQL” thành bảng riêng EmployeeSkills — mỗi row 1 skill |
| 2NF | Tách thông tin khách hàng ra khỏi bảng đơn hàng — tránh lặp tên/SĐT |
| 3NF | Tách Department (DeptID, DeptName, Manager) ra khỏi Employee — tránh phụ thuộc bắc cầu |
Trong thực tế, đạt 3NF là đủ tốt cho hầu hết hệ thống. Các chuẩn cao hơn (BCNF, 4NF, 5NF) hiếm khi cần thiết.
Checkpoint
1NF: atomic values. 2NF: full dependency on PK. 3NF: no transitive dependency. Trong thực tế, hầu hết database đạt 3NF là đủ tốt. Bạn hiểu 3 mức này chưa?
📁 7. Schema và Data Dictionary
7.1 Schema — Lược đồ
Định nghĩa: Schema là nhóm logic để tổ chức các bảng trong database, giống như "thư mục" phân loại tables.
Ý nghĩa: Trong database lớn (hàng trăm tables), schema giúp:
- Phân loại tables theo chức năng kinh doanh
- Quản lý quyền truy cập (phòng HR chỉ xem schema HumanResources)
- Tránh xung đột tên (HR.Employee vs Sales.Employee)
Ví dụ — AdventureWorks:
Cấu trúc Schema — AdventureWorks
Cú pháp truy cập: Schema.TableName
1-- Truy cập table Employee trong schema HumanResources2SELECT * FROM HumanResources.Employee;34-- Truy cập table Product trong schema Production5SELECT * FROM Production.Product;7.2 Data Dictionary — Từ điển dữ liệu
Định nghĩa: Data Dictionary là tài liệu mô tả chi tiết cấu trúc database: mỗi table có những columns nào, data type gì, constraint gì, ý nghĩa ra sao.
Tại sao cần?
- Data Analyst mới vào công ty đọc Data Dictionary để hiểu database
- Developer tham khảo khi viết queries
- Đảm bảo team cùng hiểu ý nghĩa dữ liệu
Ví dụ Data Dictionary cho table HumanResources.Employee:
| Column | Data Type | Nullable | Key | Mô tả |
|---|---|---|---|---|
| BusinessEntityID | INT | NOT NULL | PK, FK | ID nhân viên, tham chiếu Person.Person |
| NationalIDNumber | NVARCHAR(15) | NOT NULL | UNIQUE | Số CMND/CCCD |
| LoginID | NVARCHAR(256) | NOT NULL | Tên đăng nhập domain | |
| JobTitle | NVARCHAR(50) | NOT NULL | Chức danh | |
| BirthDate | DATE | NOT NULL | Ngày sinh | |
| MaritalStatus | NCHAR(1) | NOT NULL | M = Married, S = Single | |
| Gender | NCHAR(1) | NOT NULL | M = Male, F = Female | |
| HireDate | DATE | NOT NULL | Ngày vào làm | |
| SalariedFlag | BIT | NOT NULL | 1 = lương cố định, 0 = theo giờ | |
| VacationHours | SMALLINT | NOT NULL | Số giờ nghỉ phép còn lại | |
| SickLeaveHours | SMALLINT | NOT NULL | Số giờ nghỉ ốm còn lại | |
| CurrentFlag | BIT | NOT NULL | 1 = đang làm việc, 0 = đã nghỉ | |
| ModifiedDate | DATETIME | NOT NULL | Ngày sửa cuối cùng |
7.3 ERD — Entity Relationship Diagram
Định nghĩa: ERD là sơ đồ trực quan thể hiện các tables và relationships giữa chúng.
Ứng dụng: Nhìn ERD, bạn biết ngay:
- Có những tables nào
- Tables nào liên kết với nhau
- Qua columns nào (PK-FK)
- Loại quan hệ gì (1:1, 1:N, M:N)
AdventureWorks HR — ERD
Trước khi viết bất kỳ câu SQL nào, hãy xem ERD và Data Dictionary trước. Bạn cần biết: (1) Dữ liệu nằm ở table nào? (2) Tables liên kết qua column nào? (3) Column có data type gì?
Checkpoint
Schema phân nhóm tables. Data Dictionary mô tả chi tiết columns. ERD cho thấy relationships. Ba công cụ này giúp bạn hiểu database trước khi viết 1 dòng SQL nào!
🏋️ 8. Thực hành
Exercise 1: Xác định Data Types
Cho các columns sau, hãy chọn Data Type phù hợp nhất:
| Column | Mô tả | Data Type? |
|---|---|---|
| StudentID | ID sinh viên | ? |
| FullName | Họ tên (tiếng Việt) | ? |
| Địa chỉ email | ? | |
| GPA | Điểm trung bình (0.00-4.00) | ? |
| IsGraduated | Đã tốt nghiệp chưa | ? |
| EnrollDate | Ngày nhập học | ? |
| PhoneNumber | Số điện thoại | ? |
💡 Xem đáp án
| Column | Data Type | Giải thích |
|---|---|---|
| StudentID | INT IDENTITY(1,1) | Số nguyên tự tăng |
| FullName | NVARCHAR(100) | Unicode cho tiếng Việt |
VARCHAR(100) | Email chỉ ASCII | |
| GPA | DECIMAL(3,2) | Chính xác: 0.00-4.00 |
| IsGraduated | BIT | True/False |
| EnrollDate | DATE | Chỉ cần ngày, không cần giờ |
| PhoneNumber | VARCHAR(15) | Text (SĐT có thể có +84, dấu -) |
Exercise 2: Xác định Keys và Relationships
Cho hệ thống quản lý thư viện:
- Books: BookID, Title, AuthorID, CategoryID, ISBN, PublishYear
- Authors: AuthorID, Name, Nationality
- Categories: CategoryID, CategoryName
- Members: MemberID, Name, Email, JoinDate
- BorrowRecords: BorrowID, MemberID, BookID, BorrowDate, ReturnDate
Câu hỏi:
- PK của mỗi bảng là gì?
- FK nằm ở đâu?
- Relationships giữa các bảng?
💡 Xem đáp án
Primary Keys:
- Books:
BookID - Authors:
AuthorID - Categories:
CategoryID - Members:
MemberID - BorrowRecords:
BorrowID
Foreign Keys:
- Books.AuthorID → Authors.AuthorID
- Books.CategoryID → Categories.CategoryID
- BorrowRecords.MemberID → Members.MemberID
- BorrowRecords.BookID → Books.BookID
Relationships:
- Authors → Books: 1:N (1 tác giả viết nhiều sách)
- Categories → Books: 1:N (1 thể loại có nhiều sách)
- Members → BorrowRecords: 1:N (1 thành viên mượn nhiều lần)
- Books → BorrowRecords: 1:N (1 cuốn sách được mượn nhiều lần)
Exercise 3: Phát hiện vi phạm Normalization
Bảng sau vi phạm 1NF, 2NF hay 3NF? Đề xuất cách sửa.
| EmpID | EmpName | Skills | DeptID | DeptName | DeptManager |
|---|---|---|---|---|---|
| 1 | An | Python, SQL, Excel | 10 | IT | Bình |
| 2 | Cúc | SQL, Tableau | 20 | Analytics | Dũng |
| 3 | Hoa | Python, R | 10 | IT | Bình |
💡 Xem đáp án
Vi phạm 1NF: Column "Skills" chứa nhiều giá trị (Python, SQL, Excel) → không atomic
Vi phạm 3NF: DeptName và DeptManager phụ thuộc vào DeptID, không phải EmpID (transitive dependency)
Cách sửa — tách thành 3 bảng:
1-- Table: Employees2-- EmpID (PK), EmpName, DeptID (FK)34-- Table: Departments5-- DeptID (PK), DeptName, DeptManager67-- Table: EmployeeSkills8-- EmpID (FK), Skill9-- PK: (EmpID, Skill)📋 9. Tổng kết
Kiến thức nền tảng đã học
| Chủ đề | Nội dung chính | Tầm quan trọng |
|---|---|---|
| Database & RDBMS | Kho dữ liệu có tổ chức, quản lý bằng SQL | Nền tảng mọi thứ |
| Table/Row/Column | Cấu trúc lưu trữ cơ bản | Phải hiểu trước khi viết SQL |
| Data Types | INT, DECIMAL, NVARCHAR, DATE, BIT... | Chọn sai → lỗi dữ liệu |
| Keys (PK, FK) | Định danh và liên kết tables | Xương sống của JOIN |
| Constraints | NOT NULL, UNIQUE, CHECK, DEFAULT | Bảo vệ data integrity |
| Normalization | 1NF → 2NF → 3NF | Thiết kế database tốt |
| Schema & Data Dict | Tổ chức và tài liệu hóa database | Hiểu trước khi viết query |
Áp dụng vào khóa học
Từ bài tiếp theo, bạn sẽ:
- ✅ Cài đặt SQL Server và khám phá AdventureWorks database
- ✅ Đọc Data Dictionary của AdventureWorks trước khi viết queries
- ✅ Hiểu relationships giữa tables để viết JOINs đúng
- ✅ Biết data types để sử dụng functions phù hợp
Bài tiếp theo: Cài đặt SQL Server & Khám phá AdventureWorks
Câu hỏi tự kiểm tra
- Primary Key (PK) và Foreign Key (FK) khác nhau như thế nào? Vai trò của mỗi loại trong việc liên kết các bảng là gì?
- Ba mức chuẩn hóa (1NF, 2NF, 3NF) giải quyết những vấn đề gì? Trong thực tế, chuẩn hóa đến mức nào là đủ?
- Tại sao việc chọn đúng Data Type (INT, NVARCHAR, DECIMAL, DATE...) lại quan trọng khi thiết kế database?
- Schema trong SQL Server có vai trò gì? Tại sao nên dùng cú pháp
Schema.TableNamekhi truy vấn?
🎉 Tuyệt vời! Bạn đã hoàn thành bài học Nền tảng Database!
Tiếp theo: Bạn sẽ cài đặt SQL Server và bắt đầu khám phá database AdventureWorks thực tế.
