Mục lục bài họcĐang ở d08-b1
Structure of a database
Table, record, field
| table | the whole set of data, arranged in rows and columns |
| record | all the data about one item — one row |
| field | one item of data — one column |
In a table of pupils, one record holds everything about one pupil; the field called $\text{Surname}$ holds the surname of every pupil.
Confusing the two is the commonest error in this topic. The fix is to picture the table: records go across, fields go down.
The primary key
A primary key is a field that uniquely identifies each record in the table. No two records may have the same value in it, and it must not be left empty.
Why it is needed: without a unique identifier, the database has no reliable way to pick out one specific record. Two pupils named the same would be indistinguishable.
Choosing a good primary key
A good primary key is unique, never empty, and never changes.
That last requirement rules out most obvious choices:
- surname — not unique, and people do change their names;
- date of birth — very far from unique;
- telephone number — unique at any moment, but people change numbers, and a changed key breaks every link to that record;
- email address — same problem.
This is why organisations invent an ID number that means nothing outside the system: a pupil number, an account number, a membership number. Because it carries no real-world meaning, there is never any reason to change it.
Data types in a database
| text / alphanumeric | letters and digits — names, addresses, telephone numbers |
| character | a single letter or symbol |
| Boolean | a yes/no field — has the fee been paid? |
| date / time | a date or a time, so the database can sort and compare them properly |
| integer | a whole number — a quantity in stock |
| real | a number with decimals — a price |
Note the telephone number again: it is text, not a number, because a numeric field would drop the leading zero and because nobody ever performs arithmetic on a phone number.
Note also why a date field is worth using rather than text: with a real date type, the database can sort dates in order and work out the difference between two of them. Stored as text, $\text{"01/12/2025"}$ sorts before $\text{"02/01/2025"}$, which is wrong.
Validation in a database
The same checks as in programming can be attached to a field: range, length, type, presence, format. Setting these once on the field means every entry is checked, no matter who types it.
Bảng, bản ghi, trường.
- Bảng — toàn bộ tập dữ liệu, sắp xếp thành hàng và cột;
- Bản ghi — toàn bộ dữ liệu về một đối tượng, tức một hàng;
- Trường — một mục dữ liệu, tức một cột.
Trong một bảng học sinh, một bản ghi chứa mọi thứ về một học sinh; còn trường tên là $\text{Ho\_ten}$ chứa họ tên của mọi học sinh.
Lẫn hai khái niệm này là lỗi phổ biến nhất của chủ đề. Cách chữa: hình dung cái bảng — bản ghi nằm ngang, trường nằm dọc.
Khoá chính. Khoá chính là một trường xác định duy nhất mỗi bản ghi trong bảng. Không có hai bản ghi nào được mang cùng một giá trị ở trường đó, và nó không được để trống.
Vì sao cần nó: không có mã định danh duy nhất, cơ sở dữ liệu không có cách nào đáng tin để lấy ra đúng một bản ghi cụ thể. Hai học sinh trùng tên sẽ không phân biệt được.
Chọn khoá chính tốt. Một khoá chính tốt phải duy nhất, không bao giờ để trống, và không bao giờ thay đổi.
Yêu cầu cuối loại bỏ hầu hết các lựa chọn tưởng như hiển nhiên:
- họ tên — không duy nhất, và người ta có đổi tên;
- ngày sinh — rất xa mức duy nhất;
- số điện thoại — duy nhất ở một thời điểm, nhưng người ta đổi số, và khoá đã đổi thì mọi liên kết tới bản ghi đó bị đứt;
- địa chỉ thư điện tử — cùng vấn đề như vậy.
Đó là lý do các tổ chức tự đặt ra một mã số không mang ý nghĩa gì bên ngoài hệ thống: mã học sinh, số tài khoản, số thẻ hội viên. Vì nó không mang ý nghĩa thực tế nào, không bao giờ có lý do gì để đổi nó cả.
Các kiểu dữ liệu trong cơ sở dữ liệu.
- văn bản — chữ và số: họ tên, địa chỉ, số điện thoại;
- ký tự — một chữ cái hoặc ký hiệu đơn;
- lô-gic — trường có/không: đã đóng học phí chưa?;
- ngày giờ — một ngày hoặc một giờ, để cơ sở dữ liệu sắp xếp và so sánh đúng cách;
- số nguyên — số nguyên trọn vẹn: số lượng hàng tồn kho;
- số thực — số có phần thập phân: giá tiền.
Chú ý lại về số điện thoại: nó là văn bản chứ không phải số, vì trường kiểu số sẽ vứt mất số 0 đứng đầu, và vì không ai làm phép tính trên số điện thoại cả.
Chú ý thêm vì sao nên dùng kiểu ngày thay vì văn bản: với kiểu ngày thật, cơ sở dữ liệu sắp xếp được các ngày theo đúng thứ tự và tính được khoảng cách giữa hai ngày. Nếu lưu bằng văn bản, chuỗi $\text{"01/12/2025"}$ sẽ đứng trước $\text{"02/01/2025"}$ — sai hoàn toàn.
Kiểm tra hợp lệ trong cơ sở dữ liệu. Các phép kiểm giống hệt trong lập trình đều gắn được vào một trường: kiểm khoảng, độ dài, kiểu, có mặt, định dạng. Đặt chúng một lần trên trường nghĩa là mọi lần nhập đều được kiểm, bất kể ai gõ.
Một trường lập bảng dữ liệu học sinh gồm các trường: họ tên, ngày sinh, số điện thoại phụ huynh, địa chỉ, mã học sinh. (a) Nêu ba yêu cầu của một khoá chính tốt. (b) Xét từng trường và giải thích trường nào dùng được. (c) Nêu kiểu dữ liệu cho mỗi trường.
(a) Ba yêu cầu của một khoá chính tốt.
- duy nhất — không hai bản ghi nào mang cùng giá trị;
- không bao giờ để trống — mọi bản ghi đều phải có giá trị;
- không bao giờ thay đổi — giá trị phải ổn định suốt đời bản ghi.
(b) Xét từng trường.
Họ tên → không dùng được. Nó vi phạm cả hai yêu cầu quan trọng: hai học sinh trùng tên là chuyện rất thường, và người ta còn đổi tên.
Ngày sinh → không dùng được. Nó rất xa mức duy nhất: trong một trường lớn, hàng chục học sinh sinh cùng ngày.
Số điện thoại phụ huynh → không dùng được. Trường này thoạt nhìn có vẻ ổn vì thường không trùng, nhưng nó hỏng ở hai chỗ.
Thứ nhất, anh chị em ruột dùng chung số điện thoại của cùng một phụ huynh — nên nó không duy nhất.
Thứ hai, và nghiêm trọng hơn: người ta đổi số điện thoại. Khi khoá chính đổi, mọi liên kết tới bản ghi đó — điểm số, điểm danh, học phí — đều bị đứt.
Địa chỉ → không dùng được. Anh chị em ruột ở chung nhà, và gia đình thì chuyển nhà.
Mã học sinh → DÙNG ĐƯỢC. Đây là trường duy nhất thoả cả ba yêu cầu.
Vì sao nó thoả. Nhà trường tự đặt ra mã này và tự bảo đảm nó không trùng. Quan trọng hơn, nó không mang ý nghĩa gì bên ngoài hệ thống — nó không phải tên ai, không phải số nhà ai.
Chính vì thế không bao giờ có lý do gì để đổi nó. Học sinh đổi tên, đổi nhà, đổi số điện thoại — mã học sinh vẫn nguyên.
Đó là nguyên tắc chung: các tổ chức tự đặt ra một mã số vô nghĩa để làm khoá chính, đúng vì lý do này.
(c) Kiểu dữ liệu cho mỗi trường.
- họ tên → văn bản;
- ngày sinh → ngày giờ, để cơ sở dữ liệu sắp xếp và tính tuổi được;
- số điện thoại phụ huynh → văn bản, vì kiểu số vứt mất số 0 đứng đầu và không ai tính toán trên số điện thoại;
- địa chỉ → văn bản;
- mã học sinh → văn bản nếu có chữ như $\text{HS001}$; số nguyên nếu chỉ toàn chữ số.
Một người lưu ngày sinh dưới dạng văn bản thay vì kiểu ngày. Giải thích hai việc mà cơ sở dữ liệu sẽ không làm đúng được, kèm ví dụ cụ thể.
Việc thứ nhất — sắp xếp theo thứ tự thời gian.
Khi một trường có kiểu văn bản, cơ sở dữ liệu sắp xếp nó theo thứ tự chữ cái, tức so sánh từng ký tự từ trái sang phải.
Ví dụ cụ thể. Hai ngày $\text{"01/12/2025"}$ và $\text{"02/01/2025"}$.
Theo thời gian thật, $\text{01/12/2025}$ (tháng $12$) đến sau $\text{02/01/2025}$ (tháng $1$).
Nhưng khi so sánh như văn bản, máy đọc ký tự đầu: $\text{"0"}$ bằng $\text{"0"}$. Rồi ký tự thứ hai: $\text{"1"}$ nhỏ hơn $\text{"2"}$. Nó dừng ngay ở đó và kết luận $\text{"01/12/2025"}$ đứng trước.
Kết quả: danh sách xếp sai hoàn toàn, vì máy sắp theo ngày trước rồi mới tới tháng và năm.
Với kiểu ngày thật, cơ sở dữ liệu hiểu ba phần đó là ngày, tháng, năm và sắp đúng theo thời gian.
Việc thứ hai — tính khoảng cách giữa hai ngày.
Với kiểu ngày, cơ sở dữ liệu trừ được hai ngày cho nhau để ra số ngày hoặc số năm chênh lệch. Nhờ đó nó tính được tuổi của học sinh từ ngày sinh, hoặc lọc ra những học sinh trên $16$ tuổi.
Với kiểu văn bản, việc đó không làm được. Chuỗi $\text{"14/03/2009"}$ với máy chỉ là mười ký tự, không phải một thời điểm. Trừ hai chuỗi văn bản cho nhau là thao tác vô nghĩa.
Muốn tính tuổi, người dùng phải tự tách chuỗi ra thành ba phần, tự đổi sang số, rồi tự tính — dài dòng và dễ sai.
Nguyên tắc rút ra. Chọn kiểu dữ liệu không chỉ để lưu giá trị, mà để cơ sở dữ liệu hiểu được ý nghĩa của giá trị đó.
Cùng lý do này giải thích vì sao giá tiền nên là kiểu số thực (để cộng và tính trung bình được) — nhưng số điện thoại lại nên là văn bản, vì ta không bao giờ tính toán trên nó, mà lại cần giữ số 0 đứng đầu.
Đọc xong rồi — làm thử ngay
Bài tập của chương Databases gồm 14 câu trắc nghiệm và 5 đề tự luận. Đáp án hiện ngay khi chọn, miễn phí.