Học bằng cách đọc theo thứ tự

Tạo và thay đổi bảng

Học định nghĩa bảng SQL từ con số 0. Bao gồm CREATE TABLE, PRIMARY KEY, kiểm tra định nghĩa bảng, thêm / xóa / đổi tên cột với ALTER TABLE — tất cả chạy trực tiếp trên trình duyệt của bạn.

Về SQL được dạy trong khóa học này

Khóa học này dạy cú pháp SQL phổ quát hoạt động trên các RDBMS chính — MySQL, Oracle, PostgreSQL, SQL Server, v.v.. Các kiến thức cơ bản như CREATE TABLE / SELECT / WHERE / JOIN / GROUP BY được viết giống nhau dù bạn chuyển sang cơ sở dữ liệu nào.

Vì lý do kỹ thuật, console trên trình duyệt chạy SQLite, nhưng bất cứ khi nào một tính năng khác biệt giữa các cơ sở dữ liệu (ràng buộc độ dài kiểu, cách liệt kê bảng, v.v.) bạn sẽ thấy ghi chú song song như Trong MySQL bạn sẽ viết... để biết dùng gì ở nơi khác.

Bảng là gì?

Trong cơ sở dữ liệu quan hệ, bạn lưu dữ liệu trong các bảng (lưới gồm hàng và cột). Mỗi bảng gồm cộthàng (bản ghi), và mỗi cột có một kiểu dữ liệu cố định quy định những giá trị nào nó có thể chứa.

Thiết kế bảng nghĩa là quyết định trước những cột nào cần có và kiểu nào gán cho từng cột. Cố định kiểu từ đầu giúp ngăn các giá trị bất ngờ lọt vào sau này.

Cấu trúc của bảng user
Định nghĩa cột (kiểu)1 hàng = 1 bản ghiidINTEGERnameTEXTageINTEGERcityTEXT1Alice30Tokyo2Bob25Osaka3Carol35Tokyo
Bạn quyết định tên cột và kiểu trước, sau đó xếp chồng các hàng (bản ghi) lên trên. Mỗi ô chứa một giá trị tuân theo kiểu của cột đó.

CREATE TABLE — tạo bảng

Để tạo bảng bạn dùng câu lệnh CREATE TABLE. Viết tên bảng, sau đó trong dấu ngoặc đơn liệt kê các cặp tên cột + kiểu ngăn cách bằng dấu phẩy. Đừng đặt dấu phẩy sau cột cuối cùng.

Cố định kiểu từ đầu khiến dữ liệu bất ngờ khó lọt vào (ví dụ chuỗi nằm trong cột số).

-- Tạo bảng bằng cách liệt kê tên cột và kiểu
CREATE TABLE book_record (
  id INTEGER,
  title TEXT,
  price INTEGER,
  published_on TEXT
);

Các kiểu dữ liệu phổ biến

Kiểu dữ liệu SQL khác nhau về tên và chi tiết giữa các hệ cơ sở dữ liệu, nhưng khi mới bắt đầu bạn chỉ cần biết các kiểu sau.

KiểuGiá trị lưu trữVí dụ sử dụng
INTEGERSố nguyênid / age / count
REALSố dấu phẩy độngscore / weight
TEXTChuỗiname / address / message
BLOBDữ liệu nhị phânLuồng byte cho ảnh, âm thanh, v.v.
NUMERICSố nói chung (gồm cả ngày và boolean)Kiêm cả date / boolean

VARCHAR / CHAR / DATETIME của MySQL thì sao?

Trong MySQL và PostgreSQL bạn sẽ thường thấy các kiểu chi tiết như VARCHAR(255) / CHAR(13) / BOOLEAN / DATETIME. Console ở đây chấp nhận các kiểu này về mặt cú pháp, nhưng việc ràng buộc độ dài (như VARCHAR(10) từ chối ký tự thứ 11) chỉ có hiệu lực trên các RDBMS có kiểu nghiêm ngặt như MySQL hoặc PostgreSQL.

Đối với các bài tập trong khóa học này, các cột chủ yếu dùng INTEGER / TEXT / REAL để giữ mọi thứ đơn giản. Khi bạn chuyển định nghĩa sang MySQL, bạn có thể thay INTEGER bằng INTTEXT bằng VARCHAR(N) hoặc TEXT — cấu trúc của CREATE TABLE vẫn giữ nguyên.

Hãy thử tạo bảng book_record để lưu sách. (Chạy đúng thì phần giải thích sẽ hiện ra.)

① Trên dòng đầu, viết DROP TABLE IF EXISTS book_record; để xóa bảng book_record hiện có (nếu có).

② Tiếp theo, viết CREATE TABLE book_record (...) với ba cột: id INTEGER, title TEXT, và price INTEGER.

③ Để xác minh, kết thúc bằng SELECT name FROM sqlite_master WHERE type='table'; và xác nhận book_record xuất hiện trong danh sách.

