SQL
Trang này chứa các mẹo và tài nguyên để chuẩn bị cho các cuộc phỏng vấn SQL.
Khóa chính (Primary Key) là gì?
Khóa chính là một trường (column) hoặc tập hợp các trường trong một bảng cơ sở dữ liệu dùng để định danh duy nhất mỗi bản ghi (record) trong bảng đó. Nó là một loại khóa duy nhất (unique key) đặc biệt. Nếu một cột được chỉ định là khóa chính, nó không thể chứa giá trị null
hoặc để trống. Một bảng có thể có các cột trùng lặp, nhưng chỉ được phép có duy nhất một khóa chính. Khóa chính luôn đảm bảo các giá trị được lưu trữ trong cột là duy nhất.
Ví dụ:
Trong đoạn mã trên:
roll_number
là khóa chính của bảngStudent
, đảm bảo mỗi học sinh có một mã số duy nhất.Cột này không thể chứa
null
và mọi giá trị trongroll_number
phải khác nhau.
Khóa chính đóng vai trò quan trọng trong việc duy trì tính toàn vẹn dữ liệu (data integrity) và hỗ trợ liên kết giữa các bảng trong cơ sở dữ liệu quan hệ (relational database).
Khóa ngoại (Foreign Key) là gì?
Khóa ngoại là một trường hoặc tập hợp các trường trong một bảng được sử dụng để liên kết một hoặc nhiều bảng với nhau. Nó còn được gọi là khóa tham chiếu (referencing key). Khóa ngoại được định nghĩa là một khóa có mối quan hệ với khóa chính (primary key) của một bảng khác. Nói cách khác, một trường khóa ngoại trong một bảng sẽ trỏ đến trường khóa chính của bảng khác. Nó đảm bảo mỗi hàng (row) trong bảng kia được định danh duy nhất, duy trì tính toàn vẹn tham chiếu (referential integrity).
Mối quan hệ giữa khóa chính và khóa ngoại rất quan trọng vì nó giúp đảm bảo các đặc tính ACID (Atomicity, Consistency, Isolation, Durability) của cơ sở dữ liệu trong một số trường hợp. Nó cũng ngăn chặn các hành động có thể phá hủy liên kết giữa bảng con (child table) và bảng cha (parent table).
Ví dụ cú pháp:
Giải thích:
CONSTRAINT constraint_name
: Đặt tên cho ràng buộc khóa ngoại (tùy chọn).FOREIGN KEY (col_name, ...)
: Chỉ định cột hoặc tập hợp cột trong bảng hiện tại làm khóa ngoại.REFERENCES parent_tbl_name (col_name, ...)
: Trỏ đến bảng cha và cột khóa chính mà khóa ngoại tham chiếu đến.
Ví dụ cụ thể:
Trong ví dụ trên:
dept_id
trong bảngEmployee
là khóa ngoại, tham chiếu đếndept_id
(khóa chính) trong bảngDepartment
.Điều này đảm bảo rằng mọi giá trị trong
dept_id
của bảngEmployee
phải tồn tại trongdept_id
của bảngDepartment
, duy trì tính toàn vẹn dữ liệu giữa hai bảng.
Khóa duy nhất (Unique Key) là gì?
Khóa duy nhất là một trường (column) hoặc tập hợp các trường trong một bảng cơ sở dữ liệu đảm bảo rằng tất cả các giá trị được lưu trữ trong cột đó là duy nhất. Điều này có nghĩa là một cột không thể chứa các giá trị trùng lặp. Khóa duy nhất cung cấp tính duy nhất cho một cột hoặc một tập hợp các cột.
Ví dụ cú pháp:
Giải thích:
UNIQUE
: Ràng buộc này yêu cầu tất cả giá trị trongcol2
phải khác nhau.Không giống khóa chính (primary key), khóa duy nhất có thể cho phép giá trị
null
(tùy thuộc vào hệ quản trị cơ sở dữ liệu), nhưng nếu có giá trị, chúng không được trùng lặp.
Ví dụ cụ thể:
Trong ví dụ trên:
email
là một khóa duy nhất, đảm bảo không có hai nhân viên nào trong bảngEmployee
có cùng địa chỉ email.Nếu một bản ghi có
email
lànull
, điều này thường được phép (trong các hệ như MySQL), nhưng các giá trị khôngnull
phải duy nhất.
So sánh với khóa chính:
Khóa chính: Không cho phép
null
, duy nhất, và chỉ có một trong mỗi bảng.Khóa duy nhất: Có thể cho phép
null
(tùy hệ cơ sở dữ liệu), duy nhất, và một bảng có thể có nhiều khóa duy nhất.
Khóa duy nhất rất hữu ích khi cần đảm bảo tính duy nhất cho một trường không phải là khóa chính, chẳng hạn như email, số điện thoại, hoặc mã định danh phụ.
Chuẩn hóa (Normalization) trong Cơ sở dữ liệu là gì?
Chuẩn hóa là quá trình tổ chức dữ liệu trong cơ sở dữ liệu để giảm thiểu dư thừa (redundancy) và đảm bảo tính toàn vẹn dữ liệu (data integrity). Có một số quy tắc chuẩn hóa, thường được gọi là các dạng chuẩn (Normal Forms), bao gồm:
1. Dạng chuẩn thứ nhất (1NF - First Normal Form)
Quy tắc:
Mỗi ô trong bảng chỉ nên chứa một giá trị duy nhất (không chứa danh sách hoặc tập hợp).
Mỗi bản ghi (row) phải là duy nhất (không trùng lặp).
Mục tiêu: Loại bỏ dữ liệu đa trị (multi-valued data) và đảm bảo bảng ở dạng quan hệ cơ bản.
Ví dụ: Thay vì:
Chuẩn hóa thành:
2. Dạng chuẩn thứ hai (2NF - Second Normal Form)
Quy tắc:
Đã thỏa mãn 1NF.
Tất cả các thuộc tính không phải khóa (non-key attributes) phải phụ thuộc hoàn toàn vào toàn bộ khóa chính (full functional dependency), không chỉ một phần của nó.
Mục tiêu: Loại bỏ phụ thuộc chức năng một phần (partial dependency).
Ví dụ: Thay vì:
Chuẩn hóa thành:
và
3. Dạng chuẩn thứ ba (3NF - Third Normal Form)
Quy tắc:
Đã thỏa mãn 2NF.
Không có phụ thuộc chức năng bắc cầu (transitive functional dependency).
Phụ thuộc bắc cầu: Khi một thuộc tính không phải khóa phụ thuộc vào một thuộc tính không phải khóa khác thay vì phụ thuộc trực tiếp vào khóa chính.
Mục tiêu: Loại bỏ phụ thuộc gián tiếp giữa các thuộc tính.
Ví dụ: Thay vì:
Chuẩn hóa thành:
và
Ý nghĩa của chuẩn hóa
Giảm dư thừa dữ liệu: Tránh lưu trữ thông tin trùng lặp không cần thiết.
Tăng tính toàn vẹn: Đảm bảo dữ liệu nhất quán và dễ cập nhật.
Hiệu quả truy vấn: Tối ưu hóa cấu trúc bảng cho các thao tác truy vấn.
Chuẩn hóa thường được áp dụng đến 3NF trong thực tế, vì các dạng cao hơn (như BCNF, 4NF) có thể làm phức tạp hóa thiết kế mà không mang lại lợi ích đáng kể trong nhiều trường hợp.
Nhược điểm của việc không thực hiện chuẩn hóa cơ sở dữ liệu
Việc không áp dụng chuẩn hóa (Normalization) cho cơ sở dữ liệu có thể dẫn đến một số nhược điểm lớn, bao gồm:
Dư thừa dữ liệu (Redundancy):
Các thông tin trùng lặp xuất hiện trong cơ sở dữ liệu, gây lãng phí không gian lưu trữ trên đĩa.
Ví dụ: Nếu tên phòng ban được lưu lặp lại trong bảng nhân viên thay vì tách thành bảng riêng, dung lượng lưu trữ sẽ tăng không cần thiết.
Không nhất quán dữ liệu (Inconsistency):
Khi dữ liệu dư thừa không được đồng bộ, sự không nhất quán sẽ xảy ra. Nếu một bảng được cập nhật (ví dụ: đổi tên phòng ban) nhưng bảng khác không được cập nhật tương ứng, dữ liệu sẽ mâu thuẫn.
Ví dụ: Tên phòng ban "HR" được sửa thành "Human Resources" trong một bảng nhưng vẫn giữ nguyên "HR" ở bảng khác.
Khó khăn trong bảo trì (Maintenance Problems):
Sự không nhất quán do dư thừa làm tăng độ phức tạp khi cập nhật, xóa hoặc thêm dữ liệu, dẫn đến chi phí bảo trì cao hơn.
Các thao tác sửa đổi phải được thực hiện ở nhiều nơi thay vì một nơi duy nhất.
Ảnh hưởng đến đặc tính ACID:
Dư thừa và không nhất quán có thể phá vỡ các đặc tính ACID (Atomicity, Consistency, Isolation, Durability) của cơ sở dữ liệu, đặc biệt là Consistency (Tính nhất quán). Điều này làm giảm độ tin cậy của hệ thống, đặc biệt trong các ứng dụng yêu cầu giao dịch chính xác.
Ví dụ minh họa:
Không chuẩn hóa:
Nếu đổi
DeptName
từ "HR" thành "Human Resources" choEmployeeID = 1
mà quên đổi choEmployeeID = 2
, dữ liệu sẽ không nhất quán.Lãng phí dung lượng khi lưu "HR" hai lần thay vì tách thành bảng riêng.
Chuẩn hóa sẽ giải quyết các vấn đề này bằng cách tách thành hai bảng:
Kết luận
Không chuẩn hóa dẫn đến lãng phí tài nguyên, khó duy trì và rủi ro về tính toàn vẹn dữ liệu. Do đó, chuẩn hóa là bước quan trọng để thiết kế cơ sở dữ liệu hiệu quả và đáng tin cậy.
Phi chuẩn hóa (Denormalization) trong Cơ sở dữ liệu là gì?
Phi chuẩn hóa là một kỹ thuật được các quản trị viên cơ sở dữ liệu sử dụng để tối ưu hóa hiệu suất của hạ tầng cơ sở dữ liệu. Kỹ thuật này dựa trên khái niệm chuẩn hóa (Normalization), vốn được định nghĩa là quá trình sắp xếp cơ sở dữ liệu thành các bảng một cách hợp lý cho một mục đích cụ thể. Phi chuẩn hóa cho phép thêm dữ liệu dư thừa (redundant data) vào một cơ sở dữ liệu đã được chuẩn hóa nhằm giảm bớt các vấn đề liên quan đến các truy vấn cơ sở dữ liệu phức tạp, chẳng hạn như việc kết hợp dữ liệu từ nhiều bảng thành một bảng duy nhất. Nó bổ sung các thông tin dư thừa vào các bảng để tránh các phép nối (join) phức tạp và nhiều thao tác phức tạp khác.
Phi chuẩn hóa không có nghĩa là quá trình chuẩn hóa sẽ bị bỏ qua. Thay vào đó, nó là một chiến lược tối ưu hóa được thực hiện sau khi quá trình chuẩn hóa đã hoàn tất.
Đặc điểm của Phi chuẩn hóa:
Mục tiêu: Tăng tốc độ truy vấn và cải thiện hiệu suất đọc (read performance) bằng cách giảm số lượng phép nối hoặc tính toán phức tạp.
Cách thực hiện: Thêm dữ liệu dư thừa hoặc sao chép dữ liệu từ bảng này sang bảng khác để truy cập nhanh hơn.
Ví dụ: Chuẩn hóa:
Phi chuẩn hóa:
Trong trường hợp này,
DeptName
được thêm trực tiếp vào bảngEmployee
, loại bỏ nhu cầu nối với bảngDepartment
.
Khi nào nên sử dụng Phi chuẩn hóa?
Khi hiệu suất truy vấn (query performance) quan trọng hơn tính toàn vẹn dữ liệu chặt chẽ.
Trong các hệ thống chỉ đọc (read-heavy) như kho dữ liệu (data warehouse) hoặc báo cáo (reporting systems).
Khi cần giảm độ trễ (latency) trong các ứng dụng yêu cầu tốc độ cao.
Ưu điểm:
Tăng tốc độ truy vấn: Tránh các phép nối phức tạp, đặc biệt trong các bảng lớn.
Đơn giản hóa truy vấn: Giảm số lượng bảng cần truy cập.
Nhược điểm:
Dư thừa dữ liệu: Tốn thêm dung lượng lưu trữ.
Khó bảo trì: Cập nhật dữ liệu ở nhiều nơi có thể dẫn đến không nhất quán nếu không được quản lý tốt.
Phức tạp hóa ghi (write): Thêm, sửa, xóa dữ liệu đòi hỏi cập nhật đồng bộ ở nhiều bảng.
View (Lượt xem) trong SQL là gì?
Một View trong SQL là một đối tượng cơ sở dữ liệu không chứa giá trị thực tế. Nó là một bảng ảo (virtual table) chứa một tập hợp con dữ liệu từ một hoặc nhiều bảng. View trông giống như một bảng thực sự với các hàng (rows) và cột (columns), nhưng nó chiếm ít không gian hơn vì không tồn tại vật lý trong cơ sở dữ liệu. View hoạt động tương tự như bảng gốc (base table), nhưng bản thân nó không lưu trữ dữ liệu riêng. Tên của View luôn phải là duy nhất.
View có thể lấy dữ liệu từ một hoặc nhiều bảng. Nếu có bất kỳ thay đổi nào trong bảng gốc, những thay đổi đó cũng sẽ được phản ánh trong View.
Mục đích chính của View:
Cơ chế bảo mật: View cho phép giới hạn quyền truy cập vào dữ liệu, chỉ hiển thị những cột hoặc hàng mà người dùng được phép xem.
Đơn giản hóa truy vấn: View là một đối tượng có thể tìm kiếm (searchable object), cho phép sử dụng câu lệnh SQL để truy vấn dữ liệu giống như với bảng. Nó chỉ hiển thị dữ liệu được trả về bởi truy vấn đã khai báo khi View được tạo.
Cú pháp tạo View:
Ví dụ:
View
EmployeeView
chỉ hiển thịemp_id
vàname
của những nhân viên thuộc phòng ban códept_id = 10
.Khi truy vấn
SELECT * FROM EmployeeView;
, bạn sẽ thấy dữ liệu theo định nghĩa trên.
Ưu điểm của View:
Bảo mật: Ẩn các cột nhạy cảm (ví dụ: lương) khỏi người dùng không có quyền.
Đơn giản hóa: Che giấu các truy vấn phức tạp (như join nhiều bảng) dưới dạng một bảng ảo dễ sử dụng.
Tính linh hoạt: Tự động cập nhật khi dữ liệu bảng gốc thay đổi.
Nhược điểm:
Không lưu trữ dữ liệu: View không cải thiện hiệu suất nếu truy vấn cơ bản phức tạp hoặc bảng gốc lớn.
Giới hạn chỉnh sửa: Một số View (đặc biệt là View phức tạp) không cho phép cập nhật trực tiếp dữ liệu.
Chỉ mục (Index) trong SQL là gì?
Chỉ mục là một cấu trúc dữ liệu trên đĩa được liên kết với một bảng hoặc view, giúp tăng tốc độ truy xuất các hàng (rows) trong cơ sở dữ liệu. Nó giảm chi phí của truy vấn (query cost), vì chi phí cao có thể làm giảm hiệu suất của truy vấn. Chỉ mục được sử dụng để nâng cao hiệu suất và cho phép truy xuất bản ghi từ bảng nhanh hơn. Việc lập chỉ mục giảm số lượng trang dữ liệu (data pages) cần truy cập để tìm một trang dữ liệu cụ thể. Ngoài ra, chỉ mục thường có giá trị duy nhất, nghĩa là không thể trùng lặp, và nó tạo một mục nhập (entry) cho mỗi giá trị, giúp việc truy xuất dữ liệu trở nên nhanh chóng.
Các loại chỉ mục trong SQL
1. Chỉ mục duy nhất (Unique Index)
Mô tả: Chỉ mục duy nhất được sử dụng để đảm bảo tính duy nhất của giá trị trong một hoặc nhiều cột. Một bảng có thể có nhiều chỉ mục duy nhất. Khi tạo chỉ mục này, người dùng cần kiểm tra dữ liệu trong cột để đảm bảo không có giá trị trùng lặp, vì chỉ mục duy nhất được áp dụng khi cột chứa các giá trị độc nhất. Nếu một cột được lập chỉ mục duy nhất, nó không cho phép chứa giá trị trùng lặp. Chỉ mục này thường được tự động áp dụng khi một khóa chính (primary key) được định nghĩa.
Cú pháp:
Ví dụ:
Đảm bảo cột
email
không chứa giá trị trùng lặp.
2. Chỉ mục phân cụm (Clustered Index)
Mô tả: Chỉ mục phân cụm thực chất là cách tổ chức dữ liệu của bảng, trong đó dữ liệu của các hàng được lưu trữ theo thứ tự của chỉ mục. Nó xác định thứ tự vật lý của dữ liệu trong bảng dựa trên các giá trị khóa, và chỉ có thể sắp xếp theo một hướng (tăng hoặc giảm). Mỗi bảng chỉ có thể có duy nhất một chỉ mục phân cụm. Đây là loại chỉ mục được tạo tự động khi khóa chính được định nghĩa. Chỉ mục phân cụm thường được ưu tiên khi bảng yêu cầu nhiều thao tác sửa đổi dữ liệu (insert, update, delete).
Ví dụ: Khi tạo bảng với khóa chính:
Chỉ mục phân cụm sẽ tự động được tạo trên
emp_id
, sắp xếp dữ liệu theo cột này.
3. Chỉ mục không phân cụm (Non-Clustered Index)
Mô tả: Các chỉ mục không phải là chỉ mục phân cụm (tức là không phải khóa chính) được gọi là chỉ mục không phân cụm. Trong khi chỉ mục phân cụm được tạo tự động với khóa chính, chỉ mục không phân cụm được tạo khi truy vấn sử dụng nhiều điều kiện nối (join) hoặc bộ lọc (filter). Dữ liệu bảng và chỉ mục không phân cụm được lưu trữ ở các vị trí khác nhau. Nó không thay đổi thứ tự vật lý của bảng mà chỉ duy trì thứ tự logic của dữ liệu. Chỉ mục không phân cụm cải thiện hiệu suất cho các truy vấn sử dụng các khóa không phải khóa chính.
Cú pháp:
Ví dụ: Tạo chỉ mục trên cột
name
để tăng tốc tìm kiếm theo tên mà không cần khóa chính.
So sánh các loại chỉ mục
Tiêu chí
Unique Index
Clustered Index
Non-Clustered Index
Tính duy nhất
Bắt buộc
Có thể (nếu là khóa chính)
Không bắt buộc
Số lượng trên bảng
Nhiều
Chỉ một
Nhiều
Lưu trữ dữ liệu
Chỉ lưu chỉ mục
Lưu dữ liệu bảng theo thứ tự
Lưu chỉ mục riêng biệt
Tác động thứ tự
Không ảnh hưởng vật lý
Sắp xếp vật lý dữ liệu
Duy trì logic, không vật lý
Lợi ích của Chỉ mục:
Tăng tốc truy vấn: Đặc biệt với các lệnh
SELECT
,WHERE
,JOIN
.Hiệu quả tìm kiếm: Giảm thời gian quét toàn bảng (full table scan).
Nhược điểm:
Chi phí lưu trữ: Chỉ mục chiếm thêm dung lượng đĩa.
Hiệu suất ghi: Các thao tác
INSERT
,UPDATE
,DELETE
chậm hơn do phải cập nhật chỉ mục.
"TRIGGER" trong SQL là gì?
Một Trigger (kích hoạt) trong SQL là một tập hợp các câu lệnh SQL được lưu trữ trong danh mục hệ thống (system catalog). Đây là một loại thủ tục lưu trữ (stored procedure) đặc biệt, được gọi tự động để phản hồi một sự kiện cụ thể. Trigger cho phép thực thi một loạt mã khi một lệnh INSERT
, UPDATE
hoặc DELETE
được chạy trên một bảng cụ thể, vì Trigger là tập hợp các hành động được kích hoạt bất cứ khi nào các lệnh DML (Data Manipulation Language - Ngôn ngữ thao tác dữ liệu) được gửi đến hệ thống.
Trigger trong SQL có hai thành phần chính:
Hành động (Action): Là tập hợp mã hoặc logic được thực thi khi Trigger được kích hoạt.
Sự kiện (Event): Là sự kiện kích hoạt Trigger, chẳng hạn như thêm, sửa, hoặc xóa dữ liệu trong bảng.
Khi một hành động nhất định được thực hiện (ví dụ: chèn một bản ghi), một sự kiện xảy ra và Trigger sẽ tự động thực thi các hành động đã được định nghĩa.
Cú pháp cơ bản:
BEFORE
hoặcAFTER
: Xác định Trigger chạy trước hay sau sự kiện.INSERT | UPDATE | DELETE
: Loại sự kiện DML kích hoạt Trigger.FOR EACH ROW
: Áp dụng hành động cho từng hàng bị ảnh hưởng.
Ví dụ:
Giả sử muốn tự động ghi log khi có bản ghi mới được thêm vào bảng Employee
.
Giải thích:
Trigger
after_employee_insert
chạy sau khi một bản ghi được chèn vào bảngEmployee
.NEW.emp_id
tham chiếu đến giá trịemp_id
của bản ghi vừa được thêm.Mỗi khi chèn một nhân viên mới, một bản ghi log sẽ tự động được thêm vào
Employee_Log
.
Các loại Trigger:
Before Trigger: Chạy trước khi sự kiện xảy ra, thường dùng để kiểm tra hoặc sửa đổi dữ liệu trước khi lưu.
Ví dụ: Kiểm tra giá trị lương không âm trước khi cập nhật.
After Trigger: Chạy sau khi sự kiện xảy ra, thường dùng để ghi log hoặc cập nhật bảng liên quan.
Ưu điểm của Trigger:
Tự động hóa: Thực thi logic mà không cần can thiệp thủ công.
Tính toàn vẹn: Đảm bảo các quy tắc kinh doanh được áp dụng nhất quán (ví dụ: cập nhật số dư sau giao dịch).
Ghi log: Theo dõi thay đổi dữ liệu dễ dàng.
Nhược điểm:
Phức tạp: Logic ẩn trong Trigger có thể khó bảo trì hoặc debug.
Hiệu suất: Trigger chạy mỗi khi sự kiện xảy ra, có thể làm chậm thao tác DML nếu logic nặng.
Khó kiểm soát: Dễ gây hiệu ứng domino nếu không được thiết kế cẩn thận.
Toán tử tập hợp (Set Operators) trong SQL là gì?
Toán tử tập hợp trong SQL được sử dụng để kết hợp dữ liệu từ một hoặc nhiều bảng cùng loại. Mặc dù chúng tương tự như phép nối (JOIN) trong SQL, nhưng có một sự khác biệt quan trọng:
SQL JOIN: Kết hợp các cột từ các bảng khác nhau.
Set Operators: Kết hợp các hàng từ các truy vấn khác nhau.
Các truy vấn SQL chứa toán tử tập hợp được gọi là truy vấn ghép (compound queries). Trong SQL, có bốn loại toán tử tập hợp chính:
1. UNION
Mô tả: Toán tử
UNION
kết hợp kết quả của hai hoặc nhiều truy vấnSELECT
thành một tập hợp kết quả duy nhất. Nó tự động loại bỏ các hàng trùng lặp và sắp xếp theo thứ tự tăng dần (theo mặc định, nếu không chỉ địnhORDER BY
).Cú pháp:
Ví dụ:
Kết quả: Danh sách tên duy nhất từ cả hai bảng.
2. UNION ALL
Mô tả: Toán tử
UNION ALL
tương tự nhưUNION
, nhưng nó không loại bỏ các hàng trùng lặp. Do đó, nó nhanh hơnUNION
vì không cần xử lý loại bỏ trùng lặp.Cú pháp:
Ví dụ:
Kết quả: Tất cả tên từ cả hai bảng, bao gồm cả trùng lặp.
3. INTERSECT
Mô tả: Toán tử
INTERSECT
trả về các bản ghi chung (giao nhau) từ hai hoặc nhiều câu lệnhSELECT
. Nó chỉ lấy các bản ghi duy nhất và sắp xếp theo thứ tự tăng dần theo mặc định. Số lượng cột và kiểu dữ liệu trong các truy vấn phải giống nhau.Cú pháp:
Ví dụ:
Kết quả: Chỉ những tên xuất hiện trong cả hai bảng.
4. MINUS (hoặc EXCEPT)
Mô tả: Toán tử
MINUS
(trong Oracle, hoặcEXCEPT
trong SQL Server/PostgreSQL) trả về các bản ghi từ truy vấn đầu tiên mà không xuất hiện trong truy vấn thứ hai. Nó không trả về các giá trị trùng lặp. Số lượng cột và kiểu dữ liệu phải khớp nhau.Cú pháp:
Ví dụ:
Kết quả: Những tên chỉ có trong bảng
Employee
mà không có trongContractor
.
Lưu ý chung:
Điều kiện sử dụng:
Số lượng cột trong các truy vấn phải giống nhau.
Kiểu dữ liệu của các cột tương ứng phải tương thích.
Hiệu suất:
UNION ALL
nhanh hơnUNION
vì không cần loại bỏ trùng lặp.INTERSECT
vàMINUS
có thể tốn tài nguyên hơn nếu bảng lớn.
Sắp xếp: Để sắp xếp kết quả, sử dụng
ORDER BY
ở cuối truy vấn ghép (chỉ áp dụng cho toàn bộ kết quả).
Ứng dụng thực tế:
UNION/UNION ALL: Tổng hợp danh sách từ nhiều nguồn (ví dụ: danh sách nhân viên từ các chi nhánh).
INTERSECT: Tìm bản ghi chung (ví dụ: khách hàng vừa mua hàng vừa đăng ký thành viên).
MINUS: Loại trừ dữ liệu (ví dụ: nhân viên không tham gia khóa đào tạo).
Toán tử tập hợp là công cụ mạnh mẽ để thao tác dữ liệu trong SQL, đặc biệt hữu ích khi cần xử lý dữ liệu từ nhiều truy vấn mà không cần phép nối phức tạp.
Sự khác biệt giữa toán tử IN
và BETWEEN
trong SQL
IN
và BETWEEN
trong SQLCả hai toán tử IN
và BETWEEN
đều là các toán tử logic trong SQL, được sử dụng để lọc dữ liệu trong câu lệnh WHERE
. Tuy nhiên, chúng có mục đích và cách hoạt động khác nhau. Dưới đây là sự khác biệt chi tiết:
1. Toán tử BETWEEN
BETWEEN
Mô tả: Toán tử
BETWEEN
được sử dụng để chọn một phạm vi dữ liệu nằm giữa hai giá trị (bao gồm cả hai giá trị biên). Nó áp dụng được cho số, văn bản và ngày tháng.Cách hoạt động:
Kiểm tra xem một giá trị có nằm trong khoảng từ giá trị nhỏ nhất đến giá trị lớn nhất hay không.
Tương đương với điều kiện
>=
và<=
.
Cú pháp:
Ví dụ:
Kết quả: Trả về tất cả nhân viên có lương từ 30,000 đến 50,000 (bao gồm cả 30,000 và 50,000).
2. Toán tử IN
IN
Mô tả: Toán tử
IN
là một toán tử logic dùng để kiểm tra xem một giá trị cụ thể có tồn tại trong một tập hợp các giá trị hay không. Nó thay thế cho việc sử dụng nhiều điều kiệnOR
trong truy vấn.Cách hoạt động:
So sánh giá trị của cột với một danh sách các giá trị rời rạc.
Tương đương với nhiều điều kiện
=
được nối bằngOR
.
Cú pháp:
Ví dụ:
Kết quả: Trả về tất cả nhân viên thuộc các phòng ban có
dept_id
là 10, 20 hoặc 30.
So sánh chi tiết
Tiêu chí
BETWEEN
IN
Mục đích
Lọc dữ liệu trong một phạm vi liên tục
Lọc dữ liệu từ một tập hợp rời rạc
Loại giá trị
Số, văn bản, ngày tháng
Bất kỳ kiểu dữ liệu nào
Tính bao gồm
Bao gồm cả giá trị biên
Chỉ khớp với các giá trị liệt kê
Tương đương logic
column >= value1 AND column <= value2
column = value1 OR column = value2
Ví dụ thực tế
Lọc lương từ 30K đến 50K
Lọc nhân viên ở phòng 10, 20, 30
Hiệu suất
Thường nhanh hơn với phạm vi lớn
Hiệu quả với danh sách nhỏ
Ví dụ minh họa sự khác biệt:
Sử dụng
BETWEEN
:Trả về nhân viên có độ tuổi từ 25 đến 30 (bao gồm 25 và 30).
Sử dụng
IN
:Trả về nhân viên có độ tuổi chính xác là 25, 27 hoặc 30, không bao gồm các tuổi khác như 26 hay 28.
Khi nào nên sử dụng?
Sử dụng
BETWEEN
: Khi cần lọc dữ liệu trong một phạm vi liên tục (continuous range), chẳng hạn như khoảng thời gian, mức lương, hoặc giá trị số liên tục.Sử dụng
IN
: Khi cần kiểm tra một giá trị thuộc một tập hợp cụ thể (discrete set), đặc biệt khi danh sách giá trị không liên tục hoặc không theo thứ tự.
Cả hai toán tử đều giúp đơn giản hóa truy vấn, nhưng lựa chọn phụ thuộc vào bài toán cụ thể và tính chất của dữ liệu cần lọc.
Thuộc tính ACID trong cơ sở dữ liệu là gì?
Thuộc tính ACID là một tập hợp các đặc tính được thiết kế để đảm bảo rằng các giao dịch (transaction) trong cơ sở dữ liệu được thực hiện một cách đáng tin cậy. Một giao dịch là một đơn vị logic duy nhất bao gồm một hoặc nhiều tác vụ. Các thuộc tính này giúp duy trì tính nhất quán của cơ sở dữ liệu trước và sau giao dịch, đồng thời đảm bảo rằng các giao dịch dữ liệu được xử lý một cách an toàn và ổn định trong hệ thống cơ sở dữ liệu.
ACID là viết tắt của: Atomicity (Tính nguyên tử), Consistency (Tính nhất quán), Isolation (Tính cô lập), Durability (Tính bền vững).
1. Atomicity (Tính nguyên tử)
Mô tả: Tính nguyên tử đảm bảo rằng tất cả các câu lệnh hoặc thao tác trong một giao dịch phải được thực thi thành công. Nếu một phần của giao dịch thất bại, toàn bộ giao dịch sẽ thất bại, và trạng thái của cơ sở dữ liệu sẽ không thay đổi (quay về trạng thái ban đầu).
Công cụ chính:
COMMIT
: Xác nhận giao dịch thành công và lưu thay đổi.ROLLBACK
: Hủy bỏ giao dịch và khôi phục trạng thái trước đó.AUTO-COMMIT
: Tự động xác nhận giao dịch sau mỗi câu lệnh (tùy hệ cơ sở dữ liệu).
Ví dụ: Khi chuyển tiền từ tài khoản A sang B, cả hai thao tác (trừ tiền A, cộng tiền B) phải thành công. Nếu một bước thất bại, cả giao dịch bị hủy.
2. Consistency (Tính nhất quán)
Mô tả: Tính nhất quán đảm bảo rằng dữ liệu phải tuân theo tất cả các quy tắc xác thực (validation rules), ràng buộc (constraints), và quy định của cơ sở dữ liệu. Nói đơn giản, cơ sở dữ liệu chỉ thay đổi trạng thái khi giao dịch được xác nhận (
COMMIT
) thành công. Nó cũng bảo vệ dữ liệu khỏi sự cố như crash hệ thống.Ví dụ: Nếu một ràng buộc yêu cầu số dư tài khoản không được âm, giao dịch trừ tiền chỉ được phép nếu số dư sau trừ vẫn dương.
3. Isolation (Tính cô lập)
Mô tả: Tính cô lập đảm bảo rằng các giao dịch thực thi đồng thời (concurrent transactions) phải hoạt động độc lập với nhau. Các câu lệnh trong một giao dịch không được ảnh hưởng hoặc bị ảnh hưởng bởi các giao dịch khác cho đến khi hoàn tất. Mục tiêu chính là kiểm soát tính đồng thời (concurrency) trong cơ sở dữ liệu.
Ví dụ: Nếu hai giao dịch cùng cập nhật số dư tài khoản, tính cô lập đảm bảo giao dịch thứ hai không thấy thay đổi của giao dịch thứ nhất cho đến khi giao dịch thứ nhất hoàn tất (
COMMIT
).Cơ chế: Sử dụng khóa (locks) hoặc phiên bản hóa (versioning).
4. Durability (Tính bền vững)
Mô tả: Tính bền vững đảm bảo rằng một khi giao dịch đã được xác nhận (
COMMIT
), các thay đổi sẽ được lưu trữ vĩnh viễn, ngay cả khi hệ thống gặp sự cố như mất điện, crash, hoặc lỗi phần cứng.Ví dụ: Sau khi giao dịch chuyển tiền được xác nhận, dữ liệu được ghi vào ổ cứng và không bị mất kể cả khi server tắt đột ngột.
Cơ chế: Sử dụng nhật ký giao dịch (transaction log) để khôi phục dữ liệu nếu cần.
Ví dụ tổng quát:
Giả sử một giao dịch chuyển 100 USD từ tài khoản A sang B:
Atomicity: Cả trừ 100 USD từ A và cộng 100 USD vào B đều phải thành công, nếu không cả hai sẽ bị hủy.
Consistency: Tổng số tiền trong hệ thống không thay đổi (A + B = const).
Isolation: Giao dịch này không bị ảnh hưởng bởi giao dịch khác đang chạy cùng lúc.
Durability: Sau khi hoàn tất, dữ liệu được lưu vĩnh viễn dù hệ thống có crash.
Ý nghĩa của ACID:
Độ tin cậy: Đảm bảo giao dịch được xử lý chính xác, ngay cả trong môi trường đồng thời hoặc khi có lỗi.
Ứng dụng: Đặc biệt quan trọng trong các hệ thống như ngân hàng, thương mại điện tử, nơi tính toàn vẹn dữ liệu là tối quan trọng.
ACID là nền tảng của các hệ quản trị cơ sở dữ liệu quan hệ (RDBMS) như MySQL, PostgreSQL, Oracle, giúp chúng hoạt động ổn định và đáng tin cậy.
Cách sử dụng câu lệnh DISTINCT
trong SQL và mục đích của nó
DISTINCT
trong SQL và mục đích của nóDISTINCT
là gì?
Từ khóa DISTINCT
trong SQL được sử dụng để đảm bảo rằng các giá trị được truy xuất từ một truy vấn là duy nhất, tức là không chứa các giá trị trùng lặp. Nó thường được kết hợp với câu lệnh SELECT
để loại bỏ các bản ghi trùng lặp trong kết quả trả về từ một hoặc nhiều cột của bảng.
Cú pháp:
DISTINCT
: Loại bỏ các hàng trùng lặp trong kết quả.column_lists
: Danh sách các cột cần truy xuất giá trị duy nhất.WHERE [condition]
: Điều kiện lọc dữ liệu (tùy chọn).
Mục đích sử dụng:
Loại bỏ trùng lặp: Đảm bảo mỗi giá trị hoặc tổ hợp giá trị trong kết quả chỉ xuất hiện một lần.
Đơn giản hóa dữ liệu: Giúp trả về danh sách giá trị riêng biệt để phân tích hoặc hiển thị.
Hiệu quả trong báo cáo: Rất hữu ích khi cần liệt kê các giá trị độc nhất mà không quan tâm đến tần suất xuất hiện.
Ví dụ:
Truy xuất giá trị duy nhất từ một cột:
Kết quả: Liệt kê tất cả các
dept_id
(mã phòng ban) khác nhau trong bảngEmployee
, không có giá trị nào lặp lại, ngay cả khi nhiều nhân viên thuộc cùng một phòng ban.
Kết hợp nhiều cột:
Kết quả: Trả về các tổ hợp duy nhất của
dept_id
vàjob_title
. Nếu có hai nhân viên cùng phòng ban và chức danh, tổ hợp này chỉ xuất hiện một lần.
Kết hợp với điều kiện:
Kết quả: Trả về danh sách tên nhân viên duy nhất có lương trên 50,000.
So sánh với không dùng DISTINCT
:
Không có
DISTINCT
:Kết quả có thể chứa trùng lặp, ví dụ:
10, 20, 10, 30
.
Có
DISTINCT
:Kết quả chỉ chứa giá trị duy nhất:
10, 20, 30
.
Lưu ý:
Hiệu suất: Sử dụng
DISTINCT
có thể làm chậm truy vấn trên bảng lớn vì hệ thống phải thực hiện thao tác loại bỏ trùng lặp (giống như mộtGROUP BY
ngầm).Áp dụng trên toàn bộ hàng:
DISTINCT
kiểm tra sự duy nhất của toàn bộ tổ hợp cột trong câu lệnhSELECT
, không chỉ một cột riêng lẻ.Không dùng với aggregate functions: Thông thường không cần dùng
DISTINCT
với các hàm tổng hợp nhưCOUNT
,SUM
, trừ khi kết hợp trong ngữ cảnh đặc biệt.
Kết luận:
DISTINCT
là một công cụ hữu ích để lấy dữ liệu không trùng lặp trong SQL, đặc biệt phù hợp cho các tác vụ như liệt kê danh sách giá trị riêng biệt hoặc chuẩn bị dữ liệu cho báo cáo. Tuy nhiên, cần cân nhắc hiệu suất khi sử dụng trên các tập dữ liệu lớn.
Thứ tự mặc định của dữ liệu khi sử dụng mệnh đề ORDER BY
và cách thay đổi nó
ORDER BY
và cách thay đổi nóORDER BY
là gì?
Mệnh đề ORDER BY
trong SQL được sử dụng để sắp xếp dữ liệu trong bảng theo thứ tự tăng dần (ascending) hoặc giảm dần (descending) dựa trên một hoặc nhiều cột. Nó thường được đặt ở cuối câu lệnh SELECT
để định nghĩa cách dữ liệu được hiển thị.
Thứ tự mặc định:
Mặc định: Khi sử dụng
ORDER BY
mà không chỉ định hướng sắp xếp, dữ liệu sẽ được sắp xếp theo thứ tự tăng dần (ASC - Ascending).Đối với số: Từ nhỏ đến lớn (ví dụ: 1, 2, 3).
Đối với văn bản: Theo thứ tự bảng chữ cái (ví dụ: A, B, C).
Đối với ngày: Từ cũ đến mới.
Cách thay đổi thứ tự mặc định:
Để thay đổi sang thứ tự giảm dần (DESC - Descending), sử dụng từ khóa
DESC
sau tên cột trong mệnh đềORDER BY
.Từ khóa
ASC
là tùy chọn (vì nó là mặc định), nhưng có thể được thêm vào để tăng tính rõ ràng.
Cú pháp:
ASC
: Sắp xếp tăng dần (mặc định).DESC
: Sắp xếp giảm dần.
Ví dụ:
Sắp xếp tăng dần (mặc định):
Kết quả: Nhân viên được sắp xếp theo lương từ thấp đến cao (ví dụ: 30000, 40000, 50000).
Sắp xếp giảm dần:
Kết quả: Nhân viên được sắp xếp theo lương từ cao đến thấp (ví dụ: 50000, 40000, 30000).
Sắp xếp nhiều cột:
Kết quả:
Sắp xếp theo
dept_id
tăng dần trước (ví dụ: 10, 20, 30).Trong mỗi
dept_id
, sắp xếpsalary
giảm dần.
Lưu ý:
Thứ tự ưu tiên: Khi sắp xếp nhiều cột, SQL sẽ ưu tiên cột đầu tiên trong
ORDER BY
, sau đó đến cột tiếp theo.NULL values:
Trong một số hệ cơ sở dữ liệu (như MySQL), giá trị
NULL
được coi là nhỏ nhất khi sắp xếp tăng dần và lớn nhất khi sắp xếp giảm dần.Có thể dùng
NULLS FIRST
hoặcNULLS LAST
(trong PostgreSQL) để kiểm soát vị trí củaNULL
.
Hiệu suất: Sắp xếp trên bảng lớn hoặc cột không có chỉ mục (index) có thể chậm.
Kết luận:
Mệnh đề ORDER BY
mặc định sắp xếp dữ liệu theo thứ tự tăng dần (ASC
). Để thay đổi sang giảm dần, chỉ cần thêm DESC
sau tên cột. Điều này cho phép linh hoạt điều chỉnh cách hiển thị dữ liệu theo nhu cầu cụ thể của ứng dụng hoặc báo cáo.
Sự khác biệt giữa mệnh đề WHERE
và HAVING
trong SQL
WHERE
và HAVING
trong SQLMệnh đề WHERE
và HAVING
đều được sử dụng để lọc dữ liệu trong SQL, nhưng chúng khác nhau về thời điểm áp dụng và ngữ cảnh sử dụng. Dưới đây là sự khác biệt chính:
1. Mệnh đề WHERE
WHERE
Mô tả: Mệnh đề
WHERE
được sử dụng để lọc các bản ghi (rows) trước khi bất kỳ nhóm nào được thiết lập. Nó hoạt động trên từng hàng riêng lẻ trong bảng dựa trên điều kiện được chỉ định.Thời điểm áp dụng:
Áp dụng trước các hàm tổng hợp (aggregate functions) như
SUM
,COUNT
, hoặc trước khi nhóm dữ liệu bằngGROUP BY
.
Cú pháp:
Ví dụ:
Kết quả: Chỉ trả về các nhân viên có lương lớn hơn 50,000.
2. Mệnh đề HAVING
HAVING
Mô tả: Mệnh đề
HAVING
được sử dụng để lọc các giá trị từ các nhóm sau khi đã áp dụngGROUP BY
và tính toán các hàm tổng hợp. Nó hoạt động trên kết quả của nhóm, không phải từng hàng riêng lẻ.Thời điểm áp dụng:
Áp dụng sau khi dữ liệu đã được nhóm lại bằng
GROUP BY
và các hàm tổng hợp đã được tính toán.
Cú pháp:
Ví dụ:
Kết quả: Chỉ trả về các phòng ban có mức lương trung bình lớn hơn 60,000.
So sánh chi tiết
Tiêu chí
WHERE
HAVING
Mục đích
Lọc bản ghi riêng lẻ
Lọc nhóm sau khi dùng GROUP BY
Thời điểm áp dụng
Trước khi nhóm dữ liệu
Sau khi nhóm dữ liệu
Dùng với hàm tổng hợp
Không trực tiếp (chỉ lọc dữ liệu gốc)
Có (lọc dựa trên SUM
, COUNT
,...)
Vị trí trong truy vấn
Trước GROUP BY
Sau GROUP BY
Ví dụ điều kiện
salary > 50000
AVG(salary) > 60000
Ví dụ minh họa sự khác biệt:
Sử dụng
WHERE
:Lọc từng nhân viên có lương trên 50,000 trước khi xử lý thêm.
Sử dụng
HAVING
:Lọc các phòng ban có hơn 5 nhân viên sau khi nhóm.
Kết hợp cả hai:
Giải thích:
WHERE
lọc nhân viên có lương trên 40,000 trước.GROUP BY
nhóm theodept_id
.HAVING
lọc các nhóm có lương trung bình trên 60,000.
Lưu ý:
Thứ tự thực thi trong SQL:
FROM
WHERE
GROUP BY
HAVING
SELECT
ORDER BY
Do đó,WHERE
luôn được xử lý trướcHAVING
.
Hiệu suất:
WHERE
thường nhanh hơn vì nó giảm số lượng bản ghi trước khi nhóm, trong khiHAVING
xử lý sau khi nhóm, có thể tốn tài nguyên hơn.
Kết luận:
Sử dụng
WHERE
: Khi cần lọc dữ liệu gốc trước khi thực hiện bất kỳ nhóm hoặc tính toán nào.Sử dụng
HAVING
: Khi cần lọc dựa trên kết quả của các hàm tổng hợp hoặc sau khi nhóm dữ liệu. Sự khác biệt chính nằm ở thời điểm áp dụng:WHERE
lọc bản ghi riêng lẻ, cònHAVING
lọc nhóm.
Có bao nhiêu hàm tổng hợp (Aggregate Functions) trong SQL?
SQL cung cấp 7 hàm tổng hợp cơ bản, được sử dụng để thực hiện các phép tính trên một tập hợp dữ liệu. Dưới đây là danh sách và mô tả chi tiết:
1. AVG()
AVG()
Mô tả: Trả về giá trị trung bình của các giá trị trong một cột được chỉ định (chỉ tính các giá trị không
null
).Cú pháp:
AVG(column_name)
Ví dụ:
Kết quả: Trung bình lương của tất cả nhân viên.
2. COUNT()
COUNT()
Mô tả: Trả về số lượng hàng trong bảng hoặc số lượng giá trị không
null
trong một cột, tùy thuộc vào cách sử dụng.Cú pháp:
COUNT(column_name)
hoặcCOUNT(*)
Ví dụ:
Kết quả: Tổng số nhân viên trong bảng.
3. MAX()
MAX()
Mô tả: Trả về giá trị lớn nhất trong một nhóm giá trị của cột được chỉ định.
Cú pháp:
MAX(column_name)
Ví dụ:
Kết quả: Mức lương cao nhất trong bảng.
4. MIN()
MIN()
Mô tả: Trả về giá trị nhỏ nhất trong một nhóm giá trị của cột được chỉ định.
Cú pháp:
MIN(column_name)
Ví dụ:
Kết quả: Mức lương thấp nhất trong bảng.
5. SUM()
SUM()
Mô tả: Trả về tổng các giá trị không
null
trong cột được chỉ định.Cú pháp:
SUM(column_name)
Ví dụ:
Kết quả: Tổng lương của tất cả nhân viên.
6. FIRST()
FIRST()
Mô tả: Trả về giá trị đầu tiên của một biểu thức hoặc cột trong tập hợp dữ liệu.
Lưu ý: Không phải tất cả hệ quản trị cơ sở dữ liệu (DBMS) đều hỗ trợ (ví dụ: MySQL không có sẵn, nhưng SQL Server có).
Cú pháp:
FIRST(column_name)
Ví dụ:
Kết quả: Lương của nhân viên đầu tiên trong danh sách.
7. LAST()
LAST()
Mô tả: Trả về giá trị cuối cùng của một biểu thức hoặc cột trong tập hợp dữ liệu.
Lưu ý: Tương tự
FIRST()
, không phải DBMS nào cũng hỗ trợ (ví dụ: MySQL không có, nhưng SQL Server có).Cú pháp:
LAST(column_name)
Ví dụ:
Kết quả: Lương của nhân viên cuối cùng trong danh sách.
Lưu ý quan trọng:
Tính khả dụng:
AVG()
,COUNT()
,MAX()
,MIN()
, vàSUM()
là các hàm phổ biến, được hỗ trợ bởi hầu hết các hệ quản trị cơ sở dữ liệu như MySQL, PostgreSQL, SQL Server, Oracle.FIRST()
vàLAST()
không được hỗ trợ rộng rãi (ví dụ: MySQL không có, nhưng có thể thay bằngLIMIT
hoặc subquery).
Kết hợp với
GROUP BY
: Các hàm tổng hợp thường được dùng vớiGROUP BY
để tính toán trên từng nhóm dữ liệu.Xử lý
NULL
:Tất cả hàm (trừ
COUNT(*)
) đều bỏ qua giá trịnull
trong phép tính.
Kết luận:
SQL cung cấp 7 hàm tổng hợp cơ bản (AVG
, COUNT
, MAX
, MIN
, SUM
, FIRST
, LAST
), nhưng trong thực tế, 5 hàm đầu tiên (AVG
, COUNT
, MAX
, MIN
, SUM
) là phổ biến nhất và được sử dụng rộng rãi trong mọi hệ cơ sở dữ liệu. FIRST()
và LAST()
ít phổ biến hơn và phụ thuộc vào hệ DBMS cụ thể. Các hàm này rất hữu ích trong việc phân tích và tổng hợp dữ liệu.
Last updated