Chú ý: nếu có một cột nữa tham gia làm khóa chính, thì ta phải khai báo theo kiểu PRIMARY KEY column-1 [, column-2] ...như trong phần khai báo các ràng buộc bảng.. Ví dụ: s_id VARCHAR5
Trang 1Bà i 5
Bài này chủ yếu giới thiệu ngôn ngữ SQL và cũng chỉ giới thiệu ñược một phần rất nhỏ của SQL Ngôn ngữ SQL là ngôn ngữ với ñộ phức tạp rất lớn Ví dụ bộ tài liệu của chuẩn International Standard Database Language SQL (1992) - viết tắt SQL92 - dày 600 trang Các HQT CSDL trên thực tế cũng chỉ có thể tuân thủ một phần của SQL92 (tức là một tập con của SQL92) Mặc dầu vậy, các HQT CSDL có nhiều chức năng mở rộng mà SQL92 lại không có Thực tế này ñược biểu diễn một cách hình tượng như trong Hình 1
Hình 1: Ngôn ngữ chuẩn SQL92 và sự hỗ trợ của các HQT CSDL
Bài này giới hạn việc ñề cập các nội dung tương thích với SQL92 - mặc dù có thể
có các chuẩn khác mới hơn (xem dưới ñây) và các HQT CSDL có thể mở rộng một số câu lệnh của SQL92 Tuy nhiên, khi lấy ví dụ, các câu lệnh ñược chọn tương thích với MySQL
Từ kinh nghiệm thực tế chúng ta chỉ nên viết các lệnh thuộc chuẩn SQL92, vì như vậy, khi chuyển sang các HQT CSDL mới, khả năng tương thích sẽ cao hơn
1./ Ngu n g#c và m%t s# ñ(c tính c+a SQL
− Xuất phát từ nhu cầu truy xuất dữ liệu, người ta ñi ñến nhu cầu cần thống nhất một ngôn ngữ cho tất cả các HQT CSDL
− SQL (Structured Query Language) là chuẩn mặc nhiên phục vụ mục ñích
trên
− SQL là ngôn ngữ truy vấn (Query Language) và gắn chặt với lịch sử phát
triển CSDL quan hệ
− Chú ý rằng một trong 12 nguyên tắc của TS Codd về mô hình CSDL quan
hệ là phải sử dụng một ngôn ngữ thống nhất (Qui tắc #5)
của HQT CSDL
Trang 2− Vài mốc về phát triển chuẩn SQL:
Năm Tên Viết
1986 SQL-86
SQL-87
Lần ñầu tiên ñược công bố bởi ANSI Sau ñó ISO phê chuẩn vào năm 1987
1989 SQL-89 Phiên bản phụ
1992 SQL-92 SQL2 Phiên bản chính
1999 SQL:1999 SQL3 Thêm regular expression matching, truy vấn ñệ qui,
triggers, loại dữ liệu không vô hướng và một vài tính năng hướng ñối tượng (Tuy nhiên, loại dữ liệu không vô hướng
và hướng ñối tượng gây ra rất nhiều tranh cãi.)
2003 SQL:2003
Đưa vào XML, window functions, dữ liệu chuỗi và các cột có
giá trị tự ñộng
− Một số HQT CSDL hiện nay yểm trợ một phần của SQL3, SQL:2003 – như MySQL, PostgreSQL
− SQL là ngôn ngữ khai báo (Declarative Language), khác với ngôn ngữ thủ tục (Procedural Language) C++, Java là các ngôn ngữ thủ tục Ngôn ngữ khai báo chỉ ñịnh cái gì cần chứ không chỉ ñịnh cần phải làm như thế nào
ñể thực hiện Việc làm như thế nào do HQT CSDL ñảm trách
− SQL là ngôn ngữ tập hợp – nghĩa là các toán hạng là các phần tử của tập
hợp, vô hướng, rời rạc và không phân biệt thứ tự
2./ Đ0nh nghĩa d5 li7u (Data Definition)
■ Miền giá trị
Miền giá trị (domain) trong ngôn ngữ SQL chỉ là một cách viết tắt của các loại
dữ liệu cơ bản và SQL không bắt buộc phải sử dụng miền Chính vì lý do này, chúng ta sẽ không ñi chi tiết vào miền Ta sẽ phân tích ở khía cạnh thực tế của vấn ñề khi ñề cập các ứng dụng cụ thể
Trang 3■ Tạo bảng (CREATE TABLE)
Cú pháp hình thức:
CREATE TABLE table-name ({column-descr|constraint}
[,{column-descr|constraint}] );
Giải thích cú pháp:
Câu lệnh có hai phần chính là tạo tên bảng (CREATE TABLE table-name)
và ñịnh nghĩa các cột (column-descr) của bảng hoặc các ràng buộc
(constraint) Chú ý rằng ñịnh nghĩa các cột, khai báo các ràng buộc ñược viết tách nhau bởi dấu phẩy và chúng nằm giữa hai ngoặc ñơn Thông thường các ràng buộc ñược khai báo sau khi ñã ñịnh nghĩa xong các cột
Ngoài lề về cách hiểu cú pháp hình thức:
Nếu cú pháp viết { column-descr | constraint }, thì chúng ta hiểu là một trong hai vế column-descr, constraint phải có mặt Khi viết [ exp ] thì exp là tùy chọn – nghĩa là có hoặc không có mặt, không bắt buộc Dấu ba chấm có nghĩa
là có thể lặp biểu thức trước ñó một số lần tùy ý
Mỗi một cột lại ñược ñịnh nghĩa như sau:
column-name data-type [column-constraints]
Giải thích:
Định nghĩa một cột bắt ñầu bằng tên cột (column-name), tiếp theo là kiểu dữ liệu (data-type) – bắt buộc – và có thể có các ràng buộc kèm theo cột ñó ([column-constraints]) – không bắt buộc
o Các ràng buộc (constraints)
Có hai loại ràng buộc: ràng buộc bảng và ràng buộc cột
Ràng buộc bảng:
• PRIMARY KEY chỉ ñịnh tổ hợp các cột sẽ ñược dùng làm khóa chính Chỉ có thể có nhiều nhất một khóa chính cho một bảng
PRIMARY KEY ( column-1 [, column-2] )
• UNIQUE chỉ ñịnh các cột khóa - khóa phụ (tổ hợp các cột có giá trị duy nhất ñối với mỗi bản ghi)
UNIQUE ( column-1 [, column-2] )
• FOREIGN KEY chỉ ñịnh các cột khóa ngoại
Trang 4FOREIGN KEY (column-list) REFERENCES references-specification
Trong ñó, mỗi references-specification có cú pháp hình thức như sau
table-2 [ ( referenced-columns ) ]
[ ON UPDATE { CASCADE | SET NULL | NO ACTION }]
[ ON DELETE { CASCADE | SET NULL | NO ACTION }]
Ngoài lề: nghĩa ñen của một số từ, giúp chúng ta dễ hiểu hơn về câu lệnh:
Reference: tham chiếu – chú ý người ta viết như là ñộng từ ngôi thứ 3 số ít
specification: Đặc tả
ON UPDATE: Khi cập nhật
ON DELETE: Khi xóa
CASCADE: Hiệu ứng liên hoàn (bậc thang)
SET NULL: Đặt giá trị về NULL
NO ACTION: Không làm gì cả
Chú ý phân biệt bảng tham chiếu (bảng ñược tạo) và bảng ñược tham chiếu (table-2) Bảng ñược tham chiếu phải tồn tại
column-list phải là khóa chính của table-2 nếu referenced-columns
không ñược chỉ ñịnh Nếu chỉ ñịnh thì referenced-columnsphải là các cột (của table-2) ñã ñược khai báo UNIQUE
Vấn ñề ñược ñặt ra khi cập nhật table-2 và các giá trị của cột tham chiếu
bị thay ñổi Đó chính là khai báo ON UPDATE và ON DELETE Chú ý nghĩa của các từ CASCADE, SET NULL, NO ACTION
• CHECK chỉ ñịnh một ñiều kiện cần ñược thỏa mãn (check condition) Phần
ñiều kiện ñược ñặt trong dấu ngoặc ñơn Các toán hạng tham gia ñiều kiện chỉ
có thể tham chiếu các cột trong cùng bảng Một số HQT CSDL cho phép lập các ñiều kiện từ các câu truy vấn con (sub-queries) – như vậy có thể tham chiếu các cột khác bảng Trong bài này chúng ta không xét trường hợp tham chiếu ñến các cột trong các bảng khác
CHECK ( check-condition )
Ràng buộc về cột
• NOT NULL chỉ ñịnh cột này không ñược phép nhận giá trị NULL Nếu không
có chỉ ñịnh này thì cột có thể chấp nhận giá trị NULL Thông thường các cột khóa chính (primary key) ñược khai báo NOT NULL
• PRIMARY KEY chỉ ñịnh cột này là cột khóa chính và do ñó chỉ có cột này làm khóa chính của bảng mà thôi Khi ñã khai báo cột này làm khóa chính, thì các cột khác không ñược khai báo PRIMARY KEY nữa
PK
Trang 5Chú ý: nếu có một cột nữa tham gia làm khóa chính, thì ta phải khai báo theo
kiểu PRIMARY KEY ( column-1 [, column-2] )như trong phần khai báo các ràng buộc bảng
• UNIQUE chỉ ñịnh cột có giá trị khóa hoặc NULL Điều này có nghĩa là nếu giá trị không phải là NULL thì các giá trị của cột phải phân biệt – không ñược trùng nhau
• REFERENCES chỉ ñịnh cột là khóa ngoại Chú ý nếu ta có khóa ngoại gồm nhiều cột thì ta phải khai báo rời như trong phần ràng buộc bảng
• CHECK chỉ ñịnh ràng buộc (xem phần ràng buộc bảng ở trên)
■ Kiểu dữ liệu
Ta có các kiểu dữ liệu sau:
• Ký tự (String) chuỗi ký tự với ñộ dài cố ñịnh hoặc biến thiên Bộ mã ký tự do HQT CSDL qui ñịnh, mặc ñịnh là ASCII
• Số (Numeric) – giá trị là số Giá trị số ñược chia làm 2 loại chính::
o Biểu diễn chính xác (fixed-point) Chỉ ñịnh số các chữ số phía trái và phía phải của dấu thập phân (dấu chấm) Tổng số các chữ số (trái và phải của dấu thập phân) gọi là ñộ chính xác Nếu không có chữ số sau dấu thập phân thì số ñó ñược gọi là số nguyên: integer
o Biểu diễn gần ñúng (floating-point) Biểu diễn số gần ñúng bằng dấu phẩy ñộng (floating)
Số trong SQL92 luôn luôn là số có dấu (âm, dương) Điểm này khác so với các ngôn ngữ lập trình
• Biểu diễn thời gian (Datetime) – Các giá trị ngày tháng năm, thời gian (Date,
Time, Timestamp) Các giá trị biểu diễn thời gian gồm:
o Date – giá trị ngày tháng năm
o Time – thời gian giờ, phút, giấy, phần thập phân của giây và múi giờ
(timezone) Múi giờ chỉnh theo giờ và phút
o Timestamp – Con dấu thời gian: tổ hợp ngày tháng năm, giờ phút giây và
phần thập phân của giây cộng với múi giờ
■ Khai báo kiểu dữ liệu
Ký tự (String)
CHAR [(length)]
CHARACTER [(length)]
VARCHAR (length) CHARACTER VARYING (length)
length chỉ ñộ dài: số các ký tự trong chuỗi ký tự (CHAR, CHARACTER); Nếu các ký tự không chiếm hết chỗ thì người ta bù vào
ñó bằng các ký tự trắng Độ dài mặc ñịnh là 1 Đối với kiểu dữ liệu có ñộ
Trang 6dài biến thiên (VARCHAR, CHARACTER VARYING), length là ñộ dài
tối ña Chuỗi ký tự có ñộ dài lớn hơn ñộ dài tối ña sẽ bị cắt từ phải sang
Số
SMALLINT INT
INTEGER
Kiểu dữ liệu số dựa vào ñộ chính xác nhị phân: 15 bit ñối với
SMALLINT và 31 bit ñối với INT, INTEGER
Ngoài lề: Tại sao không phải là 16 và 32 mà 15 và 31?
NUMERIC ( precision [, scale] ) DECIMAL ( precision [, scale] )
Đây là biểu diễn thập phân: precision là tổng số các chữ số, còn
scale là số các chữ số thập phân Dĩ nhiên scale không ñược vượt quá precision Số các chữ số tối ña cho phép phụ thuộc vào HQT CSDL - thường khá lớn
FLOAT [(precision)]
REAL DOUBLE
Dấu phẩy ñộng là biểu diễn nhị phân và ñạt ñược chữ số có nghĩa ở mức cao nhất Số các bit của biểu diễn này phụ thuộc vào HQT CSDL Chuẩn SQL qui ñịnh là số các bit dùng biểu diên DOUBLE phải cao hơn REAL
FLOAT cũng giống như REAL, chỉ khác là chúng ta có thể chỉ ñịnh số các chữ số nhị phân (bit)
Thời gian
DATE TIME [(scale)] [WITH TIME ZONE]
TIMESTAMP [(scale)] [WITH TIME ZONE]
TIME và TIMESTAMP cho phép chỉ ñịnh thêm số các chữ số thập phân của giây (scale) Giá trị mặc ñịnh của scale ñối với TIME là 0, và ñối với TIMESTAMP là 6 Tùy chọn WITH TIME ZONE chỉ ñịnh có chỉnh múi giờ; Nếu không, múi giờ ñược lấy ra từ hệ ñiều hành
■ Tính toàn vẹn thực thể (Entity Integrity)
Trong các phần trước, chúng ta biết rằng mô hình quan hệ ñòi hỏi mỗi một bảng phải
có khóa chính Tuy nhiên, SQL92 lại không ñòi hỏi như vậy – nghĩa là chúng ta có
Trang 7thể tạo bảng mà không cần khai báo khóa chính Mặc dầu vậy, khi tạo bảng gốc (base table) chúng ta nên khai báo khóa chính
Khóa chính là một loại ràng buộc về nội dung trong một bảng, và ñược gọi là tính toàn vẹn thực thể
1 Đối với một bản ghi bất kỳ, tập hợp giá trị ứng với khóa chính là duy nhất trong toàn bộ các bản ghi của bảng,
2 Các cột tham gia vào khóa chính không ñược chấp nhận giá trị NULL, và
3 Một bảng chỉ có duy nhất một khóa chính
Chú ý: SQL92 không yêu cầu ñiểm 2 nêu trên – nghĩa là các cột tham gia lập thành
khóa chính có thể chấp nhận giá trị NULL
Chúng ta có thể khai báo khóa chính theo hai cách khác nhau Trong trường hợp khóa chính chỉ gồm một cột, ta có thể khai báo luôn trong phần khai báo cột Ví dụ:
s_id VARCHAR(5) NOT NULL PRIMARY KEY
Một hình thức khai báo khác (trong trường hợp khóa chính gồm nhiều cột thì ñây là cách khai báo bắt buộc), ta có thể khai báo khóa chính như sau:
PRIMARY KEY ( column-1 [, column-2] )
column-1 và column-2 là tên các cột
VD:
PRIMARY KEY (s_id, p_id)
Thứ tự các cột trong cú pháp trên không quan trọng – ta có thể ñể bất cứ thứ tự nào
■ Tính toàn vẹn tham chiếu (Referential Integrity)
Khóa ngoại cho phép ta lập các mối quan hệ giữa các bảng trong một CSDL Khóa ngoại là tập hợp các cột tham chiếu ñến khóa chính trong các bảng khác Mỗi một tham chiếu phải trỏ ñến một bản ghi trong bảng tương ứng sao cho giá trị của khóa chính của bảng ñó phải bằng giá trị khóa ngoại của bảng này Người ta ñặt tên cho tính chất này là
tính toàn vẹn tham chiếu (Referential Integrity)
Tóm lại, ñiều kiện của toàn vẹn tham chiếu gồm:
1 Cột khóa ngoại phải ñược khai báo cùng kiểu và cùng ñộ dài với cột khóa chính trong bảng tham chiếu ñến
2 Giá trị của khóa ngoại trong một bản ghi bất kỳ phải trùng với giá trị của khóa chính trong bản ghi của bảng tham chiếu ñến
Có một ngoại lệ trong ñiểm 2 nêu trên, ñó là khi giá trị khóa ngoại bằng NULL Trường hợp này xảy ra khi khóa ngoại không trỏ ñến bất cứ một khóa chính nào trong bảng tham chiếu (SQL92 cho phép như vậy)
Trang 8Cũng giống như toàn vẹn thực thể, toàn vẹn tham chiếu là một hình thức ràng buộc nội dung Toàn vẹn thực thể chỉ ràng buộc nội dung trong cùng một bảng Toàn vẹn tham chiếu ràng buộc nội dung của nhiều bảng Nếu ta thay ñổi giá trị của khóa chính trong bảng tham chiếu mà khóa chính ñó ứng với khóa ngoại thì sẽ xảy ra phản ứng phụ:
phải cập nhật lại giá trị các khóa ngoại Nếu không, tính toàn vẹn tham chiếu sẽ bị phá
vỡ Để ñảm bảo tính toàn vẹn tham chiếu, có hai cách:
1 Bảng tham chiếu không cho phép sửa giá trị của khóa chính
2 Giá trị khóa ngoại cũng phải ñược thay ñổi theo
Trong SQL92, ñể HQT CSDL thực thi ñảm bảo tính toàn vẹn tham chiếu ta phải khai
báo, và khai báo này có tên là bẫy tham chiếu:
• NO ACTION Sửa ñổi trong bảng tham chiếu ñến sẽ không dẫn ñến sửa ñổi trong bảng có khóa ngoại Đây là trường hợp mặc ñịnh
• CASCADE Sửa ñổi trong bảng tham chiếu ñến sẽ dẫn ñến sửa ñổi trong bảng
có khóa ngoại
• SET NULL Các giá trị tương ứng của khóa ngoại sẽ ñặt về giá trị NULL khi sửa ñổi trong bảng tham chiếu ñến
Đối với trường hợp CASCADE, cập nhật giá trị và xóa bản ghi trong bảng tham chiếu
có thể dẫn ñến các thao tác khác nhau lên bảng có khóa ngoại:
• Đối với trường hợp cập nhật giá trị, khi sửa giá trị khóa chính trong bảng tham chiếu ñến, giá trị khóa ngoại của bảng tương ứng sẽ ñược sửa theo
• Đối với trường hợp xóa bản ghi, bản ghi tương ứng với khóa ngoại cũng sẽ bị xóa theo
Có hai cách khai báo khóa ngoại Khi khóa ngoại chỉ gồm một trường:
column-descr REFERENCES references-specification
Khi khóa ngoại gồm nhiều trường:
FOREIGN KEY (column-list) REFERENCES references-specification
Chú ý là thứ tự các trường trong danh sách column-list phải khớp với thứ tự các trường references-specification
Phần references-specification có dạng như sau:
table-2 [ ( referenced-columns ) ]
[ ON UPDATE { CASCADE | SET NULL | NO ACTION }]
[ ON DELETE { CASCADE | SET NULL | NO ACTION }]
Thứ tự ON UPDATE và ON DELETE có thể bất kỳ Phần này khai báo các thao tác cần thực thi khi tham chiếu khóa chính và khóa chính ñó bị thay ñổi (ON UPDATE) hoặc bị xóa (ON DELETE) Giá trị mặc ñịnh của cả hai tùy chọn là NO ACTION
Trang 9table-2 là bảng tham chiếu ñến Tùy chọn referenced-columns là danh sách các cột của khóa chính Nếu không chỉ ñịnh tùy chọn này, thì thứ tự sẽ theo thứ tự khai báo của khóa chính bảng table-2
Ngược lại với mô hình quan hệ, SQL92 cho phép tham chiếu tất cả các khóa – nghĩa là
có thể tham chiếu ñến các tập hợp trường khai báo UNIQUE chứ không riêng gì khóa chính Khi khai báo tham chiếu các trường không phải là khóa chính, bắt buộc phải chỉ ñịnh referenced-columns
Ví dụ, khai báo khóa ngoại cho bảng sp:
FOREIGN KEY (s_id)
REFERENCES supplier (s_id)
ON DELETE NO ACTION
ON UPDATE CASCADE
■ Các ví dụ về tạo bảng (tham khảo thêm bài 3)
CREATE TABLE supplier (
s_id CHAR(5) NOT NULL, sname CHAR(20) NOT NULL, status NUMERIC(5) NOT NULL, city CHAR(15) NOT NULL, PRIMARY KEY (s_id) );
CREATE TABLE part (
p_id CHAR(6) NOT NULL, pname CHAR(20) NOT NULL, color CHAR(6) NOT NULL, weight NUMERIC(5) NOT NULL, city CHAR(15) NOT NULL, PRIMARY KEY (p_id) );
CREATE TABLE sp(
s_id CHAR(5) NOT NULL, p_id CHAR(6) NOT NULL, qty NUMERIC(9) NOT NULL, PRIMARY KEY (s_id, p_id), FOREIGN KEY (s_id) REFERENCES supplier
ON DELETE SET NULL
ON UPDATE CASCADE, FOREIGN KEY (p_id) REFERENCES part (p_id)
ON DELETE SET NULL
ON UPDATE CASCADE, CHECK (qty > 0 AND qty < 5001) );
■ Tạo VIEW (CREATE VIEW)
View thực chất là một câu lệnh SQL ñược lưu trong catalog của hệ thống
CREATE VIEW view-name [ ( column-list ) ] AS query
[ WITH [CASCADED|LOCAL] CHECK OPTION ]
Trang 10view-name tên của View, và có thể có danh sách các cột thông qua chỉ ñịnh
column-list query là câu lệnh SELECT (không ñược có mệnh ñề ORDER BY) Tùy chọn WITH CHECK OPTION là ràng buộc nếu ñó là một view có thể cập nhật
column-list cần có số cột tương thích với query Nếu không chỉ ñịnh column-list , tất cả các trường trong query phải ñược ñặt tên và các tên không ñược trùng nhau
Tùy chọn WITH CHECK OPTION sẽ tác ñộng lên các câu lệnh INSERT và UPDATE
ñối với view Nếu có chỉ ñịnh WITH CHECK OPTION, mệnh ñề WHERE của query
cần ñược tôn trọng khi chèn thêm bản ghi mới hoặc thay ñổi các bản ghi của View View có thể có nhiều thang bậc, có nghĩa là View A ñược ñịnh nghĩa trên View B, View B lại ñược ñịnh nghĩa trên View C,
Nếu chỉ ñịnh CASCADED, các ñiều kiện WITH CHECK OPTION sẽ phải ñược tôn trọng ở tất cả các bậc của View Ngược lại, tùy chọn LOCAL chỉ yêu cầu tôn trọng ở View ñang ñược ñịnh nghĩa Mặc ñịnh là LOCAL
Ví dụ
CREATE VIEW supplied_parts AS
SELECT *
FROM part
WHERE p_id IN (SELECT p_id FROM sp)
WITH CHECK OPTION;
■ Xóa bảng (DROP TABLE)
Câu lệnh DROP TABLE xóa bảng ñã tạo và xóa các phần thông tin liên quan trong catalog của hệ thống Cú pháp của nó như sau:
DROP TABLE table-name {CASCADE|RESTRICT}
table-name là tên của một bảng ñang tồn tại Một bảng có hai dạng phụ thuộc:
• View ñịnh nghĩa dựa trên bảng này
• Một bảng khác tham chiếu ñến bảng này thông qua khóa ngoại
RESTRICT chỉ ñịnh rằng sẽ không xóa bảng nếu có sự phụ thuộc nêu trên Hệ thống sẽ báo lỗi nếu ta ñưa ra câu lệnh xóa bảng trong trường hợp ñó
CASCADE chỉ ñịnh rằng các phụ thuộc sẽ bị loại bỏ trước khi xóa bảng với các trường hợp sau:
• Các View phụ thuộc sẽ bị xóa và sẽ có hiệu ứng domino nếu View này lại dựa vào View kia
• Đối với bảng thì các ràng buộc sẽ bị xóa nhưng bảng không bị xóa