1.2 Cấu trúc cơ bản
Một cơ sở dữ liệu quan hệ bao gồm một tập hợp các quan hệ, mỗi quan hệ được gán một tên duy nhất và có một cấu trúc nhất định. SQL cho phép sử dụng giá trị rỗng để gán cho các giá trị không biết hoặc không tồn tại. SQL cho phép người sử dụng chỉ rõ các thuộc tính nào không thể gán giá trị rỗng (chúng ta sẽ thảo luận vấn đề này ở mục 1.11).
Cấu trúc cơ bản của một biểu thức SQL bao gồm ba mệnh đề: Select, From và Where.
· Mệnh đề Select tương ứng với phép chiếu của đại số quan hệ. Nó được sử dụng để liệt kê các thuộc tính được yêu cầu xuất hiện trong kết quả của truy vấn.
· Mệnh đề From tương ứng với phép toán tích Đề-các của đại số quan hệ. Nó liệt kê các quan hệ sẽ được quét qua trong quá trình thực hiện truy vấn.
· Mệnh đề Where tương ứng với điều kiện lọc của đại số quan hệ. Nó đề cập đến các thuộc tính của quan hệ xuất hiện trong mệnh đề From.
Cấu trúc thông thường của một truy vấn SQL có dạng:
select A1, A2, . . .,An
from r1, r2, . . . , rm
where P
Mỗi Ai đại diện cho một thuộc tính và một ri đại diện cho một quan hệ. P là điều kiện lọc. Truy vấn trên tươgn đương với biểu thức đại số quan hệ như sau:
ΠA1, A2,...,An(σP (r1 × r2 × · · · × rm))
Nếu không có mệnh đề Where thì nghĩa là truy vấn không có điều kiện. Tuy nhiên, không giống như kết quả của một biểu thức đại số quan hệ, kết quả của truy vấn SQL có thể chứa nhiều bộ giống nhau, chúng tôi sẽ bàn vấn đề này ở phần 1.2.8.
SQL hình thành nên phép tích Đề-các của các quan hệ có tên trong mệnh đề From, sau đó thực hiện phép chọn đại số quan hệ dựa trên các điều kiện ở mệnh đề Where và sau đó lọc lấy các kết quả của các thuộc tính ở mệnh đề Select. Trong thực tế, SQL có thể chuyển đổi biểu thức sang dạng tương đương để có thể thực hiện hiệu quả hơn.
1.2.1 Mệnh đề select
Dĩ nhiên, kết quả của một truy vấn SQL là một quan hệ. Chúng ta hãy xét một ví dụ đơn giản bằng cách sử dụng lược đồ quan hệ ngân hàng ở trên, yêu cầu “Hãy tìm tên của tất cả các chi nhánh trong quan hệ loan”.
select branch-name
from loan
Kết quả của một quan hệ bao gồm một thuộc tính với tiêu đề branch-name. Các ngôn ngữ truy vấn thông dụng thường dựa trên các ghi chú toán học rằng một quan hệ là một tập hợp. Do đó, các bộ có giá trị giống nhau không bao giờ xuất hiện trong các quan hệ. Trong thực tế, việc loại bỏ các giá trị giống nhau thường mất rất nhiều thời gian. Do đó, SQL (và các ngôn ngừ truy vấn khác) cho phép xuất hiện các bộ giống nhau trong quan hệ cũng như trong kết quả truy vấn.
Trong trường hợp chúng ta muốn loại bỏ các giá trị trùng nhau trong truy vấn, chúng ta phải chèn thêm từ khóa distinct sau mệnh đề select. Chúng ta có thể viết lại truy vấn ở trên như sau:
select distinct branch-name
from loan
nếu chúng ta muốn loại bỏ các giá trị trùng nhau.
SQL cho phép chúng ta sử dựng từ khóa all để chỉ định rõ ràng là muốn hiển thị tất cả giá trị trùng nhau:
select all branch-name
from loan
Do việc hiển thị các giá trị trùng nhau là việc mặc định trong SQL, chúng ta không cần phải sử dụng từ khóa all trong các ví dụ về sau. Trong trường hợp muốn loại bỏ các giá trị trùng nhau trong kết quả truy vấn, chúng ta sử dụng từ khóa distinct. Trong hầu hết các truy vấn, distinct rất ít được sử dụng, lý do là số lượng bộ trùng nhau trong kết quả truy vấn là không quan trọng. Tuy nhiên, trong một số trường hợp, số lượng bộ trùng nhau là quan trọng, chúng ta sẽ bàn lại vấn đề nay ftrong phần 1.2.8.
Ký hiệu “*” được dùng để đại diện cho “tất cả các thuộc tính”. Do đó, việc sử dụng loan.* trong ngay sau mệnh đề select sẽ chỉ ra rằng tất cả các thuộc tính của quan hệ loan sẽ được lựa chọn. Mệnh đề select với dạng select * sẽ chỉ ra rằng tất cả các thuộc tính của tất cả các quan hệ xuất hiện trong mệnh đề from sẽ được lựa chọn.
Mệnh đề select cũng có thể chứa các biểu thức số học liên quan các toán tử +, -, * và / trên các hằng số hoặc các thuộc tính của các bộ. Ví dụ, truy vấn:
select loan-number, branch-name, amount * 100
from loan
sẽ trả về một quan hệ tương đương quan hệ loan, ngoại trừ thuộc tính amount sẽ được nhân cho 100.
SQL cũng cung cấp các kiểu dữ liệu đặc biệt và cho phép các hàm số học thực hiện trên các kiểu dữ liệu này.
1.2.2 Mệnh đề where
Chúng ta sẽ mô tả việc sử dụng mệnh đề where trong SQL. Xét truy vấn “Hãy tìm tất cả các số tài khoản có gửi tiền ở ngân hàng trong quan hệ loan tại chi nhánh Perryridge với số tiền vay mượn lớn hơn $1200”. Truy vấn này được viết dưới dạng SQL như sau:
select loan-number
from loan
where branch-name = ’Perryridge’ and amount > 1200
SQL sử dụng các toán tử logic and, or và not để thực hiện phép nối mà không dùng các ký tự toán học như ∧, ∨, và ¬ trong mệnh đề where. Các toán tử của các phép nối có thể được thay thế bằng các toán tử so sánh như <, <=, >, >=, = và <>.
SQL cho phép chúng ta sử dụng các toán tử so sánh để so sánh chuỗi và các biểu thức số học, cũng như đối với các kiểu dữ liệu đặc biệt, ví dụ kiểu ngày tháng.
SQL chứa toán tử between để làm đơn giản hóa mệnh đề where khi muốn chỉ ra giá trị nằm trong khoảng nhỏ hơn hoặc bằng, lớn hơn hoặc bằng. Ví dụ , nếu chúng ta muốn biết số tài khoản vay mượn của quan hệ loan với số tiền vay mượn trong khoảng từ $90,000 đến $100,000, chúng ta có thể sử dụng từ khóa between để viết lệnh:
select loan-number
from loan
where amount between 90000 and 100000
thay thế cho lệnh:
select loan-number
from loan
where amount <= 100000 and amount >= 90000
Tương tự, chúng ta sử dụng toán tử so sánh not between để định nghĩa giá trị nằm ngoài khoảng giá trị được đưa ra.
1.2.3 Mệnh đề from
Cuối cùng, chúng ta hãy thảo luận việc sử dụng mệnh đề from. Mệnh đề from định nghĩa phép tích Đề-các của các quan hệ trong mệnh đề. Bởi vì phép kết nối tự nhiên được định nghĩa dưới dạng phép tích Đề-các, cho nên phép chọn và phép chiếu dễ dàng được mô tả dưới dạng câu lệnh SQL. Ví dụ, biểu thức đại số quan hệ dưới đây:
Πcustomer-name, loan-number, amount (borrower x loan)
dùng để truy xuất thông tin “Tìm tất cả khách hàng có tiền gửi và vay ở ngân hàng, liệt kê tên khách hàng, số tài khoản vay ngân hàng và số tiền mượn.” Trong SQL, truy vấn này có thể viết như sau:
select customer-name, borrower.loan-number, amount
from borrower, loan
where borrower.loan-number = loan.loan-number
Lưu ý rằng giống như đại số quan hệ, SQL sử dụng cú pháp relation-name.attribute-name để tránh sự nhập nhằng trong trường hợp tên thuộc tính xuất hiện trong nhiều quan hệ. Chúng ta có thể viết borrower.customer-name thay vì customername trong mệnh đề select. Tuy nhiên, bởi vì thuộc tính customer-name chỉ xuất hiện trong một quan hệ trong mệnh đề from, nên không xảy ra việc nhập nhằng dữ liệu khi chúng ta chỉ viết customer-name.
Chúng ta có thể mở rộng truy vấn trước đó và xét thêm một trường hợp phức tạp. Ví dụ, chúng ta yêu cầu người vay tiền ở chi nhánh Perryridge: “Tìm tên khách hàng, tên tài khoản vay mượn và số tiền mượn của tất cả sự vay mượn ở chi nhánh Perryridge”. Để viết truy vấn này, chúng ta cần có hai ràng buộc ở mệnh đề where và chúng được liên kết nhau qua toán tử logic and:
select customer-name, borrower.loan-number, amount
from borrower, loan
where borrower.loan-number = loan.loan-number and
branch-name = ’Perryridge’
Ngoài ra, SQL còn chứa một số phần mở rộng để thực hiện các phép kết nối tự nhiên và kết nối ngoài trong mệnh đề from. Chúng ta sẽ thảo luận về phần mở rộng này ở phần 1.10.