Cơ sở dữ liệu: học từ ERD trước khi học SQL
Cơ sở dữ liệu dễ trượt vì học SQL trước khi hiểu mô hình dữ liệu. Cách ôn theo thứ tự ERD, khóa, chuẩn hóa BCNF và các lỗi thi hay mắc, kèm ví dụ thật.
Cơ sở dữ liệu: học từ ERD trước khi học SQL
Điểm giữa kỳ môn Cơ sở dữ liệu thường rơi vào câu hỏi mà sinh viên hay đánh giá là "khó nhất": cho một đề bài bằng lời, hãy vẽ mô hình thực thể kết hợp. Không có lệnh SELECT nào ở đó cả. Cũng chẳng có bảng sẵn để chạy.
Cái đáng lo là câu đó không phải ngoại lệ. Nó là dạng bài xuất hiện xuyên suốt học kỳ, chỉ khác nhau ở độ dài đề. Người học theo kiểu mở PostgreSQL lên gõ lệnh từ tuần một thường tới tuần tám mới phát hiện chuyện này, và lúc đó không còn đủ thời gian để lùi lại.
Vì sao SQL hấp dẫn nhưng lại dẫn sai đường
SQL có phản hồi tức thì. Gõ lệnh, Enter, ra kết quả. Cảm giác tiến bộ rất cụ thể, khác hẳn việc ngồi gạch gạch mấy cái hình chữ nhật trên giấy.
Nhưng SQL chỉ là ngôn ngữ truy vấn trên một cấu trúc đã có sẵn. Cấu trúc đó do ai đó quyết định từ trước. Câu hỏi thi không kiểm tra bạn gõ JOIN giỏi đến đâu — nó kiểm tra bạn có biết vì sao bảng này cần bảng kia, và vì sao chia như vậy thì dữ liệu không sinh ra ba bản ghi trùng nhau sau mỗi lần cập nhật.
Thấy rõ nhất qua một con số: trong một đề thi điển hình ba câu, thường hai câu thuộc về mô hình hóa, chuẩn hóa, phụ thuộc hàm. Một câu về SQL. Tỉ lệ đó nói lên kỳ vọng của người ra đề, và cũng là tỉ lệ thời gian ôn nên phân bổ.
Thứ tự ôn hợp lý cho một học kỳ mười chương
Bám theo đúng mạch của giáo trình thường dùng, không nhảy cóc.
- Tổng quan và mô hình dữ liệu. Chỉ cần nắm ba mức: mức vật lý, mức logic, mức khái niệm. Nhiều đề trắc nghiệm hỏi đúng chỗ này.
- Mô hình quan hệ. Quan hệ là bảng, bộ là dòng, thuộc tính là cột. Nghe đơn giản nhưng phải nói được bằng ngôn ngữ hình thức, không chỉ bằng tiếng Việt đời thường.
- ERD. Đây là chương nặng nhất học kỳ. Luyện ít nhất mười lăm đề từ mô tả bằng lời.
- Chuyển ER sang quan hệ, ràng buộc toàn vẹn. Có quy tắc cố định cho từng loại liên kết. Học thuộc quy tắc rồi mới luyện đề.
- Đại số quan hệ. Năm phép toán gốc, phần còn lại suy ra được. Viết bằng ký hiệu, không viết bằng lời.
- Phụ thuộc hàm và khóa. Tìm bao đóng, tìm khóa tối thiểu. Kỹ năng máy móc, luyện là lên tay.
- Chuẩn hóa tới BCNF. 1NF, 2NF, 3NF, BCNF. Mỗi bước có điều kiện riêng, đừng gộp.
- SQL. Đến lúc này mới thực hành nhiều. Có cấu trúc trong đầu rồi thì viết
JOINdễ hơn hẳn. - Bảo mật, phân quyền. Phần này hay bị bỏ qua và hay mất điểm oan ở câu hỏi ngắn.
- Giao tác, sao lưu, phục hồi. ACID, các mức cô lập, và ba kiểu hỏng dữ liệu kinh điển.
Cách chia này không phải sáng kiến gì. Nó chỉ là thứ tự mà giáo trình đã sắp, và người học hay phá vỡ vì sốt ruột.
ERD: chỗ mất điểm nhiều nhất
Đề thường có dạng một đoạn văn tả nghiệp vụ, không nêu rõ thực thể. Việc đầu tiên là gạch chân các danh từ.
Ví dụ một đề kiểu ví Trường Tiền — hệ thống ví điện tử cho sinh viên:
Mỗi sinh viên có mã số, họ tên, email. Sinh viên mở được nhiều ví, mỗi ví có một mã riêng và số dư. Ví được dùng để thanh toán tại các cửa hàng trong trường. Mỗi lần thanh toán ghi lại thời điểm, số tiền và cửa hàng nhận. Một cửa hàng có tên, mã, và người phụ trách.
Gạch chân xong sẽ ra: sinh viên, ví, cửa hàng, giao dịch. Bốn thực thể. Quan hệ giữa chúng nằm trong các câu còn lại.
Chỗ sinh viên hay vẽ sai:
- Biến "giao dịch" thành thuộc tính của ví. Sai. Giao dịch có thuộc tính riêng (thời điểm, số tiền, cửa hàng) nên nó là thực thể.
- Vẽ quan hệ sinh viên–cửa hàng trực tiếp. Sai. Sinh viên thanh toán cho cửa hàng thông qua ví, không trực tiếp.
- Bỏ bản số (cardinality). Không ghi 1:N hay M:N thì mô hình chưa đủ để chuyển sang quan hệ.
Ba loại liên kết và cách chuyển
| Loại liên kết | Cách chuyển sang quan hệ | Ghi chú |
|---|---|---|
| 1–1 | Gộp một chiều, thêm khóa ngoại vào bảng phía tham gia toàn phần | Ít gặp, hay hỏi lý thuyết |
| 1–N | Thêm khóa ngoại vào bảng phía N | Phổ biến nhất |
| M–N | Tạo bảng trung gian chứa hai khóa ngoại, khóa chính là cặp đó | Đề gần như luôn có ít nhất một |
Với ví dụ trên: sinh viên–ví là 1–N (thêm ma_sv vào bảng ví). Ví–giao dịch là 1–N. Cửa hàng–giao dịch cũng 1–N. Không có M–N nào, nên bài này khá nhẹ. Đề thi thật thường có ít nhất một M–N để thử khả năng tạo bảng trung gian.
Ràng buộc toàn vẹn
Bỏ qua phần này là mất điểm cả câu dù ERD vẽ đúng. Cần phân biệt:
- Toàn vẹn thực thể: khóa chính không được NULL.
- Toàn vẹn tham chiếu: khóa ngoại phải trỏ tới một bản ghi tồn tại, hoặc NULL nếu cho phép.
- Toàn vẹn miền: giá trị nằm trong miền xác định, ví dụ số dư ví không âm.
- Ràng buộc ngữ nghĩa: những luật nghiệp vụ đề bài nêu riêng, kiểu "mỗi sinh viên chỉ có một ví chính".
Loại thứ tư hay bị bỏ sót vì nó không nằm trong danh sách chuẩn nào.
Chuẩn hóa: hiểu bản chất thay vì học mẹo
Sinh viên hay học thuộc "1NF là không có thuộc tính đa trị, 2NF là không phụ thuộc bộ phận, 3NF là không phụ thuộc bắc cầu" rồi vào phòng thi gặp bảng lạ là tắc.
Cách chắc hơn: luôn bắt đầu bằng việc tìm tất cả phụ thuộc hàm từ đề, tính bao đóng để xác định khóa, rồi mới xét từng bậc.
Một ví dụ nhỏ, bảng đăng ký môn không chuẩn hóa:
(MaSV, MaMH, TenMH, SoTinChi, Diem)
Phụ thuộc hàm: MaSV, MaMH → Diem; MaMH → TenMH, SoTinChi.
Khóa là (MaSV, MaMH). TenMH chỉ phụ thuộc vào MaMH, tức phụ thuộc bộ phận — vi phạm 2NF. Tách thành DangKy(MaSV, MaMH, Diem) và MonHoc(MaMH, TenMH, SoTinChi).
Đọc thì gọn. Nhưng nếu không tìm khóa trước, bạn sẽ không biết TenMH phụ thuộc bộ phận vào cái gì. Đây là lý do thứ tự thao tác quan trọng hơn việc nhớ định nghĩa.
Bẫy BCNF
BCNF chặt hơn 3NF ở chỗ: mọi phụ thuộc hàm không tầm thường đều phải có vế trái là siêu khóa. Bảng có thể đạt 3NF mà chưa đạt BCNF khi có hai khóa ứng viên chồng lấn nhau.
Đề thi thích dạng này. Ví dụ bảng phân công giảng dạy với (SinhVien, MonHoc) → GiangVien và GiangVien → MonHoc. Ở đây GiangVien không phải siêu khóa, nên vi phạm BCNF dù đã đạt 3NF. Tách thành hai bảng là xong.
Thà luyện kỹ năm dạng này còn hơn đọc lại định nghĩa mười lần.
SQL: học sau, nhưng học thật
Tới chương SQL thì đừng chỉ chép lệnh cho chạy được. Nên dựng một cơ sở dữ liệu nhỏ trên PostgreSQL, nạp dữ liệu mẫu, và tự đặt câu hỏi rồi trả lời.
Mấy câu nên tự viết được không cần nhìn tài liệu:
- Liệt kê sinh viên có tổng chi tiêu trong tháng lớn hơn một ngưỡng.
- Tìm cửa hàng chưa từng nhận giao dịch nào.
- Với mỗi cửa hàng, tính số giao dịch trung bình mỗi ngày trong tháng trước.
- Tìm sinh viên có số dư ví thấp hơn mức trung bình của toàn bộ sinh viên.
Câu thứ ba và thứ tư là chỗ phân loại trình độ. Chúng cần GROUP BY lồng với truy vấn con, và nhiều bạn viết ra kết quả đúng nhưng sai khi có giá trị NULL.
Một điều ít tài liệu nói rõ: đáp án trong sách thường giả định dữ liệu sạch. Dữ liệu thật thì không. Cột email có thể NULL, cột so_du có thể chưa cập nhật. Chạy thử với dữ liệu bẩn rồi mới thấy AVG bỏ qua NULL còn COUNT(*) thì không — chênh lệch đó hay xuất hiện trong câu hỏi tự luận.
Giao tác: phần dễ mất điểm oan
Ba tính chất ACID ai cũng đọc qua. Nhưng câu hỏi thật thường hỏi tình huống: hai người cùng rút tiền từ một ví, mỗi người rút 80.000 trong khi số dư 100.000. Chuyện gì xảy ra ở mức cô lập Read Committed?
Trả lời gọn: cả hai đều đọc được số dư 100.000, cả hai đều thấy đủ tiền, và tùy thứ tự ghi, một trong hai sẽ ghi đè. Kết quả có thể là số dư âm hoặc mất một giao dịch. Đây gọi là lost update, và cách chặn là khóa dòng (SELECT ... FOR UPDATE) hoặc nâng mức cô lập.
Học thuộc bảng bốn mức cô lập không đủ. Phải kể được hiện tượng nào bị chặn ở mức nào, kèm ví dụ. Đề tự luận rất thích dạng này vì nó phân biệt người hiểu và người học vẹt.
Vài hạn chế của đề cương và cách bù
Không có tài liệu nào phủ hết. Cần biết trước để không hụt.
Đề cương giấy thường không cập nhật theo phiên bản PostgreSQL mới. Một số hàm cửa sổ hay cú pháp RETURNING có thể chưa có trong bản in cũ. Nếu trường dạy bản mới, phải tra thêm tài liệu chính thức.
Phần tối ưu truy vấn và chỉ mục thường được dạy mỏng, trong khi đề thi ở một số trường lại hỏi. Xem lại đề các năm trước để biết trường mình có ra phần này không.
Và phần lớn đề cương không có lời giải chi tiết cho câu tự luận dài. Có dàn ý là tốt, nhưng dàn ý không dạy cách viết. Cần tự viết thử ít nhất ba bài rồi đối chiếu.
Cách học một tuần trước thi
Nếu chỉ còn bảy ngày, đừng đọc lại từ đầu. Làm ngược:
Ngày 1 và 2, giải ba đề năm trước trong điều kiện không mở tài liệu. Ghi lại chỗ tắc. Ngày 3 và 4, chỉ học đúng những chỗ đã tắc. Ngày 5, làm lại ba đề đó. Ngày 6, học phần lý thuyết ngắn — ACID, các mức cô lập, ràng buộc toàn vẹn. Ngày 7, nghỉ và đọc lướt bảng phụ lục.
Cách này hiệu quả hơn đọc tuần tự vì nó nhắm vào lỗ hổng thật của bạn, không phải lỗ hổng trung bình của một lớp.
Một lưu ý nhỏ: đừng học nhóm trong hai ngày cuối. Học nhóm tốt khi còn thời gian sửa hiểu sai, còn sát thi thì dễ loạn.
Câu hỏi nên tự đặt khi đọc một đề bài
Sinh viên hay hỏi mình nên làm gì để không bị đề đánh lừa. Không có mẹo chung. Nhưng có ba câu hỏi áp được cho gần như mọi đề mô hình hóa.
Câu thứ nhất: nghiệp vụ này có ghi nhận đối tượng nào lặp lại nhiều lần theo thời gian không? Nếu có, gần như chắc chắn đó là một thực thể, không phải thuộc tính. Giao dịch, lần đăng nhập, lượt bình chọn đều rơi vào đây. Người mới hay nhét chúng vào bảng cha vì chúng chỉ chiếm một hai dòng trong đề.
Câu thứ hai: nếu xóa một bản ghi ở bảng này, dữ liệu ở bảng kia còn nghĩa không? Xóa môn học mà điểm của sinh viên vẫn còn treo lơ lửng là dấu hiệu ràng buộc tham chiếu chưa đặt đúng. Trả lời câu này giúp xác định chiều của quan hệ và chỗ đặt khóa ngoại.
Câu thứ ba, khó nhất: đề có nói hai đối tượng chỉ liên hệ được với nhau khi tồn tại một đối tượng thứ ba không? Nếu có, đó là dấu hiệu quan hệ M–N kèm thuộc tính riêng, và phải tách thành thực thể riêng chứ không vẽ thành đường nối. Những đề có câu "mỗi lần thanh toán ghi lại thời điểm" thường là dạng này.
Ba câu này không thay được việc luyện đề. Nhưng khi gặp đề lạ và bị tắc, chúng là điểm bám để gỡ.
Cũng nên tập thói quen vẽ nháp bằng bút chì ở góc giấy, đừng vẽ thẳng. Đề mô hình hóa gần như luôn cần sửa lại ít nhất một lần, và một bản nháp bị gạch không được tính điểm.
Những chỗ đề thi và đời thật lệch nhau
Điểm này ít người nói trong lớp nhưng biết trước thì đỡ bỡ ngỡ khi ra làm.
Trong đề thi, mọi yêu cầu được viết rõ. "Mỗi sinh viên có duy nhất một email" nghĩa là phải đặt ràng buộc UNIQUE. Ngoài đời, không ai nói với bạn điều đó. Phải tự hỏi khách hàng, hoặc phải phát hiện khi dữ liệu cũ đã có hàng nghìn email trùng. Sửa sau tốn thời gian hơn giả định trước rất nhiều.
Trong đề thi, thực thể có tên gọn gàng và thuộc tính ít. Ngoài đời, một bảng khách hàng có thể dễ dàng vượt bốn mươi cột, trong đó phần lớn được thêm dần qua nhiều năm bởi nhiều người khác nhau. Chuẩn hóa lúc đó không còn là bài tập sạch mà là cuộc đàm phán với những hệ thống đang chạy.
Và cảnh báo cuối. Chuẩn hóa tới BCNF là đúng về lý thuyết nhưng bị ngược chiều với hiệu năng đọc. Hệ thống báo cáo thật thường cố ý phi chuẩn hóa, lưu thêm một cột tổng đã tính sẵn, để khỏi phải JOIN năm bảng mỗi lần mở trang. Đề thi không hỏi điều này, nhưng hiểu nó giúp bạn không biến thành người áp quy tắc sách vở một cách máy móc khi ra làm nghề.
Tài liệu đang có
Bộ đề cương Cơ sở dữ liệu song ngữ Việt–Anh, 493 trang, mười chương đi đúng thứ tự nêu trên, cộng năm phụ lục. Mọi con số trong phần SQL và giao tác lấy từ lần chạy thật trên PostgreSQL với cơ sở dữ liệu ví Trường Tiền, không phải ví dụ giả định. Có bài tập vận dụng kèm lời giải, câu tự luận kèm dàn ý, và trắc nghiệm có đáp án ở cuối.
Giá 173.000 đồng. Xem thử 5 trang đầu tại trang sản phẩm trước khi quyết định — năm trang đó cho thấy cách trình bày và độ chi tiết của lời giải, đủ để biết có hợp với cách học của bạn không.
Chuyển khoản trong nước, không cần thẻ quốc tế. Nhận file qua email trong 24 giờ sau khi thanh toán.