SQL Editor

Chạy truy vấn để xem kết quả

PRIMARY KEY — định danh duy nhất một hàng

Khóa chính (PRIMARY KEY — cột dùng để định danh duy nhất một hàng) là một cột có giá trị phải duy nhấtkhông bao giờ NULL. Bạn đặt một cột làm khóa chính khi giá trị của nó luôn phải tồn tại và không bao giờ trùng nhau, như mã nhân viên hoặc ID người dùng.

Khi đã có khóa chính, bạn có thể tin cậy lấy được một hàng duy nhất. Theo nguyên tắc, mỗi bảng nên có đúng một khóa chính.

Ba tính chất của PRIMARY KEY
Tính chấtÝ nghĩaVi phạm / Hiệu ứngDuy nhấtKhông có giá trị trùng✗ Vi phạm UNIQUEBắt buộcKhông cho phép NULL✗ Vi phạm NOT NULLĐánh số tự độngChỉ với INTEGER PRIMARY KEYTự điền số nguyênchưa dùng nếu INSERT bỏ qua
Khóa chính là một cột với ba tính chất: duy nhất, không cho phép NULL, và (với INTEGER PRIMARY KEY) các giá trị được đánh số tự động. Mỗi bảng nên có đúng một khóa chính.
-- Thêm PRIMARY KEY sau định nghĩa cột
CREATE TABLE member (
  id INTEGER PRIMARY KEY,
  name TEXT NOT NULL,
  joined_on TEXT
);

INTEGER PRIMARY KEY tự đánh số

Một cột được khai báo INTEGER PRIMARY KEY sẽ tự đánh số bắt đầu từ 1 khi bạn INSERT mà không chỉ định giá trị của nó. Trong MySQL, cùng kiểu đánh số tự động được viết là id INT PRIMARY KEY AUTO_INCREMENT, và trong PostgreSQL là id SERIAL PRIMARY KEY. Trong console của khóa học này, INTEGER PRIMARY KEY là đủ.

Nếu bạn INSERT với một giá trị cụ thể, giá trị đó được dùng, và lần đánh số tự động tiếp theo sẽ tiếp tục từ số nguyên ngay sau nó.

Hãy thử tạo bảng member để lưu thành viên, với id là khóa chính.

① Viết DROP TABLE IF EXISTS member; để xóa bảng member hiện có.

② Viết CREATE TABLE member (...) với ba cột: id INTEGER PRIMARY KEY, name TEXT NOT NULL, và joined_on TEXT.

③ Viết INSERT INTO member (name, joined_on) VALUES ('Frank', '2026-04-01'), ('Grace', '2026-04-02'); để thêm hai hàng mà không chỉ định id.

④ Kết thúc bằng SELECT * FROM member; để xác nhận id đã được đánh số tự động.

SQL Editor

Chạy truy vấn để xem kết quả

Thử vi phạm ràng buộc — cách NOT NULL hoạt động

Hãy cố tình phá luật để xem các ràng buộc (constraint — quy tắc mà giá trị của một cột phải tuân theo) như NOT NULLPRIMARY KEY hoạt động ra sao. NOT NULL là quy tắc không cho phép NULL trong cột. Thêm nó vào các trường bắt buộc (tên, email, v.v.) ngăn các hàng không đầy đủ lọt vào.

Bảng user được tạo ở đầu bài viết được định nghĩa với name TEXT NOT NULL. Nếu bạn cố thêm NULL vào cột name, cơ sở dữ liệu sẽ từ chối INSERT và trả về lỗi.

Cách ràng buộc NOT NULL hoạt động
name được chènKiểm tra NOT NULLKết quả'Alice'OK(có giá trị)○ Chèn thành công'' (chuỗi rỗng)OK(chuỗi rỗng ≠ NULL)○ Chèn thành côngNULLVi phạm(NULL không cho phép)✗ NOT NULLconstraint failed
Một INSERT đặt NULL vào cột NOT NULL bị từ chối kèm lỗi. Chuỗi rỗng ('') được coi là một giá trị khác với NULL, nên một INSERT với chuỗi rỗng vẫn thông qua — nhớ rõ sự phân biệt này.

Cột name của bảng user được định nghĩa với ràng buộc NOT NULL. Cố ý chèn NULL để thấy lỗi vi phạm ràng buộc.

① Chạy câu INSERT INTO user (...) VALUES (10, NULL, 30, 'Tokyo'); đã chuẩn bị sẵn (vì bạn đang cố đặt NULL vào name, bạn sẽ nhận được lỗi như NOT NULL constraint failed: user.name).

(Bài tập này đúng khi có lỗi trả về — đó chính là vai trò của ràng buộc: chặn dữ liệu không hợp lệ trước khi nó tiếp đất.)

