Trong bài này
Cô Mai phụ trách câu lạc bộ lập trình có sáu học viên. Mỗi ngày cô cần trả lời những câu hỏi như "Bạn nào học khối 7?", "Ai đang có nhiều xu nhất?" hay "Bạn nào chưa có người hướng dẫn?". Nếu thông tin nằm rải rác trong tin nhắn và sổ tay, mỗi câu hỏi mất vài phút lục tìm. Khi thông tin được xếp vào một bảng, cô chỉ cần nhìn vào đúng một cột.
Bảng xếp thông tin thành dòng và cột
Đây là bảng students, nơi câu lạc bộ lưu thông tin của sáu học viên:
students6 dòng| id | name | grade | city | coins | mentor |
|---|---|---|---|---|---|
| 1 | An | 6 | Hà Nội | 120 | Cô Mai |
| 2 | Bình | 7 | Đà Nẵng | 90 | NULL |
| 3 | Chi | 8 | Hà Nội | 180 | Thầy Nam |
| 4 | Dung | 6 | Huế | 60 | NULL |
| 5 | Huy | 9 | Cần Thơ | 180 | Cô Mai |
| 6 | Lan | 7 | Hà Nội | 150 | Thầy Nam |
Một bảng gồm ba thành phần:
- Cột (column) lưu một loại thông tin của mọi học viên. Cột
gradelưu khối lớp, cộtcoinslưu số xu. - Dòng (row) lưu toàn bộ thông tin của một học viên. Dòng được tô màu ở trên là của Bình.
- Ô (cell) là chỗ một dòng gặp một cột. Ô ở dòng của Bình, cột
coins, chứa số 90.
Vì học viên nào cũng có đủ các cột giống nhau, bạn trả lời câu "Ai học khối 7?" bằng cách dò xuống cột grade. Có hai bạn: Bình và Lan.
Con số chỉ có nghĩa khi biết nó nằm ở cột nào
Số 180 xuất hiện hai lần trong bảng trên, ở dòng của Chi và dòng của Huy. Nếu chỉ thấy "180" mà không biết cột, bạn không thể biết đó là số xu, điểm thi hay số trang sách. Vì vậy, khi đọc dữ liệu, hãy luôn đọc kèm tên cột.
Tên cột thường là một từ tiếng Anh ngắn. Bảng sau giải thích từng cột của students:
| Cột | Ý nghĩa | Ví dụ |
|---|---|---|
id | Mã học viên, không bao giờ trùng giữa hai người | 3 |
name | Tên học viên | Chi |
grade | Khối lớp, từ 6 đến 12 | 8 |
city | Thành phố học viên đang sống | Hà Nội |
coins | Số xu học viên đang có | 180 |
mentor | Người hướng dẫn | Thầy Nam |
Trả lời câu hỏi bằng cách đọc đúng cột
Quay lại ba câu hỏi của cô Mai ở đầu bài. Với mỗi câu, việc đầu tiên là chọn cột chứa thông tin cần tìm. Sau đó mới dò từng dòng trong cột đó.
| Câu hỏi | Cột cần đọc | Cách dò | Kết quả |
|---|---|---|---|
| Bạn nào học khối 7? | grade | Tìm các ô có giá trị 7 | Bình, Lan |
| Ai đang có nhiều xu nhất? | coins | So sánh cả sáu ô, tìm số lớn nhất | Chi và Huy, cùng 180 xu |
| Bạn nào chưa có người hướng dẫn? | mentor | Tìm các ô NULL | Bình, Dung |
Câu hỏi thứ hai có hai người cùng đứng đầu. Đây là điều bạn chỉ thấy được khi đọc hết cả cột, không dừng lại ở số lớn nhất đầu tiên. Khi viết truy vấn ở các bài sau, những trường hợp như vậy cũng cần được tính tới: "người nhiều xu nhất" có thể là một nhóm người, không phải chỉ một người.
Cách làm này không đổi dù bảng có sáu dòng hay sáu triệu dòng. Bạn xác định cột cần đọc và điều kiện cần tìm, rồi máy tính dò giúp bạn. Đó chính là việc một câu truy vấn SQL sẽ làm.
Một dòng đại diện cho điều gì?
Trong bảng students, một dòng là một người. Nhưng không phải bảng nào cũng như vậy. Hãy xem bảng scores, nơi câu lạc bộ lưu điểm các bài kiểm tra:
scores7 dòng| id | student_id | score | day |
|---|---|---|---|
| 1 | 1 | 80 | 2026-09-01 |
| 2 | 1 | 90 | 2026-09-02 |
| 3 | 2 | 70 | 2026-09-01 |
| 4 | 3 | 90 | 2026-09-01 |
| 5 | 3 | 100 | 2026-09-02 |
| 6 | 4 | 50 | 2026-09-01 |
| 7 | 5 | 90 | 2026-09-01 |
Hai dòng đầu có cùng student_id là 1, tức là cùng thuộc về An. An làm bài hai lần: lần đầu được 80 điểm vào ngày 01/09, lần sau được 90 điểm vào ngày 02/09. Hai dòng này không phải dữ liệu bị nhập trùng, vì mỗi dòng của scores là một lần chấm bài.
Bảng scores có hai cột mã dễ nhầm với nhau:
idlà mã của lần chấm. Mỗi lần chấm có một mã riêng, từ 1 đến 7.student_idlà mã của học viên được chấm. Giá trị1trỏ tới dòng cóidbằng 1 trong bảngstudents, tức là An.
Cơ sở dữ liệu gồm nhiều bảng liên quan với nhau
Câu lạc bộ không chỉ lưu học viên và điểm. Toàn bộ thông tin được chia vào năm bảng, mỗi bảng lưu một loại việc:
| Bảng | Một dòng là | Số dòng |
|---|---|---|
students | một học viên | 6 |
classes | một lớp học | 3 |
enrollments | một lần học viên đăng ký vào một lớp | 7 |
scores | một lần chấm bài | 7 |
ledger | một lần số xu của học viên thay đổi | 6 |
Tập hợp các bảng có liên quan với nhau như vậy gọi là một cơ sở dữ liệu (database). Phần mềm giúp tạo bảng, đọc, thêm, sửa dữ liệu và kiểm tra các quy tắc gọi là hệ quản trị cơ sở dữ liệu. Trong khóa này, bạn thực hành trên SQLite, một hệ quản trị nhỏ chạy ngay trong bàn thực hành của VIMIC.
Lược đồ và dữ liệu là hai thứ khác nhau
Lược đồ (schema) là bản mô tả cấu trúc của bảng: bảng có những cột nào, mỗi cột chứa loại giá trị gì và phải tuân theo quy tắc nào. Ví dụ, lược đồ của students quy định cột grade chỉ nhận số từ 6 đến 12. Dữ liệu là các dòng đang nằm trong bảng.
Lược đồ và dữ liệu thay đổi trong những tình huống khác nhau:
| Việc xảy ra | Lược đồ | Dữ liệu |
|---|---|---|
| Câu lạc bộ nhận thêm học viên Minh | Không đổi | Thêm một dòng |
| An được cộng 20 xu | Không đổi | Sửa một ô |
| Câu lạc bộ cần lưu thêm số điện thoại của mọi học viên | Thêm một cột | Các ô của cột mới chưa có giá trị |
Lược đồ thường được thiết kế cẩn thận từ đầu và ít khi đổi. Dữ liệu thì thay đổi hằng ngày, mỗi khi học viên làm bài, nhận xu hay đăng ký lớp.
Đọc kết quả của một câu truy vấn
Để lấy thông tin từ cơ sở dữ liệu, ta viết một truy vấn (query) bằng SQL, ngôn ngữ dùng để làm việc với các bảng. Câu truy vấn đơn giản nhất chọn một vài cột của một bảng. Câu dưới đây lấy tên và khối lớp của mọi học viên:
Dữ liệu đầu vào
students6 dòng · chọn 2 cột| id | name | grade | city | coins | mentor |
|---|---|---|---|---|---|
| 1 | An | 6 | Hà Nội | 120 | Cô Mai |
| 2 | Bình | 7 | Đà Nẵng | 90 | NULL |
| 3 | Chi | 8 | Hà Nội | 180 | Thầy Nam |
| 4 | Dung | 6 | Huế | 60 | NULL |
| 5 | Huy | 9 | Cần Thơ | 180 | Cô Mai |
| 6 | Lan | 7 | Hà Nội | 150 | Thầy Nam |
Câu lệnh
SELECT name, grade
FROM students;Kết quả
| name | grade |
|---|---|
| An | 6 |
| Bình | 7 |
| Chi | 8 |
| Dung | 6 |
| Huy | 9 |
| Lan | 7 |
Kết quả là một bảng mới có 6 dòng và 2 cột. Câu truy vấn gồm hai phần:
SELECT name, gradecho biết cần lấy những cột nào, theo đúng thứ tự viết.FROM studentscho biết lấy từ bảng nào.
Truy vấn SELECT chỉ đọc dữ liệu. Bảng students vẫn giữ nguyên đủ 6 cột và 6 dòng. Các cột city, coins không bị xóa, chỉ là không được lấy vào kết quả lần này. Bài 2 sẽ hướng dẫn chi tiết cách viết câu SELECT.
Lỗi thường gặp
| Lỗi | Vì sao sai | Cách đúng |
|---|---|---|
Thấy An xuất hiện hai lần trong scores và cho rằng dữ liệu bị trùng | Mỗi dòng của scores là một lần chấm, không phải một học viên | Xác định một dòng đại diện cho điều gì trước khi kết luận |
Đếm số dòng của scores để biết số học viên đã làm bài | Một học viên có thể có nhiều dòng | Đếm số mã học viên khác nhau trong cột student_id |
Nhầm cột id với cột student_id của scores | id là mã lần chấm, student_id là mã học viên | Đọc kỹ tên cột trước khi dùng |
Nghĩ rằng SELECT name, grade xóa các cột còn lại | SELECT chỉ đọc dữ liệu | Bảng gốc giữ nguyên; kết quả là một bảng mới |
Tóm tắt
- Bảng xếp dữ liệu thành dòng và cột. Ô là chỗ một dòng gặp một cột.
- Mỗi bảng có một câu trả lời riêng cho câu hỏi "một dòng là gì": một người, một lớp, hay một lần chấm bài.
- Lược đồ là cấu trúc của bảng; dữ liệu là các dòng đang có. Thêm học viên làm thay đổi dữ liệu, còn thêm cột làm thay đổi lược đồ.
- Câu
SELECT ... FROM ...đọc dữ liệu và trả về một bảng kết quả mới, không làm thay đổi bảng gốc.
Kiểm tra nhanh
Đọc thêm
- Tài liệu SQLite về câu lệnh SELECT (tiếng Anh)
- CS50 SQL, tuần 0: Truy vấn dữ liệu (tiếng Anh)