-- INSERT kích hoạt vi phạm NOT NULL trong Bài tập 3
INSERT INTO user (id, name, age, city)
  VALUES (10, NULL, 30, 'Tokyo');

SQL Editor

Chạy truy vấn để xem kết quả

Kiểm tra và xóa bảng

Sau khi tạo bảng, bạn sẽ muốn kiểm tra các bảng nào tồn tạimỗi bảng có cột gì. Console ở đây dùng hai truy vấn này:

- Danh sách bảng: SELECT name FROM sqlite_master WHERE type='table';

- Định nghĩa cột: PRAGMA table_info(table_name);

Trong MySQL bạn sẽ viết SHOW TABLES;DESCRIBE table_name;; Oracle dùng SELECT table_name FROM user_tables;. Mỗi cơ sở dữ liệu có cú pháp riêng. DROP TABLE để xóa bảng hoạt động giống nhau trên tất cả các cơ sở dữ liệu.

-- ① Liệt kê tất cả các bảng
SELECT name FROM sqlite_master WHERE type='table';

-- ② Hiển thị định nghĩa cột của bảng user
PRAGMA table_info(user);

-- ③ Xóa một bảng
DROP TABLE IF EXISTS book_record;

Xem nhanh bên trong bảng user được thiết lập ở đầu bài viết, sau đó luyện tập xóa một bảng không còn cần thiết.

① Viết PRAGMA table_info(user); để hiển thị định nghĩa cột của bảng user.

② Nhìn vào cột pk trong kết quả để biết cột nào là khóa chính.

③ Xóa bảng book_record mà bạn tạo trong Bài tập 1 với DROP TABLE IF EXISTS book_record;.

④ Cuối cùng, chạy SELECT name FROM sqlite_master WHERE type='table'; và xác nhận book_record đã biến mất khỏi danh sách.

SQL Editor

Chạy truy vấn để xem kết quả

ALTER TABLE — sửa định nghĩa hiện có

Khi hệ thống đã đi vào vận hành, các yêu cầu như "thêm một cột nữa" hoặc "đổi tên bảng" là không thể tránh khỏi. Đó là lúc ALTER TABLE phát huy tác dụng. Bốn thao tác được đề cập ở đây đều hoạt động trong MySQL và PostgreSQL với cú pháp gần như giống hệt.

Thao tácCú phápSử dụng
Đổi tên bảngALTER TABLE old_name RENAME TO new_name;Đổi tên toàn bộ bảng
Thêm cộtALTER TABLE table ADD COLUMN col type;Thêm thuộc tính mới
Xóa cộtALTER TABLE table DROP COLUMN col;Xóa thuộc tính không dùng
Đổi tên cộtALTER TABLE table RENAME COLUMN old TO new;Đổi tên một cột
Bốn thao tác ALTER TABLE
RENAME TOĐổi tên bảngADD COLUMNThêm cộtDROP COLUMNXóa cộtRENAME COLUMNĐổi tên cột
Biết cách đổi tên bảng, thêm cột, xóa cột và đổi tên cột bao quát gần như mọi thay đổi định nghĩa bạn sẽ làm trong thực tế.

MODIFY / CHANGE COLUMN / AFTER của MySQL

Trong MySQL bạn có thể thay đổi kiểu của một cột với ALTER TABLE table MODIFY col type;, thay đổi tên và kiểu của cột cùng lúc với CHANGE COLUMN old new type;, và xóa khóa chính với DROP PRIMARY KEY;.

-- Đổi tên bảng
ALTER TABLE user RENAME TO user_record;

-- Thêm một cột (cột email được thêm vào cuối)
ALTER TABLE user_record ADD COLUMN email TEXT;

-- Đổi tên cột
ALTER TABLE user_record RENAME COLUMN city TO area;

-- Xóa một cột
ALTER TABLE user_record DROP COLUMN email;

Áp dụng cả ba thao tác ALTER TABLE (thêm, đổi tên, xóa) cho bảng user theo thứ tự. (Đây là bài tập cuối cùng trong bài viết.)

① Thêm cột email với ALTER TABLE user ADD COLUMN email TEXT;.

② Đổi tên cột city thành area với ALTER TABLE user RENAME COLUMN city TO area;.

③ Xóa cột email mà bạn vừa thêm với ALTER TABLE user DROP COLUMN email;.

④ Cuối cùng, chạy PRAGMA table_info(user); và xác nhận area đã thay thế và email không còn ở đó.

SQL Editor

Chạy truy vấn để xem kết quả
QUIZ

Kiểm tra kiến thức

Hãy trả lời từng câu hỏi một.

Câu 1Câu nào sau đây mô tả đúng về khóa chính (PRIMARY KEY)?

Câu 2Cách thích hợp nhất để kiểm tra định nghĩa cột của bảng user trong console của khóa học này là gì?

Câu 3Câu nào sau đây mô tả đúng cách ALTER TABLE hoạt động trong console của khóa học này?