cơ sở dữ liệu mã nguồn mở - mysql
DESCRIPTION
Cơ sở dữ liệu mã nguồn mở - MySQL. Nội dung trình bày. I. Làm quen với MySQL II. MySQL căn bản III. Tối ưu hóa MySQL IV. Quản trị CSDL MySQL IV. Một số tính năng mở rộng của MySQL. I. Làm quen với MySQL. I.1. MySQL là gì? I.2. Cài đặt MySQL I.3. CSDL đầu tiên với MySQL. - PowerPoint PPT PresentationTRANSCRIPT
Cơ sở dữ liệu mã nguồn Cơ sở dữ liệu mã nguồn mở - MySQLmở - MySQL
Nội dung trình bàyNội dung trình bày
I. Làm quen với MySQLII. MySQL căn bảnIII. Tối ưu hóa MySQLIV. Quản trị CSDL MySQLIV. Một số tính năng mở rộng của
MySQL
I. Làm quen với MySQLI. Làm quen với MySQL
I.1. MySQL là gì?I.2. Cài đặt MySQLI.3. CSDL đầu tiên với MySQL
I.1. MySQL là gì?I.1. MySQL là gì?
MySQL (My Ess Que Ell) là hệ quản trị cơ sở dữ liệu
MySQL là hệ quản trị cơ sở dữ liệu quan hệ
MySQL là PMNM◦Bạn có thể download phần mềm và mã
nguồn của MySQL qua internet, có thể sửa đổi MySQL theo nhu cầu của mình. MySQL tuân theo giấy phép GNU GPL(http://www.fsf.org/licenses/)
◦Ngoài phiên bản sử dụng GPL, bạn có thể mua bản thương mại của MySQL (https://order.mysql.com/)
I.1. MySQL là gì?I.1. MySQL là gì?
Vì sao sử dụng CSDL MySQL?◦ MySQL là cơ sở dữ liệu tốc độ cao, ổn định và dễ sử dụng
Friendster, more than 85 million dynamic page views per day, able to support more than 1.5 billion MySQL queries per day
Wikipedia, more than 200 million queries and 1.2 million updates per day with peak loads of 11,000 queries per second
◦ MySQL có tính khả chuyển, hoạt động trên nhiều hệ điều hành (Unix, FreeBSD, NetBSD, Linux, Novell NetWare, SGI Irix, Solaris, SunOS, Windows)
◦ Qua nhiều năm phát triển, hiện tại MySQL cung cấp một hệ thống lớn các hàm tiện ích rất mạnh
◦ Với tốc độ và tính bảo mật cao, MySQL rất thích hợp cho các ứng dụng có truy cập CSDL trên internet
Bạn có thể sử dụng các CSDL MySQL free trên interrnet◦ http://www.db4free.net/◦ http://www.freesql.org/
I.1. Cài đặt MySQL (trên I.1. Cài đặt MySQL (trên Windows)Windows)I.1.1. Yêu cầu tối thiểuI.1.2. Cài đặt
I.1.1. Yêu cầu tối thiểuI.1.1. Yêu cầu tối thiểu
Windows 9x, NT, Me, 2000, XP. Các hệ dòng NT cho phép chạy MySQL dưới dạng các service.
Phiên bản cài đặt MySQL download từ địa chỉ http://www.mysql.com/downloads
Khoảng trống >= 200MB (khoảng trống còn lại phụ thuộc vào nhu cầu đối với CSDL của bạn)
Nếu muốn kết nối với MySQL qua ODBC, bạn phải cài đặt MyODBC (http://www.mysql.com/downloads/api-myodbc.html. )
Với CSDL có các bảng (table) có kích thước lớn hơn 4GB, bạn phải cài đặt trên ổ đĩa NTFS hoặc mới hơn
I.1.2. Cài đặt MySQL trên I.1.2. Cài đặt MySQL trên WindowsWindowsNếu sử dụng Windows NT, 2000 hay XP,
phải có quyền administratorNếu nâng cấp, bạn phải dừng MySQL theo
các bước sau>net stop mysql
>mysqld –remove
>mysqladmin –u root shutdown
Bung file nén download đượcChạy setup.exe
I.1.3. CSDL đầu tiên với I.1.3. CSDL đầu tiên với MySQLMySQLI.1.3.1. Connect & Disconnect
serverI.1.3.2. Nhập Query trên consoleI.1.3.3. Tạo và sử dụng Cơ sở dữ
liệuI.1.3.4. Tạo bảng, import dữ liệu
vào bảngI.1.3.5. Xem thông tin từ bảng
I.1.3.1. Connect & Disconnect I.1.3.1. Connect & Disconnect serverserver
Để kết nối đến máy chủ, cần cung cấp username & password. Nếu kết nối máy chủ từ xa, phải xác định hostname.> mysql -h host -u user –pEnter password: ********
> mysql -h host -u user –p
Enter password: ********
Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 25338 to server version: 4.0.14-log Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql>
I.1.3.2. Nhập Query trên I.1.3.2. Nhập Query trên consoleconsole
mysql> SELECT VERSION(), CURRENT_DATE;+--------------+--------------+| VERSION() | CURRENT_DATE |+--------------+--------------+| 3.22.20a-log | 1999-03-19 |+--------------+--------------+1 row in set (0.01 sec)mysql>
mysql> SELECT VERSION(), CURRENT_DATE;mysql> select version(), current_date;mysql> SeLeCt vErSiOn(), current_DATE;
mysql> SELECT SIN(PI()/4), (4+1)*5;+-------------+---------+| SIN(PI()/4) | (4+1)*5 |+-------------+---------+| 0.707107 | 25 |+-------------+---------+
I.1.3.2. Nhập Query trên Console I.1.3.2. Nhập Query trên Console (2)(2)
mysql> SELECT VERSION(); SELECT NOW();+--------------+| VERSION() |+--------------+| 3.22.20a-log |+--------------+
+---------------------+| NOW() |+---------------------+| 1999-03-19 00:15:33 |+---------------------+
mysql> SELECT -> USER() -> , -> CURRENT_DATE;+--------------------+--------------+| USER() | CURRENT_DATE |+--------------------+--------------+| joesmith@localhost | 1999-03-18 |+--------------------+--------------+
I.1.3.2. Nhập Query trên Console (3)I.1.3.2. Nhập Query trên Console (3)
Để dừng lệnh đang nhập, dùng lệnh \cmysql> SELECT -> USER() -> \cmysql>Chú ý đến ý nghĩa của dấu nhắc của MySQL
Dấu nhắc Ý nghĩa
mysql> Sẵn sàng để nhập lệnh mới
-> Đang đợi dòng tiếp theo (khi nhập lệnh nhiều dòng)
'> Đang đợi dòng tiếp theo, người dùng đang nhập một string bắt đầu bởi dấu nháy đơn
"> Đang đợi dòng tiếp theo, người dùng đang nhập một string bắt đầu bởi dấu nháy kép
`> Đang đợi dòng tiếp theo, người dùng đang nhập một ký hiệu bắt đầu bởi dấu nháy ngược `
I.1.3.2. Nhập query trên I.1.3.2. Nhập query trên console (4)console (4)Làm việc theo lô (batch)
> mysql -e "source batch-file"
> mysql -h host -u user -p < batch-file
Enter password: ********
> mysql < batch-file | more
> mysql < batch-file > mysql.out
I.1.3.2. Nhập Query trên Console I.1.3.2. Nhập Query trên Console (4)(4)
Làm việc theo lô (batch)◦ Một query bình thường hiển thị kết quả ở chế độ interactive
+---------+| species |+---------+| bird || cat || dog || hamster || snake |+---------+
◦ Ở chế độ batch, kết quả hiển thị như sauspeciesbirdcatdoghamstersnake
◦ Để hiển thị dữ liệu kiểu interactive ở chế độ batch, sử dụng lệnh mysql –t
◦ Để hiển thị các lệnh được gọi, dùng lệnh mysql -vvv
I.1.3.2. Nhập Query trên Console I.1.3.2. Nhập Query trên Console (4)(4)Chú ý: Câu lệnh MySQL phải kết thúc bởi dấu ;mysql> SELECT USER() ->
mysql> SELECT USER() -> ;+--------------------+| USER() |+--------------------+| joesmith@localhost |+--------------------+
I.1.3.3. Tạo và sử dụng cơ sở dữ I.1.3.3. Tạo và sử dụng cơ sở dữ liệuliệu
mysql> show databases;+-----------+| Database |+-----------+| guestbook || mysql || quang || test |+-----------+4 rows in set (0.00 sec)
mysql> CREATE DATABASE dhxd;
mysql> USE dhxdDatabase changed
> mysql -h host -u user -p dhxdEnter password: ********
I.1.3.4. Tạo bảng, import dữ liệu I.1.3.4. Tạo bảng, import dữ liệu vào bảngvào bảng
mysql> SHOW TABLES;Empty set (0.00 sec)
mysql> create table sv(id int auto_increment primary key, hodem varchar(30), -> ten varchar(10), gioitinh char(1), ngaysinh date);Query OK, 0 rows affected (0.03 sec)
mysql> show tables;+----------------+| Tables_in_dhxd |+----------------+| sv |+----------------+1 row in set (0.00 sec)
I.1.3.4. Tạo bảng, import dữ liệu vào I.1.3.4. Tạo bảng, import dữ liệu vào bảng (2)bảng (2)
mysql> describe sv;+----------+-------------+------+-----+---------+----------------+| Field | Type | Null | Key | Default | Extra |+----------+-------------+------+-----+---------+----------------+| id | int(11) | | PRI | NULL | auto_increment || hodem | varchar(30) | YES | | NULL | || ten | varchar(10) | YES | | NULL | || gioitinh | char(1) | YES | | NULL | || ngaysinh | date | YES | | NULL | |+----------+-------------+------+-----+---------+----------------+5 rows in set (0.02 sec)
Nội dung file "dhxd.txt" (chú ý các trường cách nhau bởi dấu tab)1 Nguyen Phu Quang M 1979-04-043 Tran Van On M 1919-04-064 Nguyen Viet Xuan F 1029-03-02
I.1.3.4. Tạo bảng, import dữ liệu vào I.1.3.4. Tạo bảng, import dữ liệu vào bảng (3)bảng (3)mysql> load data local infile "dhxd.txt" into table
sv;Query OK, 3 rows affected (0.00 sec)Records: 3 Deleted: 0 Skipped: 0 Warnings: 0
mysql> select * from sv;+----+-------------+-------+----------+------------+| id | hodem | ten | gioitinh | ngaysinh |+----+-------------+-------+----------+------------+| 1 | Nguyen Phu | Quang | M | 1979-04-04 || 3 | Tran Van | On | M | 1919-04-06 || 4 | Nguyen Viet | Xuan | F | 1029-03-02 |+----+-------------+-------+----------+------------+3 rows in set (0.00 sec)
I.1.3.5. Xem thông tin từ I.1.3.5. Xem thông tin từ bảngbảng
mysql> select * from sv;+----+-------------+-------+----------+------------+| id | hodem | ten | gioitinh | ngaysinh |+----+-------------+-------+----------+------------+| 1 | Nguyen Phu | Quang | M | 1979-04-04 || 3 | Tran Van | On | M | 1919-04-06 || 4 | Nguyen Viet | Xuan | F | 1029-03-02 |+----+-------------+-------+----------+------------+3 rows in set (0.00 sec)mysql> select hodem, ten from sv;+-------------+-------+| hodem | ten |+-------------+-------+| Nguyen Phu | Quang || Tran Van | On || Nguyen Viet | Xuan |+-------------+-------+3 rows in set (0.00 sec)
I.1.3.5. Xem thông tin từ I.1.3.5. Xem thông tin từ bảng (2)bảng (2)
mysql> select concat(hodem, " ", ten) from sv;+-------------------------+| concat(hodem, " ", ten) |+-------------------------+| Nguyen Phu Quang || Tran Van On || Nguyen Viet Xuan |+-------------------------+3 rows in set (0.44 sec)
mysql> select concat(hodem, " ", ten) from sv where ten="quang";+-------------------------+| concat(hodem, " ", ten) |+-------------------------+| Nguyen Phu Quang |+-------------------------+1 row in set (0.35 sec)
II. MySQL căn bảnII. MySQL căn bảnII.1. Cấu trúc ngôn ngữII.2. Các kiểu trườngII.3. Các hàm sử dụng với câu lệnh SELECT và mệnh đề
WHEREII.4. Các câu lệnh thao tác trên dữ liệu (SELECT, INSERT,
UPDATE, DELETE)II.5. Các câu lệnh thao tác trên bảng CREATE, DROP,
ALTERII.6. Làm việc với giao dịch (transaction) & các lệnh khóa
(Locking command)II.7. Tìm kiếm văn bản (Full-text search)II.8. Các dạng bảng của MySQL
II.1. Cấu trúc ngôn ngữII.1. Cấu trúc ngôn ngữ
II.1.1. String & sốII.1.2. Tên CSDL, bảng, chỉ số, cộtII.1.3. Phân biệt chữ hoa, chữ
thườngII.1.4. Biến người dùngII.1.5. Biến hệ thốngII.1.6. Chú thích
II.1.1. String & SốII.1.1. String & Số
II.1.1.1. StringII.1.1.2. SốII.1.1.3. Giá trị NULL
II.1.1.1. StringII.1.1.1. String
String trong MySQL có thể được ký hiệu bằng cả dấu nháy đơn và dấu nháy kép
Trong String, để viết các ký tự đặc biệt, ta sử dụng dấu chéo ngược (backslash)
Do đó, khi làm việc với đường dẫn, tốt nhất là dùng ký tự /
\0 Ký tự mã ASCII 0 (NULL)
\' Dấu nháy đơn
\" Dấu nháy kép
\b Ký tự xóa ngược (backspace)
\n Ký tự xuống dòng (newline)
\r Ký tự về đầu dòng (carriage return)
\t Ký tự tab
\\ Ký tự chéo ngược (backslash)
\\% Ký tự phần trăm (%)
\_ Ký tự gạch dưới (_)
II.1.1.1. String (2)II.1.1.1. String (2)mysql> SELECT 'hello', '"hello"', '""hello""', 'hel''lo', '\'hello';+-------+---------+-----------+--------+--------+| hello | "hello" | ""hello"" | hel'lo | 'hello |+-------+---------+-----------+--------+--------+
mysql> SELECT "hello", "'hello'", "''hello''", "hel""lo", "\"hello";+-------+---------+-----------+--------+--------+| hello | 'hello' | ''hello'' | hel"lo | "hello |+-------+---------+-----------+--------+--------+
mysql> SELECT "This\nIs\nFour\nlines";+--------------------+| ThisIsFourlines |+--------------------+
II.1.1.2. SốII.1.1.2. Số
Số ký hiệu như những ngôn ngữ khác12210-32294.42-32032.6809e+10148.00
Từ version 4.1.0: TRUE (1), FALSE(0) Số Hexa
mysql> SELECT x'4D7953514C'; -> MySQLmysql> SELECT 0xa+0; -> 10mysql> SELECT 0x5061756c; -> Paul
II.1.1.3. Giá trị NULLII.1.1.3. Giá trị NULLGiá trị NULL có nghĩa là không có
dữ liệu (không giống với giá trị 0 của kiểu số, xâu rỗng của kiểu String)
Giá trị NULL khi import hoặc export ra file text sử dụng ký hiệu (\N)
II.1.1.2. Tên CSDL, bảng, chỉ số, cộtII.1.1.2. Tên CSDL, bảng, chỉ số, cột
Độ dài tối đa Các ký tự cho phép
CSDL 64 Tất cả các ký tự cho phép khi đặt tên thư mục (trừ '/', '\', '.')
Bảng 64 Tất cả các ký tự cho phép khi đặt tên file, trừ '/', '.'
Cột (trường) 64 Tất cả các ký tự
Bí danh (alias) 255 Tất cả các ký tự
Các tên CSDL, bảng, cột... nếu trùng với từ khóa thì phải đặt trong dấu nháy ngược [`]
mysql> SELECT * FROM `select` WHERE `select`.id > 100;
II.1.3. Phân biệt chữ hoa, chữ II.1.3. Phân biệt chữ hoa, chữ thườngthườngVới MySQL, cơ sở dữ liệu và bảng
tương ứng với thư mục và file trên máy tính. Do vậy, sự phân biệt chữ hoa, chữ thường (case-sensitive) phụ thuộc vào hệ điều hành◦Windows: Không phân biệt chữ hoa chữ
thường◦Linux, Unix: Có phân biệt chữ hoa, chữ
thườngCác bí danh (alias) có phân biệt chữ
hoa chữ thường
II.1.4. BiếnII.1.4. BiếnTên biến phân biệt chữ hoa chữ thường. Biến
không cần khởi tạo (biến chưa khởi tạo có giá trị NULL)
Để gán giá trị cho biến, sử dụng cú phápSET @variable= { integer expression | real expression | string expression }
[,@variable= ...] .mysql> SET @t1=0, @t2=0, @t3=0;mysql> SELECT @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;+----------------------+------+------+------+| @t1:=(@t2:=1)+@t3:=4 | @t1 | @t2 | @t3 |+----------------------+------+------+------+| 5 | 5 | 1 | 4 |+----------------------+------+------+------+
II.1.5. Biến hệ thốngII.1.5. Biến hệ thốngmysql> SELECT (@aa:=id) AS a, (@aa+3) AS b FROM table_name HAVING b=5;
SET SESSION sort_buffer_size=value;SET @@session.sort_buffer_size=value;SET sort_buffer_size=value;
SELECT @@global.sort_buffer_size;SHOW GLOBAL VARIABLES like 'sort_buffer_size';
SELECT @@session.sort_buffer_size;SHOW SESSION VARIABLES like 'sort_buffer_size';
II.1.6. Chú thíchII.1.6. Chú thíchmysql> SELECT 1+1; # This comment continues to the end
of linemysql> SELECT 1+1; -- This comment continues to the end
of linemysql> SELECT 1 /* this is an in-line comment */ + 1;mysql> SELECT 1+/*this is amultiple-line comment*/1;
II.2. Kiểu trường (cột)II.2. Kiểu trường (cột)
II.2.1. Các kiểu số◦NUMERIC, DECIMAL, INTEGER,
SMALLINT◦FLOAT, REAL, DOUBLE
II.2.2. Các kiểu ngày thángII.2.3. Các kiểu chuỗi (string)II.2.4. Kích thước của các kiểu dữ
liệu
II.2.1. Các kiểu sốII.2.1. Các kiểu sốCác kiểu số sử dụng trong MySQL
◦NUMERIC, DECIMAL, INTEGER, SMALLINT
◦FLOAT, REAL, DOUBLECác kiểu số riêng cho MySQL
◦TINYINT, MEDIUMINT, BIGINTmysql> create table pet(id decimal(5,2));
II.2.2. Kiểu ngày thángII.2.2. Kiểu ngày tháng
Các kiểu ngày tháng trong MySQL gồm có◦ DATETIME, DATE, TIMESTAMP, TIME, YEAR
Chú ý: MySQL không kiểm tra tính hợp lệ của ngày tháng, ví dụ 1999-11-31 cũng được MySQL chấp nhận (MySQL chỉ kiểm tra điều kiện tháng từ 0-12, ngày từ 0-31 – điều này giúp MySQL có được tốc độ cao)
MySQL cho phép bạn lưu ngày thàng với ngày =0 hoặc tháng =0, điều này rất hữu ích trong trường hợp bạn không biết chính xác ngày tháng (ví dụ 1999-00-00)
Kiểu trường "Zero" value
DATETIME '0000-00-00 00:00:00'
DATE '0000-00-00'
TIMESTAMP 00000000000000 (length depends on display size)
TIME '00:00:00'
YEAR 0000
II.2.3. Các kiểu chuỗiII.2.3. Các kiểu chuỗi
II.2.3.1. Kiểu 'CHAR' và 'VARCHAR'II.2.3.2. Kiểu 'BLOB' và 'TEXT'II.2.3.3. Kiểu 'ENUM'II.2.3.4. Kiểu 'SET'
II.2.3.1. Kiểu 'CHAR' và 'VARCHAR'II.2.3.1. Kiểu 'CHAR' và 'VARCHAR'
Kiểu CHAR và VARCHAR là tương tự nhau, nhưng khác nhau khi lưu trữ:◦ Các trường kiểu CHAR có kích thước cố định khi bạn tạo bảng
(chiều dài của chuỗi kiểu CHAR từ 1-255)◦ Các trường kiểu VARCHAR có kích thước thay đổi tùy thuộc vào
dữ liệu vào (chiều dài từ 1-255)
Giá trị CHAR(4) Kích thước cần thiết
VARCHAR(4) Kích thước cần thiết
'' ' ' 4 byte ' ' 1 byte
'ab' 'ab ' 4 byte 'ab' 3 byte
'abcd' 'abcd' 4 byte 'abcd' 5 byte
'abcdefgh' 'abcd' 4 byte 'abcd' 5 byte
II.2.3.2. Kiểu 'BLOB' và II.2.3.2. Kiểu 'BLOB' và 'TEXT''TEXT'
Kiểu BLOB dùng để lưu trữ các dữ liệu có kích thước lớn. BLOB gồm 4 loại◦ TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB
Kiểu TEXT gồm 4 kiểu◦ TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT
Hai kiểu BLOB và TEXT chỉ có sự khác nhau duy nhất là BLOB có phân biệt sự khác nhau giữa chữ hoa và chữ thường còn kiểu TEXT thì không phân biệt chữ hoa và chữ thường
TEXT có thể coi là VARCHAR nhưng có kích thước lớn Nếu bạn muốn sử dụng kiểu BLOB, TEXT cho câu lệnh GROUP BY, phải
chuyển chúng về cùng một chiều dàimysql> SELECT comment FROM tbl_name,SUBSTRING(comment,20) AS substr -> ORDER BY substr;
Nếu không sử dụng cú pháp trên chỉ có một đoạn có độ dài max_sort_length của văn bản là được sắp xếp (giá trị mặc định của max_sort_length là 1024 và có thể thay đổi bằng tùy chọn –O của mysql)
Kích thước của trường kiểu TEXT và BLOB là thay đổi tùy theo kích thước của dữ liệu nhập vào (giống VARCHAR)
II.2.3.3. Kiểu 'ENUM'II.2.3.3. Kiểu 'ENUM'
Kiểu ENUM là kiểu string mà giá trị được lựa chọn từ 1 trong các giá trị được liệt kê lúc tạo bảngmysql>CREATE TABLE temp(gt enum("nam","nu");mysql> insert into temp values("nam"),("nu"),("");mysql> select * from temp;+------+| gt |+------+| nam || nu || |+------+mysql> insert into temp values(NULL), (0), (1), (2);mysql> select * from temp;+------+| gt |+------+| nam || nu || || NULL || || nam || nu |+------+
II.2.3.3. Kiểu 'ENUM' (2)II.2.3.3. Kiểu 'ENUM' (2)
mysql> select concat("'", gt, "'") from temp;+----------------------+| concat("'", gt, "'") |+----------------------+| 'nam' || 'nu' || '' || NULL || '' || 'nam' || 'nu' |+----------------------+mysql> select concat("'", gt, "'") from temp where gt=0;+----------------------+| concat("'", gt, "'") |+----------------------+| '' || '' |+----------------------+mysql> select concat("'", gt, "'") from temp where gt=1;+----------------------+| concat("'", gt, "'") |+----------------------+| 'nam' || 'nam' |+----------------------+
II.2.3.4. Kiểu 'SET'II.2.3.4. Kiểu 'SET'
mysql> create table temp (s set("one", "two", "three"));mysql> insert into temp values("one"),("two"),("two,three");mysql> select * from temp;+-----------+| s |+-----------+| one || two || two,three |+-----------+mysql> select s+0 from temp;+------+| s+0 |+------+| 1 || 2 || 6 |+------+
II.2.3.4. Kiểu 'SET' (2)II.2.3.4. Kiểu 'SET' (2)
mysql> delete from temp;mysql> insert into temp values("one"),("two"),("three"),("one,two"),("one,three"),("two,three"),("one,two,three");mysql> select * from temp;+---------------+| s |+---------------+| one || two || three || one,two || one,three || two,three || one,two,three |+---------------+mysql> select s+0 from temp;+------+| s+0 |+------+| 1 || 2 || 4 || 3 || 5 || 6 || 7 |+------+
II.2.3.4. Kiểu 'SET' (3)II.2.3.4. Kiểu 'SET' (3)
mysql> select * from temp where s like "%one%";+---------------+| s |+---------------+| one || one,two || one,three || one,two,three |+---------------+mysql> select * from temp where find_in_set("one", s);+---------------+| s |+---------------+| one || one,two || one,three || one,two,three |+---------------+
II.2.4. Kích thước của các kiểu dữ liệuII.2.4. Kích thước của các kiểu dữ liệu
Kiểu Kích thước (bytes)
TINYINT 1
SMALLINT 2
MEDIUMINT 3
INT 4
BIGINT 5
FLOAT 4
DOUBLE 8
REAL 8
DECIMAL(M,D) M+2 (D>0), M+1 (D=0), D+2 (M<D)
NUMERIC(M,D) M+2 (D>0), M+1 (D=0), D+2 (M<D)
II.2.4. Kích thước của các kiểu dữ liệu II.2.4. Kích thước của các kiểu dữ liệu (2)(2)
Kiểu Kích thước (bytes)
DATE 3
DATETIME 8
TIMESTAMP 4
TIME 3
YEAR 1
II.2.4. Kích thước của các kiểu dữ liệu II.2.4. Kích thước của các kiểu dữ liệu (3)(3)
Kiểu Kích thước (bytes)
CHAR(M) M (1-255)
VARCHAR(M) L+1 (L<=M, M: 1-255)
TINYBLOB, TINYTEXT L+1 (L<2^8)
BLOB, TEXT L+2 (L<2^16)
MEDIUMBLOB, MEDIUMTEXT L+3(L<2^24)
LONGBLOB, LONGTEXT L+4(L<2^32)
ENUM ('value1', 'value2',...) 1-2 (tùy thuộc vào số lượng giá trị, nhiều nhất là 2^16-1 giá trị)
SET ('value1', 'value2',...) 1,2,4,8 (tùy thuộc vào số lượng giá trị, nhiều nhất là 64)
II.3. Các hàm sử dụng với câu lệnh II.3. Các hàm sử dụng với câu lệnh SELECT và mệnh đề WHERESELECT và mệnh đề WHERE
II.3.1. Các toán tử và hàm điều kiện
II.3.2. Các hàm trên StringII.3.3. Các hàm trên kiểu sốII.3.4. Các hàm trên ngày thángII.3.5. Hàm đổi kiểuII.3.7. Các hàm dùng với mệnh đề
GROUP BY
II.3.1. Các toán tử và hàm điều kiệnII.3.1. Các toán tử và hàm điều kiện
II.3.1.1. Các toán tử so sánhII.3.1.2. Các toán tử logicII.3.1.3. Các hàm điều kiện
II.3.1.1. Các toán tử so II.3.1.1. Các toán tử so sánhsánh
Các phép toán so sánh trả về các giá trị TRUE(1), FALSE(0) hoặc NULL.
Các phép toán này làm việc với cả số và stringNguyên tắc so sánh của MySQL
◦ Trả về NULL nếu 1 trong 2 toán hạng là NULL (trừ phép toán <=>)
◦ Nếu cả 2 toán hạng là string, sử dụng phép so sánh string (phép so sánh string không phân biệt chữ hoa và chữ thường)
◦ Nếu cả 2 toán hạng là số nguyên, sử dụng phép so sánh số nguyên
◦ Nếu 1 trong 2 toán hạng là kiểu DATETIME hoặc TIMESTAMP, toán hạng còn lại là 1 hằng số, thì chuyển kiểu của hằng số trước khi so sánh
◦ Trừ các trường hợp trên, các toán hạng sẽ được so sánh bằng phép so sánh số thực
II.3.1.1. Các toán tử so II.3.1.1. Các toán tử so sánh (2)sánh (2)
Các toán tử so sánh (=,<>,>... trừ phép LIKE) của string sẽ bỏ qua các khoảng trắng (ký tự cách, tab, xuống dòng)mysql> select 'a'='A \n\t';+---------------+| 'a'='A \n\t' |+---------------+| 1 |+---------------+mysql> SELECT 1 > '6x'; -> 0mysql> SELECT 7 > '6x'; -> 1mysql> SELECT 0 > 'x6'; -> 0mysql> SELECT 0 = 'x6'; -> 1
II.3.1.1. Các toán tử so II.3.1.1. Các toán tử so sánh (3)sánh (3)
=mysql> SELECT 1 = 0; -> 0mysql> SELECT '0' = 0; -> 1mysql> SELECT '0.0' = 0; -> 1mysql> SELECT '0.01' = 0; -> 0mysql> SELECT '.01' = 0.01; -> 1
<> !=mysql> SELECT '.01' <> '0.01'; -> 1mysql> SELECT .01 <> '0.01'; -> 0mysql> SELECT 'zapp' <> 'zappp'; -> 1
II.3.1.1. Các toán tử so II.3.1.1. Các toán tử so sánh (4)sánh (4)
<= mysql> SELECT 0.1 <= 2; -> 1< mysql> SELECT 2 < 2; -> 0>= mysql> SELECT 2 >= 2; -> 1> mysql> SELECT 2 > 2; -> 0<=> mysql> SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL; -> 1 1 0
II.3.1.1. Các toán tử so sánh II.3.1.1. Các toán tử so sánh (5)(5)
IS NULL IS NOT NULL
◦ Kiếm tra 1 giá trị là NULL hay không:mysql> SELECT 1 IS NULL, 0 IS NULL, NULL IS NULL;-> 0 0 1mysql> SELECT 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;
-> 1 1 0 Một số chú ý với toán tử IS NULL
◦ Để lấy dòng cuối cùng của bảngSELECT * FROM tbl_name WHERE auto_col IS NULL;
◦ Để bỏ chế độ này, đặt SQL_AUTO_IS_NULL=0◦ Với NOT NULL DATE và DATETIME bạn có thể tìm giá trị 0000-
00-00 bằng cú pháp:SELECT * FROM tbl_name WHERE date_column IS NULL;
◦ Điều này để phù hợp với ODBC (không hỗ trợ ngày 0000-00-00)
II.3.1.1. Các toán tử so sánh II.3.1.1. Các toán tử so sánh (6)(6)
expr BETWEEN min AND maxmysql> SELECT 1 BETWEEN 2 AND 3; -> 0mysql> SELECT 'b' BETWEEN 'a' AND 'c'; -> 1mysql> SELECT 2 BETWEEN 2 AND '3'; -> 1mysql> SELECT 2 BETWEEN 2 AND 'x-3'; -> 0
expr NOT BETWEEN min AND maxmysql> SELECT 2 IN (0,3,5,'wefwf'); -> 0
expr IN (value,...)mysql> SELECT 'wefwf' IN (0,3,5,'wefwf'); -> 1
II.3.1.1. Các toán tử so sánh II.3.1.1. Các toán tử so sánh (7)(7)
ISNULL(expr)mysql> SELECT ISNULL(1+1); -> 0mysql> SELECT ISNULL(1/0); -> 1
COALESCE(list): Trả về giá trị đầu tiên != NULL trong danh sáchmysql> SELECT COALESCE(NULL,1); -> 1mysql> SELECT COALESCE(NULL,NULL,NULL); -> NULL
INTERVAL(N,N1,N2,N3,...): Trả về 0 nếu N<N1, 1 nếu N>=N1 && N<N2...mysql> SELECT INTERVAL(23, 1, 15, 17, 30, 44, 200); -> 3mysql> SELECT INTERVAL(10, 1, 10, 100, 1000); -> 2mysql> SELECT INTERVAL(22, 23, 30, 44, 200); -> 0
II.3.1.2. Các toán tử logicII.3.1.2. Các toán tử logicNOT
!
mysql> SELECT NOT 10;
-> 0
mysql> SELECT NOT 0;
-> 1
mysql> SELECT NOT NULL;
-> NULL
mysql> SELECT ! (1+1);
-> 0
mysql> SELECT ! 1+1;
-> 1
AND
&&
mysql> SELECT 1 && 1;
-> 1
mysql> SELECT 1 && 0;
-> 0
mysql> SELECT 1 && NULL;
-> NULL
mysql> SELECT 0 && NULL;
-> 0
mysql> SELECT NULL && 0;
-> 0
OR
||
mysql> SELECT 1 || 1;
-> 1
mysql> SELECT 1 || 0;
-> 1
mysql> SELECT 0 || 0;
-> 0
mysql> SELECT 0 || NULL;
-> NULL
mysql> SELECT 1 || NULL;
-> 1
XOR mysql> SELECT 1 XOR 1;
-> 0
mysql> SELECT 1 XOR 0;
-> 1
mysql> SELECT 1 XOR NULL;
-> NULL
mysql> SELECT 1 XOR 1 XOR 1;
-> 1
II.3.1.3. Các hàm điều kiệnII.3.1.3. Các hàm điều kiện
CASE ... WHEN...THEN...ELSE...ENDmysql> SELECT CASE 1 WHEN 1 THEN "one" WHEN 2 THEN "two" ELSE "more" END; -> "one"mysql> SELECT CASE WHEN 1>0 THEN "true" ELSE "false" END; -> "true"mysql> SELECT CASE BINARY "B" WHEN "a" THEN 1 WHEN "b" THEN 2
END; -> NULL
IF(expr1,expr2,expr3)mysql> SELECT IF(1>2,2,3); -> 3mysql> SELECT IF(1<2,'yes','no'); -> 'yes'mysql> SELECT IF(STRCMP('test','test1'),'no','yes'); -> 'no'
◦ expr1 luôn được chuyển về số nguyênmysql> SELECT IF(0.1,1,0); -> 0mysql> SELECT IF(0.1<>0,1,0); -> 1
II.3.1.3. Các hàm điều kiện II.3.1.3. Các hàm điều kiện (2)(2) IFNULL(expr1,expr2)
mysql> SELECT IFNULL(1,0); -> 1mysql> SELECT IFNULL(NULL,10); -> 10mysql> SELECT IFNULL(1/0,10); -> 10mysql> SELECT IFNULL(1/0,'yes'); -> 'yes'
NULLIF(expr1,expr2) mysql> SELECT NULLIF(1,1); -> NULLmysql> SELECT NULLIF(1,2); -> 1
II.3.2. Các hàm trên StringII.3.2. Các hàm trên String
ASCII(str) mysql> SELECT ASCII('2'); -> 50mysql> SELECT ASCII(2); -> 50mysql> SELECT ASCII('dx'); -> 100
BIN(N) mysql> SELECT BIN(12); -> '1100'
BIT_LENGTH(str) mysql> SELECT BIT_LENGTH('text'); -> 32
CHAR(N,...) mysql> SELECT CHAR(77,121,83,81,'76'); -> 'MySQL'mysql> SELECT CHAR(77,77.3,'77.3'); -> 'MMM'
CHAR_LENGTH(str)
CONCAT(str1,str2,...)
mysql> SELECT CONCAT('My', 'S', 'QL'); -> 'MySQL'mysql> SELECT CONCAT('My', NULL, 'QL'); -> NULLmysql> SELECT CONCAT(14.3); -> '14.3'
II.3.2. Các hàm trên String II.3.2. Các hàm trên String (2)(2)
CONCAT_WS(separator, str1, str2,...)
SELECT CONCAT_WS(",","First name","Second name","Last Name"); -> 'First name,Second name,Last Name'SELECT CONCAT_WS(",","First name",NULL,"Last Name"); -> 'First name,Last Name'
CONV(N,from_base,to_base)
SELECT CONV("a",16,2); -> '1010'SELECT CONV("6E",18,8); -> '172'SELECT CONV(-17,10,-18); -> '-H'SELECT CONV(10+"10"+'10'+0xa,10,10); -> '40'
ELT(N,str1,str2,str3,...)
SELECT ELT(1, 'ej', 'Heja', 'hej', 'foo'); -> 'ej'SELECT ELT(4, 'ej', 'Heja', 'hej', 'foo'); -> 'foo'
EXPORT_SET(bits,on,off,[separator,[number_of_bits]])
SELECT EXPORT_SET(5,'Y','N',',',4) -> Y,N,Y,N
FIELD(str,str1,str2,str3,...)
SELECT FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo'); -> 2SELECT FIELD('fo', 'Hej', 'ej', 'Heja', 'hej', 'foo'); -> 0
II.3.2. Các hàm trên String (3)II.3.2. Các hàm trên String (3)
FIND_IN_SET(str,strlist) mysql> SELECT FIND_IN_SET('b','a,b,c,d');
-> 2
HEX(N_or_S) mysql> SELECT HEX(255);
-> 'FF'
mysql> SELECT HEX("abc");
-> 616263
mysql> SELECT 0x616263;
-> "abc"
INSERT(str,pos,len,newstr) mysql> SELECT INSERT('Quadratic', 3, 4, 'What');
-> 'QuWhattic'
INSTR(str,substr) mysql> SELECT INSTR('foobarbar', 'bar');
-> 4
mysql> SELECT INSTR('xbar', 'foobar');
-> 0
LEFT(str,len) mysql> SELECT LEFT('foobarbar', 5);
-> 'fooba'
LENGTH(str) mysql> SELECT LENGTH('text');
-> 4
LOAD_FILE(file_name) mysql> UPDATE tbl_name
SET blob_column=LOAD_FILE("/tmp/picture")
WHERE id=1;
II.3.2. Các hàm trên String (4)II.3.2. Các hàm trên String (4)
LOCATE(substr,str)
LOCATE(substr,str,pos)
mysql> SELECT LOCATE('bar', 'foobarbar');
-> 4
mysql> SELECT LOCATE('xbar', 'foobar');
-> 0
mysql> SELECT LOCATE('bar', 'foobarbar',5);
-> 7
LOWER(str) mysql> SELECT LOWER('QUADRATICALLY');
-> 'quadratically'
LPAD(str,len,padstr) mysql> SELECT LPAD('hi',6,'?');
-> '????hi'
LTRIM(str) mysql> SELECT LTRIM(' barbar');
-> 'barbar'
MAKE_SET(bits,str1,str2,...)
mysql> SELECT MAKE_SET(1,'a','b','c');
-> 'a'
mysql> SELECT MAKE_SET(1 | 4,'hello','nice','world');
-> 'hello,world'
mysql> SELECT MAKE_SET(0,'a','b','c');
-> ''
QUOTE(str) mysql> SELECT QUOTE("Don't");
-> 'Don\'t!'
mysql> SELECT QUOTE(NULL);
-> NULL
II.3.2. Các hàm trên String (5)II.3.2. Các hàm trên String (5)
REPEAT(str,count) mysql> SELECT REPEAT('MySQL', 3);
-> 'MySQLMySQLMySQL'
REPLACE(str,from_str,to_str)
mysql> SELECT REPLACE('www.mysql.com', 'w', 'Ww');
-> 'WwWwWw.mysql.com'
REVERSE(str) mysql> SELECT REVERSE('abc');
-> 'cba'
RIGHT(str,len) mysql> SELECT RIGHT('foobarbar', 4);
-> 'rbar'
RPAD(str,len,padstr) mysql> SELECT RPAD('hi',5,'?');
-> 'hi???'
RTRIM(str) mysql> SELECT RTRIM('barbar ');
-> 'barbar'
SPACE(N) mysql> SELECT SPACE(6);
-> ' '
SUBSTRING(str,pos)
SUBSTRING(str FROM pos)
SUBSTRING(str,pos,len)
SUBSTRING(str FROM pos FOR len)
mysql> SELECT SUBSTRING('Quadratically',5);
-> 'ratically'
mysql> SELECT SUBSTRING('foobarbar' FROM 4);
-> 'barbar'
mysql> SELECT SUBSTRING('Quadratically',5,6);
-> 'ratica'
II.3.2. Các hàm trên String (6)II.3.2. Các hàm trên String (6)
SUBSTRING_INDEX(str,delim,count)
mysql> SELECT SUBSTRING_INDEX('www.mysql.com', '.', 2);
-> 'www.mysql'
mysql> SELECT SUBSTRING_INDEX('www.mysql.com', '.', -2);
-> 'mysql.com'
TRIM([[BOTH | LEADING | TRAILING] [remstr] FROM] str)
mysql> SELECT TRIM(' bar ');
-> 'bar'
mysql> SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx');
-> 'barxxx'
mysql> SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx');
-> 'bar'
mysql> SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz');
-> 'barx'
UCASE(str)
UPPER(str)
mysql> SELECT UPPER('Hej');
-> 'HEJ'
II.3.2. Các hàm trên StringII.3.2. Các hàm trên String
II.3.2.1. So sánh stringII.3.2.2. Phân biệt chữ hoa, chữ
thường
II.3.2.1. So sánh stringII.3.2.1. So sánh string
MySQL tự động chuyển các số thành string (nếu cần)mysql> SELECT 1+"1";
-> 2
mysql> SELECT CONCAT(2,' test');
-> '2 test' expr LIKE pat [ESCAPE 'escape-char']
mysql> SELECT 'David!' LIKE 'David_';
-> 1
mysql> SELECT 'David!' LIKE '%D%v%';
-> 1
mysql> SELECT 'David!' LIKE 'David\_';
-> 0
mysql> SELECT 'David_' LIKE 'David\_';
-> 1
mysql> SELECT 'David_' LIKE 'David|_' ESCAPE '|';
-> 1
mysql> SELECT 'abc' LIKE 'ABC';
-> 1
mysql> SELECT 'abc' LIKE BINARY 'ABC';
-> 0
mysql> SELECT 10 LIKE '1%';
-> 1
II.3.2.1. So sánh string (2)II.3.2.1. So sánh string (2)
MATCH ... AGAINST()mysql> CREATE TABLE articles (
-> id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
-> title VARCHAR(200),
-> body TEXT,
-> FULLTEXT (title,body)
-> );
mysql> INSERT INTO articles VALUES
-> (NULL,'MySQL Tutorial', 'DBMS stands for DataBase ...'),
-> (NULL,'How To Use MySQL Efficiently', 'After you went through a ...'),
-> (NULL,'Optimizing MySQL','In this tutorial we will show ...'),
-> (NULL,'1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
-> (NULL,'MySQL vs. YourSQL', 'In the following database comparison ...'),
-> (NULL,'MySQL Security', 'When configured properly, MySQL ...');
mysql> SELECT * FROM articles
-> WHERE MATCH (title,body) AGAINST ('database');
+----+-------------------+------------------------------------------+
| id | title | body |
+----+-------------------+------------------------------------------+
| 5 | MySQL vs. YourSQL | In the following database comparison ... |
| 1 | MySQL Tutorial | DBMS stands for DataBase ... |
+----+-------------------+------------------------------------------+
II.3.2.2. Phân biệt chữ hoa, chữ II.3.2.2. Phân biệt chữ hoa, chữ thườngthường
BINARY: Chuyển từ String sang kiểu Binarymysql> SELECT "a" = "A";
-> 1
mysql> SELECT BINARY "a" = "A";
-> 0
Đối với kiểu trường BLOB, để tránh phân biệt chữ hoa, chữ thường, bạn chuyển tất cả về chữ hoaSELECT 'A' LIKE UPPER(blob_col) FROM table_name;
II.3.3. Các hàm trên kiểu II.3.3. Các hàm trên kiểu sốsố
mysql> SELECT 3+5; -> 8mysql> SELECT 3-5; -> -2mysql> SELECT - 2; -> -2mysql> SELECT 3*5; -> 15mysql> SELECT 18014398509481984*18014398509481984.0; -> 324518553658426726783156020576256.0mysql> SELECT 18014398509481984*18014398509481984; -> 0mysql> SELECT 3/5; -> 0.60mysql> SELECT 102/(1-1); -> NULL
II.3.3. Các hàm trên kiểu II.3.3. Các hàm trên kiểu số (2)số (2)ABS(X) mysql> SELECT ABS(2);
-> 2
mysql> SELECT ABS(-32);
-> 32
ACOS(X) mysql> SELECT ACOS(1);
-> 0.000000
mysql> SELECT ACOS(1.0001);
-> NULL
mysql> SELECT ACOS(0);
-> 1.570796
ASIN(X) mysql> SELECT ASIN(0.2);
-> 0.201358
mysql> SELECT ASIN('foo');
-> 0.000000
ATAN(X) mysql> SELECT ATAN(2);
-> 1.107149
mysql> SELECT ATAN(-2);
-> -1.107149
ATAN(Y,X)
ATAN2(Y,X)
mysql> SELECT ATAN(-2,2);
-> -0.785398
mysql> SELECT ATAN2(PI(),0);
-> 1.570796
CEILING(X)
CEIL(X)
mysql> SELECT CEILING(1.23);
-> 2
mysql> SELECT CEIL(-1.23);
-> -1
COS(X) mysql> SELECT COS(PI());
-> -1.000000
COT(X) mysql> SELECT COT(12);
-> -1.57267341
mysql> SELECT COT(0);
-> NULL
CRC32(expr) mysql> SELECT CRC32('MySQL');
-> 3259397556
DEGREES(X) mysql> SELECT DEGREES(PI());
-> 180.000000
DIV mysql> SELECT 5 DIV 2
-> 2
EXP(X) mysql> SELECT EXP(2);
-> 7.389056
mysql> SELECT EXP(-2);
-> 0.135335
II.3.3. Các hàm trên kiểu II.3.3. Các hàm trên kiểu số (3)số (3)
FLOOR(X) mysql> SELECT FLOOR(1.23);
-> 1
mysql> SELECT FLOOR(-1.23);
-> -2
GREATEST(X,Y,...)
mysql> SELECT GREATEST(2,0);
-> 2
mysql> SELECT GREATEST(34.0,3.0,5.0,767.0);
-> 767.0
mysql> SELECT GREATEST("B","A","C");
-> "C"
LEAST(X,Y,...)
mysql> SELECT LEAST(2,0);
-> 0
mysql> SELECT LEAST(34.0,3.0,5.0,767.0);
-> 3.0
mysql> SELECT LEAST("B","A","C");
-> "A"
LN(X) mysql> SELECT LN(2);
-> 0.693147
mysql> SELECT LN(-2);
-> NULL
LOG(X)
LOG(B,X)
mysql> SELECT LOG(2);
-> 0.693147
mysql> SELECT LOG(-2);
-> NULL
mysql> SELECT LOG(2,65536);
-> 16.000000
mysql> SELECT LOG(1,100);
-> NULL
MOD(N,M)
%
mysql> SELECT MOD(234, 10);
-> 4
mysql> SELECT 253 % 7;
-> 1
mysql> SELECT 29 MOD 9;
-> 2
PI() mysql> SELECT PI();
-> 3.141593
mysql> SELECT PI()+0.000000000000000000;
-> 3.141592653589793116
POW(X,Y)
POWER(X,Y)
mysql> SELECT POW(2,2);
-> 4.000000
mysql> SELECT POW(2,-2);
-> 0.250000
II.3.3. Các hàm trên kiểu II.3.3. Các hàm trên kiểu số (4)số (4)
RADIANS(X) mysql> SELECT RADIANS(90);
-> 1.570796
RAND()
RAND(N)
mysql> SELECT RAND();
-> 0.9233482386203
mysql> SELECT RAND(20);
-> 0.15888261251047
mysql> SELECT RAND(20);
-> 0.15888261251047
mysql> SELECT RAND();
-> 0.63553050033332
mysql> SELECT RAND();
-> 0.70100469486881
ROUND(X)
ROUND(X,D)
mysql> SELECT ROUND(-1.23);
-> -1
mysql> SELECT ROUND(-1.58);
-> -2
mysql> SELECT ROUND(1.58);
-> 2
mysql> SELECT ROUND(1.298, 1);
-> 1.3
mysql> SELECT ROUND(1.298, 0);
-> 1
mysql> SELECT ROUND(23.298, -1);
-> 20
SIGN(X) mysql> SELECT SIGN(-32);
-> -1
mysql> SELECT SIGN(0);
-> 0
mysql> SELECT SIGN(234);
-> 1
COS(X) mysql> SELECT SIN(PI());
-> 0.000000
SQRT(X) mysql> SELECT SQRT(4);
-> 2.000000
mysql> SELECT SQRT(20);
-> 4.472136
TAN(X) mysql> SELECT TAN(PI()+1);
-> 1.557408
TRUNCATE(X,D) mysql> SELECT TRUNCATE(1.223,1);
-> 1.2
mysql> SELECT TRUNCATE(1.999,1);
-> 1.9
mysql> SELECT TRUNCATE(1.999,0);
-> 1
mysql> SELECT TRUNCATE(-1.999,1);
-> -1.9
II.3.4. Các hàm trên ngày II.3.4. Các hàm trên ngày thángtháng
ADDDATE(expr,days) mysql> SELECT ADDDATE('1998-01-02', 31);
-> '1998-02-02'
ADDTIME(expr,expr2) mysql> SELECT ADDTIME("1997-12-31 23:59:59.999999", "1 1:1:1.000002");
-> '1998-01-02 01:01:01.000001'
mysql> SELECT ADDTIME("01:00:00.999999", "02:00:00.999998");
-> '03:00:01.999997'
CURDATE()
CURRENT_DATE
CURRENT_DATE()
mysql> SELECT CURDATE();
-> '1997-12-15'
mysql> SELECT CURDATE() + 0;
-> 19971215
CURTIME()
CURRENT_TIME
CURRENT_TIME()
mysql> SELECT CURTIME();
-> '23:50:26'
mysql> SELECT CURTIME() + 0;
-> 235026
DATE(expr) mysql> SELECT DATE('2003-12-31 01:02:03');
-> '2003-12-31'
DATEDIFF(expr,expr2) mysql> SELECT DATEDIFF('1997-12-31 23:59:59','1997-12-30');
-> 1
mysql> SELECT DATEDIFF('1997-11-31 23:59:59','1997-12-31');
-> -30
II.3.4. Các hàm trên ngày II.3.4. Các hàm trên ngày tháng (2)tháng (2)
DATE_ADD(date,INTERVAL expr type) DATE_SUB(date,INTERVAL expr type)
mysql> SELECT '1997-12-31 23:59:59' + INTERVAL 1 SECOND; -> '1998-01-01 00:00:00'mysql> SELECT INTERVAL 1 DAY + '1997-12-31'; -> '1998-01-01'mysql> SELECT '1998-01-01' - INTERVAL 1 SECOND; -> '1997-12-31 23:59:59'mysql> SELECT DATE_ADD('1997-12-31 23:59:59', -> INTERVAL 1 SECOND); -> '1998-01-01 00:00:00'mysql> SELECT DATE_ADD('1997-12-31 23:59:59', -> INTERVAL 1 DAY); -> '1998-01-01 23:59:59'mysql> SELECT DATE_ADD('1997-12-31 23:59:59', -> INTERVAL '1:1' MINUTE_SECOND); -> '1998-01-01 00:01:00'mysql> SELECT DATE_SUB('1998-01-01 00:00:00', -> INTERVAL '1 1:1:1' DAY_SECOND); -> '1997-12-30 22:58:59'mysql> SELECT DATE_ADD('1998-01-01 00:00:00', -> INTERVAL '-1 10' DAY_HOUR); -> '1997-12-30 14:00:00'mysql> SELECT DATE_SUB('1998-01-02', INTERVAL 31 DAY); -> '1997-12-02'mysql> SELECT DATE_ADD('1992-12-31 23:59:59.000002', -> INTERVAL '1.999999' SECOND_MICROSECOND); -> '1993-01-01 00:00:01.000001'
II.3.4. Các hàm trên ngày II.3.4. Các hàm trên ngày tháng (3)tháng (3)
DATE_FORMAT(date,format) mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y');
-> 'Saturday October 1997'
mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s');
-> '22:23:00'
mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00',
'%D %y %a %d %m %b %j');
-> '4th 97 Sat 04 10 Oct 277'
mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00',
'%H %k %I %r %T %S %w');
-> '22 22 10 10:23:00 PM 22:23:00 00 6'
mysql> SELECT DATE_FORMAT('1999-01-01', '%X %V');
-> '1998 52'
DAY(date)
DAYOFMONTH(date)
mysql> SELECT DAYOFMONTH('1998-02-03');
-> 3
DAYNAME(date) mysql> SELECT DAYNAME('1998-02-05');
-> 'Thursday'
DAYOFWEEK(date) mysql> SELECT DAYOFWEEK('1998-02-03');
-> 3
DAYOFYEAR(date) mysql> SELECT DAYOFYEAR('1998-02-03');
-> 34
II.3.4. Các hàm trên ngày II.3.4. Các hàm trên ngày tháng (4)tháng (4)
EXTRACT(type FROM date) mysql> SELECT EXTRACT(YEAR FROM "1999-07-02");
-> 1999
mysql> SELECT EXTRACT(YEAR_MONTH FROM "1999-07-02 01:02:03");
-> 199907
mysql> SELECT EXTRACT(DAY_MINUTE FROM "1999-07-02 01:02:03");
-> 20102
mysql> SELECT EXTRACT(MICROSECOND FROM "2003-01-02 10:30:00.00123");
-> 123
FROM_DAYS(N) mysql> SELECT FROM_DAYS(729669);
-> '1997-10-07'
HOUR(time) mysql> SELECT HOUR('272:59:59');
-> 272
MAKEDATE(year,dayofyear) mysql> SELECT MAKEDATE(2001,31), MAKEDATE(2001,32);
-> '2001-01-31', '2001-02-01'
mysql> SELECT MAKEDATE(2001,365), MAKEDATE(2004,365);
-> '2001-12-31', '2004-12-30'
mysql> SELECT MAKEDATE(2001,0);
-> NULL
MAKETIME(hour,minute,second) mysql> SELECT MAKETIME(12,15,30);
-> '12:15:30'
II.3.4. Các hàm trên ngày II.3.4. Các hàm trên ngày tháng (5)tháng (5)
MINUTE(time) mysql> SELECT MINUTE('98-02-03 10:05:03');
-> 5
MONTH(date) mysql> SELECT MONTH('1998-02-03');
-> 2
MONTHNAME(date) mysql> SELECT MONTHNAME('1998-02-05');
-> 'February'
SECOND(time) mysql> SELECT SECOND('10:05:03');
-> 3
STR_TO_DATE(str,format) mysql> SELECT STR_TO_DATE('03.10.2003 09.20', '%d.%m.%Y %H.%i');
-> 2003-10-03 09:20:00
mysql> SELECT STR_TO_DATE('10rap', '%crap');
-> 0000-10-00 00:00:00
mysql> SELECT STR_TO_DATE('2003-15-10 00:00:00', '%Y-%m-%d %H:%i:%s');
-> NULL
TIMEDIFF(expr,expr2) mysql> SELECT TIMEDIFF('2000:01:01 00:00:00', '2000:01:01 00:00:00.000001');
-> '-00:00:00.000001'
mysql> SELECT TIMEDIFF('1997-12-31 23:59:59.000001','1997-12-30 01:01:01.000002');
-> '46:58:57.999999'
TO_DAYS(date) mysql> SELECT TO_DAYS(950501);
-> 728779
mysql> SELECT TO_DAYS('1997-10-07');
-> 729669
II.3.5. Hàm đổi kiểuII.3.5. Hàm đổi kiểu
Sử dụng hàm CAST hoặc CONVERT◦ CAST(expression AS type)◦ CONVERT(expression,type)◦ CONVERT(expr USING transcoding_name)
Các kiểu sử dụng trong tham số type◦ BINARY ◦ CHAR ◦ DATE ◦ DATETIME ◦ SIGNED {INTEGER} ◦ TIME ◦ UNSIGNED {INTEGER}mysql> SELECT CAST(1-2 AS UNSIGNED); -> 18446744073709551615mysql> SELECT CAST(CAST(1-2 AS UNSIGNED) AS SIGNED); -> -1mysql> SELECT CAST(NOW() AS DATE); -> 2003-05-26
II.3.7. Các hàm dùng với mệnh đề II.3.7. Các hàm dùng với mệnh đề GROUP BYGROUP BY
II.3.7.1. Các hàm GROUP BYII.3.7.2. WITH ROLLUPII.3.7.3. GROUP BY với các trường
không nằm trong mệnh đề GROUP
II.3.7.1. Các hàm GROUP BYII.3.7.1. Các hàm GROUP BY
AVG(expr) SELECT student_name, AVG(test_score)
FROM student
GROUP BY student_name;
COUNT(expr)
SELECT student.student_name,COUNT(*)
FROM student,course
WHERE student.student_id=course.student_id
GROUP BY student_name;
SELECT COUNT(*) FROM student;
II.3.7.1. Các hàm GROUP BYII.3.7.1. Các hàm GROUP BY
COUNT(DISTINCT expr,[expr...])
SELECT COUNT(DISTINCT results) FROM student;
GROUP_CONCAT(expr)
SELECT student_name,
GROUP_CONCAT(test_score)
FROM student
GROUP BY student_name;
SELECT student_name,
GROUP_CONCAT(DISTINCT test_score
ORDER BY test_score DESC SEPARATOR " ")
FROM student
GROUP BY student_name;
II.3.7.1. Các hàm GROUP BY II.3.7.1. Các hàm GROUP BY (2)(2)
MIN(expr)
MAX(expr)
SELECT student_name, MIN(test_score), MAX(test_score)
FROM student
GROUP BY student_name;
STD(expr)
STDDEV(expr)
SUM(expr)
VARIANCE(expr)
II.3.7.2. WITH ROLLUPII.3.7.2. WITH ROLLUP
SELECT AVG(diemtb) FROM sv GROUP BY lop;+-------------+| avg(diemtb) |+-------------+| 7.10000 || 7.76667 || 8.35000 || 8.00000 || 8.50000 |+-------------+SELECT AVG(diemtb) FROM sv GROUP BY lop WITH ROLLUP;+-------------+| avg(diemtb) |+-------------+| 7.10000 || 7.76667 || 8.35000 || 8.00000 || 8.50000 || 7.92308 |+-------------+
SELECT lop, AVG(diemtb) FROM sv GROUP BY lop WITH ROLLUP;+------+-------------+| lop | avg(diemtb) |+------+-------------+| 1 | 7.10000 || 2 | 7.76667 || 4 | 8.35000 || 10 | 8.00000 || 11 | 8.50000 || NULL | 7.92308 |+------+-------------+SELECT lop, SUM(diemtb) FROM sv GROUP BY lop WITH ROLLUP;+------+-------------+| lop | sum(diemtb) |+------+-------------+| 1 | 21.3 || 2 | 23.3 || 4 | 33.4 || 10 | 8.0 || 11 | 17.0 || NULL | 103.0 |+------+-------------+
II.3.7.2. WITH ROLLUP (2)II.3.7.2. WITH ROLLUP (2)
SELECT lop.khoa, lop.id, SUM(diemtb)FROM sv, lopWHERE sv.lop=lop.idGROUP BY lop.khoa, lop.id WITH rollup;+------+-----+-------------+| khoa | id | sum(diemtb) |+------+-----+-------------+| 1 | 1 | 21.3 || 1 | 2 | 23.3 || 1 | 4 | 33.4 || 1 |NULL | 78.0 || 2 | 10 | 8.0 || 2 | 11 | 17.0 || 2 |NULL | 25.0 || NULL |NULL | 103.0 |+------+-----+-------------+
II.3.7.3. GROUP BY với các trường II.3.7.3. GROUP BY với các trường không nằm trong mệnh đề GROUPkhông nằm trong mệnh đề GROUP
SELECT hodem, ten, MAX(diemtb) FROM sv GROUP BY lop;+----------+-------+-------------+| hodem | ten | max(diemtb) |+----------+-------+-------------+| Dao Ngoc | Manh | 8.7 || Tran Van | Khom | 8.8 || doan | cong | 9.5 || Cu van | Chuoi | 8.0 || Dao Ngoc | Manh | 9.2 |+----------+-------+-------------+SELECT hodem, ten, diemtb, MAX(diemtb) FROM sv GROUP BY lop;+----------+-------+--------+-------------+| hodem | ten | diemtb | max(diemtb) |+----------+-------+--------+-------------+| Dao Ngoc | Manh | 6.4 | 8.7 || Tran Van | Khom | 7.2 | 8.8 || doan | cong | 9.5 | 9.5 || Cu van | Chuoi | 8.0 | 8.0 || Dao Ngoc | Manh | 7.8 | 9.2 |+----------+-------+--------+-------------+
II.3.7.3. GROUP BY với các trường II.3.7.3. GROUP BY với các trường không nằm trong mệnh đề GROUP (2)không nằm trong mệnh đề GROUP (2)
SELECT hodem, ten, diemtb, MAX(diemtb) FROM sv GROUP BY lop ORDER BY diemtb DESC;
+----------+-------+--------+-------------+
| hodem | ten | diemtb | max(diemtb) |
+----------+-------+--------+-------------+
| doan | cong | 9.5 | 9.5 |
| Cu van | Chuoi | 8.0 | 8.0 |
| Dao Ngoc | Manh | 7.8 | 9.2 |
| Tran Van | Khom | 7.2 | 8.8 |
| Dao Ngoc | Manh | 6.4 | 8.7 |
+----------+-------+--------+-------------+
SELECT * FROM
sv,(SELECT lop, MAX(diemtb) AS diem FROM sv GROUP BY lop) AS b
WHERE sv.lop=b.lop AND sv.diemtb=b.diem;
+----+-----------+-------+------------+------+--------+------+------+
| id | hodem | ten | ngaysinh | lop | diemtb | lop | diem |
+----+-----------+-------+------------+------+--------+------+------+
| 6 | Pham Xuan | Dinh | 1983-08-10 | 1 | 8.7 | 1 | 8.7 |
| 10 | Tran Van | Khom | 2005-03-03 | 2 | 8.8 | 2 | 8.8 |
| 1 | doan | cong | 0000-00-00 | 4 | 9.5 | 4 | 9.5 |
| 11 | Cu van | Chuoi | 2004-03-05 | 10 | 8.0 | 10 | 8.0 |
| 13 | Le Minh | Thuy | 1983-06-21 | 11 | 9.2 | 11 | 9.2 |
+----+-----------+-------+------------+------+--------+------+------+
II.3.7.3. GROUP BY với các trường II.3.7.3. GROUP BY với các trường không nằm trong mệnh đề GROUP không nằm trong mệnh đề GROUP (2)(2)
mysql> select hodem, ten, diemtb, max(diemtb) from sv group by lop order by diemtb desc;+----------+-------+--------+-------------+| hodem | ten | diemtb | max(diemtb) |+----------+-------+--------+-------------+| doan | cong | 9.5 | 9.5 || Cu van | Chuoi | 8.0 | 8.0 || Dao Ngoc | Manh | 7.8 | 9.2 || Tran Van | Khom | 7.2 | 8.8 || Dao Ngoc | Manh | 6.4 | 8.7 |+----------+-------+--------+-------------+mysql> select * from sv,(select lop, max(diemtb) as diem from sv group by lop) as b where sv.lop=b.lop and sv.diemtb=b.diem;+----+-----------+-------+------------+------+--------+------+------+| id | hodem | ten | ngaysinh | lop | diemtb | lop | diem |+----+-----------+-------+------------+------+--------+------+------+| 6 | Pham Xuan | Dinh | 1983-08-10 | 1 | 8.7 | 1 | 8.7 || 10 | Tran Van | Khom | 2005-03-03 | 2 | 8.8 | 2 | 8.8 || 1 | doan | cong | 0000-00-00 | 4 | 9.5 | 4 | 9.5 || 11 | Cu van | Chuoi | 2004-03-05 | 10 | 8.0 | 10 | 8.0 || 13 | Le Minh | Thuy | 1983-06-21 | 11 | 9.2 | 11 | 9.2 |+----+-----------+-------+------------+------+--------+------+------+
II.4. Các câu lệnh thao tác trên dữ II.4. Các câu lệnh thao tác trên dữ liệu (SELECT, INSERT, UPDATE, liệu (SELECT, INSERT, UPDATE, DELETE)DELETE)II.4.1. Câu lệnh SELECTII.4.2. Sử dụng query lồng nhau
(subquery)II.4.3. Câu lệnh INSERTII.4.4. Câu lệnh UPDATEII.4.5. Câu lệnh DELETEII.4.6. Câu lệnh REPLACEII.4.7. Câu lệnh LOAD DATA INFILE
II.4.1. Câu lệnh SELECTII.4.1. Câu lệnh SELECT
II.4.1.1. Cú pháp lệnh SELECTII.4.1.2. Sử dụng SELECT với JOINII.4.1.3. Sử dụng SELECT với UNION
II.4.1. Câu lệnh SELECT (2)II.4.1. Câu lệnh SELECT (2)
Câu lệnh SELECT là câu lệnh SQL được sử dụng nhiều nhất
SELECT sử dụng để rút trích dữ liệu từ một hoặc nhiều bảng khác nhau
Lệnh SELECT thường được sử dụng kết hợp với các điều kiện WHERE, HAVING
Khi sử dụng SELECT trên nhiều bảng, cần phải chú ý đến cách thức các bảng kết hợp với nhau vì điều này ảnh hưởng rất nhiều đến tốc độ thực hiện của lệnh
II.4.1.1. Cú pháp lệnh II.4.1.1. Cú pháp lệnh SELECTSELECT
SELECT [DISTINCT | DISTINCTROW | ALL] select_expression,...[FROM table_references] [WHERE where_definition]
[GROUP BY {col_name | formula} [ASC | DESC], ... [WITH ROLLUP]]
[HAVING where_definition] [ORDER BY {col_name | formula} [ASC | DESC] ,...] [LIMIT [offset,] row_count | row_count OFFSET offset]
II.4.1.1. Cú pháp lệnh II.4.1.1. Cú pháp lệnh SELECT (2)SELECT (2)Cú pháp của MySQL
SELECT 1+1;
Sử dung bảng dual để tương thích với CSDL khácSELECT 1+1 FROM dual;
Một số ví dụSELECT * FROM sv;
SELECT id, hodem, ten, ngay sinh FROM sv;
SELECT * FROM sv ORDER BY diemtb;
SELECT * FROM sv ORDER BY diemtb DESC;
SELECT * FROM sv ORDER BY lop ASC, diemtb DESC;
SELECT * FROM sv WHERE lop >= 2 AND lop <= 4;
SELECT * FROM sv WHERE lop BETWEEN 2 AND 4;
II.4.1.1. Cú pháp lệnh II.4.1.1. Cú pháp lệnh SELECT (3)SELECT (3)
Having chỉ nên sử dụng ở cuối câu query có sử dụng GROUP BY◦ SELECT MAX(diemtb) AS diemmax FROM sv GROUP BY lop HAVING diemmax>=9;
Liệt kê 5 dòng đầu tiên◦ SELECT * FROM sv LIMIT 5;
Liệt kê từ dòng 8 đến dòng 12◦ SELECT * FROM sv LIMIT 7, 5;
Đưa dữ liệu ra file text◦ SELECT * INTO OUTFILE 'sv.txt' FIELDS TERMINATED BY ';' FROM sv;
II.4.1.2. Sử dụng SELECT II.4.1.2. Sử dụng SELECT với JOINvới JOIN
Tích đề cactable, table
table STRAIGHT_JOIN table
Inner Jointable [INNER | CROSS] JOIN table [join_condition]
II.4.1.2. Sử dụng SELECT với JOIN II.4.1.2. Sử dụng SELECT với JOIN (2)(2)
Left Jointable_reference LEFT [OUTER] JOIN table_reference [join_condition]
Right Jointable_reference RIGHT [OUTER] JOIN table_reference [join_condition]
II.4.1.2. Sử dụng SELECT với JOIN II.4.1.2. Sử dụng SELECT với JOIN (3)(3)
Tích đề cácSELECT * FROM sv, lop;
SELECT * FROM sv STRAIGHT_JOIN lop
Phân biệt inner, left, right join?SELECT * FROM sv INNER JOIN lop ON sv.lop = lop.id;
SELECT * FROM sv LEFT JOIN lop ON sv.lop = lop.id;
SELECT * FROM sv RIGHT JOIN lop ON sv.lop = lop.id;
II.4.1.2. Sử dụng SELECT với JOIN II.4.1.2. Sử dụng SELECT với JOIN (3)(3)
SELECT * FROM lop LEFT JOIN sv
ON lop.id = sv.lop
WHERE sv.lop IS NULL;
SELECT * FROM sv LEFT JOIN lop
ON sv.lop=lop.id LEFT JOIN khoa
ON lop.khoa = khoa.id;
SELECT * FROM sv LEFT JOIN lop
ON sv.lop=lop.id LEFT JOIN khoa
ON lop.khoa = khoa.id;
II.4.1.3. Sử dụng SELECT với UNIONII.4.1.3. Sử dụng SELECT với UNION
Cú pháp UNION:SELECT ...
UNION [ALL | DISTINCT]
SELECT ...
[UNION [ALL | DISTINCT]
[SELECT ...]
Chú ý: Chỉ sử dụng 1 loại UNION ALL hoặc UNION DISTINCT trong 1 câu lệnh UNION
II.4.1.3. Sử dụng SELECT với UNION II.4.1.3. Sử dụng SELECT với UNION (2)(2)
CREATE TABLE t1 (id INT);CREATE TABLE t2 (id INT);INSERT INTO t1 VALUES(1),(1),(1),(2),(2);INSERT INTO t2 VALUES(2),(2),(3),(3),(3);
(SELECT * FROM t1)UNION DISTINCT(SELECT * FROM t2);
II.4.1.3. Sử dụng SELECT với UNION II.4.1.3. Sử dụng SELECT với UNION (3)(3)CREATE TABLE t1 (id INT);CREATE TABLE t2 (id INT);INSERT INTO t1 VALUES(2),(2),(1),(1),(1);INSERT INTO t2 VALUES(3),(3),(3),(2),(2);
(SELECT * FROM t1 ORDER BY id)UNION ALL(SELECT * FROM t2 ORDER BY id);
II.4.2. Sử dụng query lồng nhau II.4.2. Sử dụng query lồng nhau (SUBQUERY)(SUBQUERY)
SUBQUERY là query nằm trong query khác◦ SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
SELECT * FROM t1...◦ gọi là OUTER QUERY
SELECT column2 FROM t2◦ gọi là SUBQUERY
II.4.2. Sử dụng query lồng nhau II.4.2. Sử dụng query lồng nhau (SUBQUERY) (2)(SUBQUERY) (2)
SELECT tenlop, ( SELECT count(*) FROM sv WHERE sv.lop=lop.id )FROM lop;
SELECT tenlop, ( SELECT max(diemtb) FROM sv WHERE sv.lop=lop.id )FROM lop;
II.4.2. Sử dụng query lồng nhau II.4.2. Sử dụng query lồng nhau (SUBQUERY) (3)(SUBQUERY) (3)
SELECT tenlop, ( SELECT max(diemtb) FROM sv WHERE sv.lop=lop.id ) AS dmax, ( SELECT concat(hodem," ", ten) FROM sv WHERE sv.lop=lop.id AND diemtb=dmax )FROM lop;
II.4.2. Sử dụng query lồng nhau II.4.2. Sử dụng query lồng nhau (SUBQUERY) (4)(SUBQUERY) (4)
SELECT l_Ten, BangDiem.*FROM tblLop LEFT JOIN ( SELECT * FROM ( SELECT * FROM tblSinhVien ORDER BY sv_DiemTb DESC ) AS DiemSapXep GROUP BY sv_Lop ) BangDiemON l_ID = BangDiem.sv_Lop;
II.4.2. Sử dụng query lồng nhau II.4.2. Sử dụng query lồng nhau (subquery)(subquery)
II.4.2.1. Subquery với ANY, IN, SOME, ALL
II.4.2.2. Truyền các tham số giữa các lớp query
II.4.2.3. Sử dụng EXISTS và NOT EXISTS
II.4.2.4. Row SubqueryII.4.2.5. Subquery trong mệnh đề
FROMII.4.2.6. Tối ưu hóa Subquery
II.4.2.1. Subquery với ANY, IN, SOME, II.4.2.1. Subquery với ANY, IN, SOME, ALLALL
<operand> <comparison operator> ANY(<subquery>)
<operand> IN (<subquery>)
<operand> <comparison operator> SOME(<subquery>)
SELECT * FROM sv WHERE lop IN(SELECT id FROM lop);
SELECT * FROM sv WHERE lop = ANY(SELECT id FROM lop);
SELECT * FROM sv WHERE lop = ALL(SELECT id FROM lop);
SELECT * FROM sv WHERE lop <> ANY(SELECT id FROM lop);
SELECT * FROM sv WHERE lop <> ALL(SELECT id FROM lop);
II.4.2.2. Truyền các tham số giữa các II.4.2.2. Truyền các tham số giữa các lớp querylớp query
SELECT l_Ten, sv_Hodem, sv_Ten, sv_DiemTBFROM tblLop LEFT JOIN tblSinhVienON l_ID=sv_Lop AND sv_DiemTB = ( SELECT MAX(sv_DiemTB) FROM tblSinhVien WHERE sv_Lop=l_ID );
II.4.2.2. Truyền các tham số giữa II.4.2.2. Truyền các tham số giữa các lớp query (2)các lớp query (2)
SELECT tenkhoa, ( SELECT sum(( SELECT count(*) FROM sv WHERE sv.lop=lop.id )) FROM lop WHERE lop.khoa=khoa.id )FROM khoa;
II.4.2.3. Sử dụng EXISTS và NOT II.4.2.3. Sử dụng EXISTS và NOT EXISTSEXISTS
SELECT *FROM lopWHERE EXISTS( SELECT * FROM sv WHERE sv.lop=lop.id );
SELECT *FROM lopWHERE NOT EXISTS( SELECT * FROM sv WHERE sv.lop=lop.id );
II.4.2.3. Sử dụng EXISTS và NOT II.4.2.3. Sử dụng EXISTS và NOT EXISTS (2)EXISTS (2)
SELECT *FROM khoaWHERE NOT EXISTS( SELECT * FROM lop WHERE lop.khoa=khoa.id );
SELECT *FROM khoaWHERE NOT EXISTS( SELECT * FROM lop WHERE EXISTS( SELECT * FROM sv WHERE sv.lop=lop.id ) AND lop.khoa=khoa.id );
II.4.2.4. Row SubqueryII.4.2.4. Row Subquery
SELECT *FROM t1WHERE (1,2) = ( SELECT column1, column2 FROM t2 );
SELECT *FROM t1WHERE ROW(1,2) = ( SELECT column1, column2 FROM t2 );
II.4.2.4. Row Subquery (2)II.4.2.4. Row Subquery (2)SELECT *FROM t1WHERE (column1,column2) = (1,1);
SELECT *FROM t1WHERE column1 = 1 AND column2 = 1;
II.4.2.4. Row Subquery (3)II.4.2.4. Row Subquery (3)
SELECT column1,column2,column3FROM t1WHERE (column1,column2,column3) IN ( SELECT column1,column2,column3 FROM t2 );
SELECT * FROM sv WHERE (hodem,ten)=("doan","cong");
SELECT tenlop, ( SELECT max(diemtb) FROM sv WHERE sv.lop=lop.id) AS diemmax, ( SELECT concat(hodem, " ", ten) FROM sv WHERE (lop, diemtb)=(lop.id, diemmax))FROM lop;
II.4.2.5. Subquery trong mệnh đề II.4.2.5. Subquery trong mệnh đề FROMFROM
SELECT ... FROM (<subquery>) AS <name> ...SELECT count(a) FROM ( SELECT 'a' UNION ALL SELECT 'a' UNION ALL SELECT 'a' UNION ALL SELECT 'b') AS tempGROUP BY a;
SELECT avg(tongdiem)FROM ( SELECT sum(diemtb) AS tongdiem FROM sv GROUP BY lop ) AS a;
II.4.2.5. Subquery trong mệnh đề II.4.2.5. Subquery trong mệnh đề FROM (2)FROM (2)
SELECT *FROM svINNER JOIN ( SELECT lop, max(diemtb) AS diemmax FROM sv GROUP BY lop ) AS aON sv.lop=a.lop AND sv.diemtb = a.diemmax;
II.4.2.6. Tối ưu hóa II.4.2.6. Tối ưu hóa SubquerySubquery
Chuyển các mệnh đề từ ngoài vào trong subquerySELECT * FROM t1WHERE s1 IN (SELECT s1 FROM t1) OR s1 IN (SELECT s1 FROM t2);Đổi thànhSELECT * FROM t1WHERE s1 IN ( SELECT s1 FROM t1 UNION ALL SELECT s1 FROM t2 );HaySELECT (SELECT column1 FROM t1) + 5 FROM t2;Đổi thànhSELECT (SELECT column1 + 5 FROM t1) FROM t2;
II.4.2.6. Tối ưu hóa II.4.2.6. Tối ưu hóa Subquery (2)Subquery (2)
Sử dụng Rowsubquery thay vì truyền tham sốSELECT * FROM t1WHERE EXISTS( SELECT * FROM t2 WHERE t2.column1=t1.column1 AND t2.column2=t1.column2 );
Đổi thànhSELECT * FROM t1WHERE (column1,column2) IN ( SELECT column1,column2 FROM t2 );Sử dụng NOT (a=ANY(...)) thay vì a<>ALL(...)Sử dụng = ANY thay vì dùng EXISTS
II.4.2.6. Tối ưu hóa II.4.2.6. Tối ưu hóa Subquery (3)Subquery (3)
Cách thức MySql thực hiện Subquery◦ Những câu lệnh không có móc nối (truyền tham số) được
gọi 1 lần◦ Viết lại các câu lệnh sử dụng IN/ALL/ANY/SOME nếu sử
dụng các trường index trong bảng
... IN (SELECT indexed_column FROM single_table ...)
Thay bằng các hàm index-lookup
value {ALL|ANY|SOME} {> | < | >= | <=} (non-correlated subquery)
Thay bằng các hàm MIN, MAX (khi không có giá trị NULL)WHERE 5 > ALL (SELECT x FROM t)Thay bằngWHERE 5 > (SELECT MAX(x) FROM t)
II.4.3. Câu lệnh INSERTII.4.3. Câu lệnh INSERT
INSERT [LOW_PRIORITY | DELAYED] [IGNORE][INTO] tbl_name [(col_name,...)]VALUES ((expression | DEFAULT),...),(...),...[ON DUPLICATE KEY UPDATE col_name=expression, ...]
INSERT [LOW_PRIORITY | DELAYED] [IGNORE][INTO] tbl_name [(col_name,...)]SELECT ...
INSERT [LOW_PRIORITY | DELAYED] [IGNORE][INTO] tbl_nameSET col_name=(expression | DEFAULT), ...[ON DUPLICATE KEY UPDATE col_name=expression, ...]
II.4.3. Câu lệnh INSERTII.4.3. Câu lệnh INSERT
INSERT ... VALUES: Thêm dữ liệu theo giá trị nhập vào của 1 hoặc nhiều dòng
INSERT ... SELECT: Thêm dữ liệu vào bảng sử dụng dữ liệu của bảng khác
Nếu không xác định danh sách tên cột thì tất cả các cột phải được liệt kê
Nếu 1 cột không được liệt kê trong danh sách tên cột (hoặc được gán giá trị NULL) thì khi insert sẽ được sử dụng giá trị default
Nếu sử dụng từ khóa DELAYED, các dòng chèn vào sẽ được để trong buffer (sau đó tiến trình gọi INSERT được tiếp tục), dữ liệu được để trong buffer cho đến khi không còn thao tác đọc nào đến bảng mới được chèn vào trong bảng
Nếu dùng LOW_PRIORITY thì tiến trình đợi không còn thao tác đọc nào mới chèn dữ liệu vào trong bảng và tiếp tục
II.4.3. Câu lệnh INSERT (2)II.4.3. Câu lệnh INSERT (2)
CREATE TABLE temp(id INT PRIMARY KEY NOT NULL);INSERT INTO temp VALUES(10),(20),(30);INSERT INTO temp VALUES(20),(30),(40),(50);SELECT * FROM temp;
INSERT IGNORE INTO temp VALUES (20),(30),(40),(50);SELECT * FROM temp;
II.4.3. Câu lệnh INSERT (3)II.4.3. Câu lệnh INSERT (3)
CREATE TABLE temp (id INT);INSERT INTO temp VALUES(1),(2);INSERT INTO temp SELECT * FROM temp;SELECT * FROM temp;+------+| id |+------+| 1 || 2 || 1 || 2 |+------+
II.4.4. Câu lệnh UPDATEII.4.4. Câu lệnh UPDATE
UPDATE [LOW_PRIORITY] [IGNORE] tbl_nameSET col_name1=expr1 [, col_name2=expr2 ...][WHERE where_definition][ORDER BY ...][LIMIT row_count]
UPDATE [LOW_PRIORITY] [IGNORE] tbl_name [, tbl_name ...]
SET col_name1=expr1 [, col_name2=expr2 ...][WHERE where_definition]
II.4.4. Câu lệnh UPDATE II.4.4. Câu lệnh UPDATE (2)(2)
Lệnh UPDATE: sửa giá trị cột của các dòng đã có trong bảng Mệnh đề WHERE dùng để xác định dòng nào được cập nhật Mệnh đề ORDER BY xác định thứ tự cập nhật, kết hợp với
LIMIT để xác định các dòng cập nhật Nếu sử dụng từ khóa LOW_PRIORITY, tiến trình đợi đến khi
không có yêu cầu đến bảng mới thực hiện UPDATE Nếu sử dụng từ khóa IGNORE, MySQL sẽ bỏ qua lỗi trùng
khóa và vẫn tiếp tục cập nhật Nếu tên cột nằm ở phía phải của biểu thức thì sẽ cho giá trị
hiện tại của cột đó (ví dụ UPDATE temp SET id=id+1) Thứ tự thực hiện biểu thức từ trái qua phải (ví dụ UPDATE
temp SET id=id+1, id=id*2) Nếu cập nhật giá trị NULL cho cột NOT NULL thì sẽ lấy giá
trị DEFAULT của cột đó
II.4.4. Câu lệnh UPDATE (3)II.4.4. Câu lệnh UPDATE (3)
CREATE TABLE temp(id INT);INSERT INTO temp VALUES(1),(2);UPDATE temp SET id=id+1, id=id*2;SELECT * FROM temp;
UPDATE lop, svSET diemtb = diemtb+0.1WHERE lop.id=sv.lop AND lop.tenlop="46pm1";
SELECT tenlop, ( SELECT min(diemtb) FROM sv WHERE sv.lop = lop.id ORDER BY diemtb desc LIMIT 3 )FROM lop;
II.4.5. Câu lệnh DELETEII.4.5. Câu lệnh DELETE
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM table_name [WHERE where_definition] [ORDER BY ...] [LIMIT row_count]
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] table_name[.*] [, table_name[.*] ...]
FROM table-references [WHERE where_definition]
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM table_name[.*] [, table_name[.*] ...] USING table-references [WHERE where_definition]
II.4.5. Câu lệnh DELETE II.4.5. Câu lệnh DELETE (2)(2)Nếu sử dụng từ khóa LOW_PRIORITY, tiến
trình đợi đến khi không còn thao tác nào đến bảng mới thực hiện thao tác delete
Nếu sử dụng từ khóa IGNORE thì các lỗi sẽ được bỏ qua trong quá trình xóa
Mệnh đề ORDER BY kết hợp với LIMIT có thể xóa được một số lượng xác định các bản ghi theo thứ tự
Bạn có thể sử dụng cú pháp thứ 2 để xóa nhiều bảng cùng 1 lúc với các điều kiện ràng buộc giữa các bảng
II.4.5. Câu lệnh DELETE (3)II.4.5. Câu lệnh DELETE (3)
DELETE FROM sv;DELETE FROM sv WHERE sv.lop IN (1,2);
DELETE FROM svWHERE NOT EXISTS( SELECT id FROM lop WHERE lop.id = sv.lop );
DELETE FROM sv2WHERE sv2.lop <> ALL(SELECT id FROM lop2);
II.4.5. Câu lệnh DELETE II.4.5. Câu lệnh DELETE (4)(4)
DELETE sv2FROM sv2, lop2WHERE sv2.lop=lop2.id AND lop2.tenlop = "46pm1";
DELETE FROM sv2WHERE ( SELECT tenlop FROM lop2 WHERE lop2.id=sv2.lop AND lop2.tenlop="47th2“ )ORDER BY diemtb LIMIT 1;
II.4.5. Câu lệnh DELETE II.4.5. Câu lệnh DELETE (5)(5)TRUNCATE TABLE table_name Giống lệnh DELETE FROM
table_name Một số điểm khác biệt:
◦ Ko chỉ xóa mà còn drop table, sau đó tạo lại (do đó nhanh hơn)
◦ Không trả về số dòng bị xóa◦ Các số AUTO_INCREMENT không
được reset lại từ đầu mà vẫn lưu lại giá trị tiếp theo trước khi xóa bảng
II.4.6. Câu lệnh REPLACEII.4.6. Câu lệnh REPLACE
REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name [(col_name,...)] VALUES (expression,...),(...),...
REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name [(col_name,...)] SELECT ...
REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name SET col_name=expression,col_name=expression,...
Cú pháp giống với câu lệnh INSERT nhưng hoạt động khác 1 chút:- Xóa các dòng cũ có PRIMARY KEY trùng với dòng mới
insert- Chèn các dòng mới
II.4.7. Câu lệnh LOAD II.4.7. Câu lệnh LOAD DATA INFILEDATA INFILE
LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL]INFILE 'file_name.txt' [REPLACE | IGNORE] INTO TABLE tbl_name [FIELDS [TERMINATED BY '\t'] [[OPTIONALLY] ENCLOSED BY ''] [ESCAPED BY '\\' ] ] [LINES [STARTING BY ''] [TERMINATED BY '\n'] ] [(col_name,...)]
II.5. Các câu lệnh thao tác trên II.5. Các câu lệnh thao tác trên bảng CREATE, DROP, ALTERbảng CREATE, DROP, ALTER
II.5.1. CREATE DATABASEII.5.2. DROP DATABASEII.5.3. CREATE TABLEII.5.4. ALTER TABLEII.5.5. RENAME TABLEII.5.6. DROP TABLE
II.5.1. CREATE DATABASEII.5.1. CREATE DATABASE
CREATE DATABASE [IF NOT EXISTS] db_name
Nếu database đã tồn tại -> lỗi Nếu không muốn sinh lỗi, sử
dụng từ khóa IF NOT EXISTS
II.5.2. DROP DATABASEII.5.2. DROP DATABASE
DROP DATABASE [IF EXISTS] db_name Sử dụng từ khóa IF EXISTS để
tránh gây lỗi trong trường hợp db_name không tồn tại
II.5.3. CREATE TABLEII.5.3. CREATE TABLE
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,...)] [table_options] [select_statement]
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(] LIKE old_tbl_name [)];
II.5.3. CREATE TABLE (2)II.5.3. CREATE TABLE (2)
Từ khóa TEMPORARY để tạo bảng tạm thời, bảng này chỉ tồn tại trong connection và sau đó sẽ bị xóa khi disconnect
Từ khóa IF NOT EXISTS dùng để tránh phát sinh lỗi khi bảng đã tồn tại
Bạn có thể tạo bảng từ 1 câu lệnh SELECT với cú pháp CREATE TABLE tbl_name SELECT..., tuy nhiên phải chú ý đến tên trường của câu lệnh SELECT◦ CREATE TABLE temp SELECT * FROM sv, lop WHERE sv.lop=lop.id;
◦ CREATE TABLE temp SELECT sv.*, lop.tenlop FROM sv, lop WHERE sv.lop=lop.id;
II.5.3. CREATE TABLE (3)II.5.3. CREATE TABLE (3)Để tạo 1 bảng mới với cấu trúc
giống với một bảng đã có, có thể sử dụng CREATE TABLE ... LIKE (lệnh này chỉ sao chép cấu trúc, không sao chép dữ liệu)◦CREATE TABLE sv2 LIKE sv;
II.5.3. CREATE TABLE (4)II.5.3. CREATE TABLE (4)
II.5.3.1. create_definitionII.5.3.2. table_option
II.5.3.1. create_definitionII.5.3.1. create_definition
col_name type [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT] [PRIMARY] KEY]| PRIMARY KEY [index_name] (index_col_name,...)| KEY [index_name] (index_col_name,...)| [UNIQUE] INDEX [index_name] (index_col_name,...)| FULLTEXT [INDEX] [index_name] index_col_name,...)| FOREIGN KEY [index_name] (index_col_name,...) [reference_definition]
II.5.3.1. create_definition II.5.3.1. create_definition (2)(2)II.5.3.1.1. typeII.5.3.1.2. reference_definition
II.5.3.1.1. typeII.5.3.1.1. type
TINYINT, SMALLINT, MEDIUMINT, INT, INTEGER, BIGINT[(length)] [UNSIGNED] [ZEROFILL]
REAL[(length,decimals)], DOUBLE[(length,decimals)], FLOAT[(length,decimals)], DECIMAL(length,decimals), NUMERIC(length,decimals) [UNSIGNED] [ZEROFILL]
CHAR(length) [BINARY | ASCII | UNICODE], VARCHAR(length) [BINARY]
DATE, TIME, TIMESTAMP, DATETIMETINYBLOB, BLOB, MEDIUMBLOB, LONGBLOBTINYTEXT, TEXT, MEDIUMTEXT, LONGTEXTENUM(value1,value2,value3,...), SET(value1,value2,value3,...)
II.5.3.1.2. II.5.3.1.2. reference_definitionreference_definition
REFERENCES tbl_name [(index_col_name,...)] [MATCH FULL | MATCH PARTIAL] [ON DELETE RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT] [ON UPDATE RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT]
Ví dụ:CREATE TABLE lop2 ( id INT AUTO_INCREMENT PRIMARY KEY NOT NULL, tenlop VARCHAR(20));
CREATE TABLE sv2 ( id INT AUTO_INCREMENT PRIMARY KEY NOT NULL, hoten VARCHAR(30), lop INT NOT NULL, FOREIGN KEY (lop) REFERENCES lop(id));
II.5.3.2. table_optionII.5.3.2. table_option
TYPE = {BDB | HEAP | ISAM | InnoDB | MERGE | MRG_MYISAM | MYISAM }
Table type Description
BDB or BerkeleyDB Transaction-safe tables with page locking
HEAP The data for this table is only stored in memory.
ISAM The original storage engine
InnoDB Transaction-safe tables with row locking
MERGE A collection of MyISAM tables used as one table.
MRG_MyISAM An alias for MERGE.
MyISAM The new binary portable storage engine that is the replacement for ISAM.
II.5.4. ALTER TABLEII.5.4. ALTER TABLE
ALTER [IGNORE] TABLE tbl_name alter_specification, ...alter_specification: ADD [COLUMN] create_def [FIRST | AFTER column_name ] | ADD [COLUMN] (create_def, create_def,...) | ADD INDEX [index_name] (index_col_name,...) | ADD PRIMARY KEY (index_col_name,...) | ADD FOREIGN KEY (index_col_name,...)[reference_def] | ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT} | CHANGE [COLUMN] old_col_name create_def [FIRST | AFTER column_name] | MODIFY [COLUMN] create_def [FIRST | AFTER column_name] | DROP [COLUMN] col_name | DROP PRIMARY KEY | DROP INDEX index_name | RENAME [TO] new_tbl_name | ORDER BY col
II.5.4. ALTER TABLE (2)II.5.4. ALTER TABLE (2)
ALTER TABLE dùng để sửa đổi cấu trúc của bảng (thêm cột, xóa cột, sửa kiểu, tên cột, sửa tên bảng, tạo, xóa index...)
ALTER TABLE làm việc như sau:◦ Tạo một bảng theo cấu trúc mới◦ Copy dữ liệu từ bảng cũ sang bảng mới◦ Xóa bảng cũ và đổi tên bảng mới
Trong quá trình copy dữ liệu từ bảng cũ sang bảng mới có thể phát sinh lỗi (cấu trúc của bảng cũ không chuyển được sang bảng mới), có thể sử dụng từ khóa IGNORE để bỏ qua các lỗi phát sinh (nếu không chương trình sẽ dừng ngay khi gặp lỗi đầu tiên)
II.5.4. ALTER TABLE (3)II.5.4. ALTER TABLE (3)
CREATE TABLE sinhvien(id INT, hodem VARCHAR(20), lop INT);
ALTER TABLE sinhvien MODIFY id BIGINT PRIMARY KEY AUTO_INCREMENT, ADD ten VARCHAR(15);
ALTER TABLE sinhvien CHANGE id maso BIGINT NOT NULL AUTO_INCREMENT;
ALTER TABLE sinhvien RENAME danhsachsinhvien;ALTER TABLE danhsachsinhvien RENAME svien, MODIFY maso BIGINT, DROP PRIMARY KEY;
II.5.6. DROP TABLEII.5.6. DROP TABLE
DROP [TEMPORARY] TABLE [IF EXISTS] tbl_name [, tbl_name,...] [RESTRICT | CASCADE]
II.6. ViewII.6. View
View là tính năng mới và rất được mong chờ của MySQL, được đưa vào từ phiên bản 5.0
View là khái niệm chỉ các khung nhìn về 1 bảng hoặc nhiều bảng khác nhau
Khái niệm View có thể coi là bảng ảo, những bảng này thực chất là sự trích dẫn dữ liệu từ 1 hoặc nhiều bảng khác
Với View, bạn có thể lập trình SQL đơn giản hơn, tránh được việc phải viết các lệnh SQL lồng nhau nên dễ dàng chia nhỏ công việc và gỡ rối
CREATE [OR REPLACE] VIEW view_name [(column_list)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
II.6. View (2)II.6. View (2)
# vLop: Xem thong tin ve LopCREATE VIEW viewLop AS
SELECT tblSinhVien.*, tblLop.l_Ten, tblLop.l_Khoa, (sv_Toan+sv_Ly+sv_Hoa)/3 AS sv_TrungBinh
FROM tblSinhVien JOIN tblLopON tblLop.l_ID = tblSinhVien.sv_LopORDER BY sv_Lop;
SELECT * FROM viewLop;
# vKhoa: Xem thong ten ve KhoaCREATE VIEW viewKhoa AS
SELECT viewLop.*, tblKhoa.k_TenFROM viewLop JOIN tblKhoaON viewLop.l_Khoa = tblKhoa.k_IDORDER BY l_Khoa;
SELECT * FROM viewKhoa;
II.6. View (3)II.6. View (3)
Trong view không được sử dụng biến người dùng định nghĩa
Trong view không được dùng SUBQUERY ở mệnh đề FROM
Tùy theo tính chất của câu lệnh SELECT, View có thể là chỉ đọc hoặc cập nhật được
Mệnh đề WITH CHECK OPTION dùng với View cập nhật được, để bắt buộc việc thêm hoặc chỉnh sửa phải đảm bảo yêu cầu trong mệnh đề WHERE của câu lệnh SELECT
II.6. View (4)II.6. View (4)
CREATE TABLE t (qty INT, price INT);
INSERT INTO t VALUES(3, 50);
CREATE VIEW v AS
SELECT qty, price, qty*price AS value FROM t;
SELECT * FROM v;
II.6. View (5)II.6. View (5)CREATE TABLE t1 (a INT);
CREATE VIEW v1 AS SELECT * FROM t1 WHERE a < 2
WITH CHECK OPTION;
CREATE VIEW v2 AS SELECT * FROM v1 WHERE a > 0
WITH LOCAL CHECK OPTION;
CREATE VIEW v3 AS SELECT * FROM v1 WHERE a > 0
WITH CASCADED CHECK OPTION;
INSERT INTO v2 VALUES (2);
INSERT INTO v3 VALUES (2);
II.7. Store ProcedureII.7. Store Procedure
Store Procedure cũng là một chức năng mới trong phiên bản MySQL5.0
Store Procedure cho phép tập hợp nhiều câu lệnh SQL trong 1 chương trình con. Giống như các ngôn ngữ khác, Store Procedure cũng cho phép truyền tham số
II.7.1. Khai báo Store procedureII.7.2. Gọi hàmII.7.3. Sử dụng biếnII.7.4. Các câu lệnh điều khiển
II.7.1. Khai báo Store II.7.1. Khai báo Store ProcedureProcedure
CREATE PROCEDURE sp_name ([parameter[,...]]) routine_body
CREATE FUNCTION sp_name ([parameter[,...]]) RETURNS type routine_body
parameter: [ IN | OUT | INOUT ] param_name typetype: Any valid MySQL data type
routine_body: Valid SQL procedure statements or statements
II.7.1. Khai báo Store II.7.1. Khai báo Store ProcedureProcedure
DELIMITER $$;CREATE PROCEDURE countSV()BEGIN SELECT count(*) FROM tblSinhVien;END$$
CREATE PROCEDURE showSVLop(tenlop VARCHAR(50))BEGIN SELECT l_Ten, tblSinhVien.* FROM tblSinhVien, tblLop WHERE sv_Lop = l_ID AND l_Ten = tenlop;END$$DELIMITER ;$$
II.7.1. Khai báo FunctionII.7.1. Khai báo Function
DELIMITER $$;CREATE FUNCTION TrungBinh(d1 FLOAT, d2 FLOAT, d3 FLOAT) RETURNS FLOATBEGIN RETURN IFNULL(d1,0)+IFNULL(d2,0)+IFNULL(d3,0)) / !ISNULL(d1) + !ISNULL(d2) + !ISNULL(d3));END$$DELIMITER ;$$
II.7.2. Gọi hàmII.7.2. Gọi hàmCALL sp_name([parameter[,...]])
Ví dụCALL countSV();CALL showSVLop("47PM1");
SELECT TrungBinh(d_Toan, d_Ly, d_Hoa)
FROM tblDiem;
II.7.3. Sử dụng biếnII.7.3. Sử dụng biến
Khai báo biến◦DECLARE var_name[,...] type [DEFAULT value]
Gán giá trị◦SET var_name = expr [, var_name = expr]
SELECT INTO◦SELECT col_name[,...] INTO var_name[,...] table_expr
II.7.3. Sử dụng biếnII.7.3. Sử dụng biến
DELIMITER $$;DROP PROCEDURE IF EXISTS incScore$$CREATE PROCEDURE incScore(id INT, score INT)BEGIN DECLARE c INT; SELECT COUNT(*) INTO c FROM tblScore WHERE sc_ID=id; IF c=1 THEN UPDATE tblScore SET sc_Score=sc_Score+score WHERE
sc_ID=id; ELSE INSERT INTO tblScore VALUES (id, score); END IF;END$$DELIMITER ;$$
II.7.4. Cấu trúc điều kiểnII.7.4. Cấu trúc điều kiển
Các cấu trúc được hỗ trợ: IF, CASE, LOOP, WHILE, ITERATE, LEAVE
IF search_condition THEN statement_list
[ELSEIF search_condition THEN statement_list]...
[ELSE statement_list]
END IF
II.7.4. Cấu trúc điều khiển II.7.4. Cấu trúc điều khiển (2)(2)
CASE case_value WHEN when_value THEN statement_list [WHEN when_value THEN statement_list ...] [ELSE statement_list]END CASE
[begin_label:] LOOP statement_list [LEAVE label] [ITERATE label]END LOOP [end_label]
II.7.4. Cấu trúc điều khiển II.7.4. Cấu trúc điều khiển (3)(3)
[begin_label:] REPEAT
statement_list
UNTIL search_condition
END REPEAT [end_label]
[begin_label:] WHILE search_condition DO
statement_list
END WHILE [end_label]
II.7.4. Cấu trúc điều khiển II.7.4. Cấu trúc điều khiển (4)(4)
delimiter $$CREATE PROCEDURE dorepeat(p1 INT)BEGIN SET @x = 0; REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;END$$
CREATE PROCEDURE dowhile()BEGIN DECLARE v1 INT DEFAULT 5; WHILE v1 > 0 DO ... SET v1 = v1 - 1; END WHILE;END$$
II.8. TriggerII.8. Trigger
Trigger là một đối tượng liên kết với bảng (table), được kích hoạt khi có những sự kiện (thêm, xóa, sửa...) xảy ra trong bảng
II.8.1. Tạo triggerII.8.2. Sử dụng trigger
II.8.1. Tạo TriggerII.8.1. Tạo Trigger
CREATE TRIGGER trigger_name [BEFORE | AFTER] trigger_eventON tbl_name FOR EACH ROW trigger_stmt
trigger_event:
Xác định loại sự kiện (INSERT, UPDATE, DELETE)
trigger_stmt:
Các lệnh được gọi khi trigger bị kích hoạt, để sử dụng nhiều lệnh, dùng cấu trúc BEGIN...END giống như STORE PROCEDURE
II.8.2. Sử dụng TriggerII.8.2. Sử dụng Trigger
CREATE TABLE sv(id INT, ten VARCHAR(10), diem INT);CREATE TABLE record(id INT, diemcu INT, diemmoi INT);
INSERT sv VALUES (1, "Quang", 5), (2, "Quang2", 8);
CREATE TRIGGER onUpdateSV AFTER UPDATEON sv FOR EACH ROW INSERT INTO record VALUES (NEW.id, OLD.diem, NEW.diem);
UPDATE sv SET diem=9 WHERE id=1;
II.8.2. Sử dụng TriggerII.8.2. Sử dụng Trigger
Khi các Trigger được kích hoạt, để lấy các giá trị của bảng trước và sau khi sự kiện xảy ra, MySQL sử dụng các từ khóa OLD, NEW◦OLD: đại diện cho dòng bị DELETE hay dòng
trước khi UPDATE◦NEW: đại diện cho dòng được INSERT vào hay
dòng sau khi UPDATE◦Dữ liệu trong dòng OLD là readonly◦Dữ liệu trong dòng NEW có thể chỉnh sửa (sử
dụng để kiểm tra dữ liệu trong các câu lệnh INSERT và UPDATE với sự kiện loại BEFORE)
II.9. Các dạng bảng của II.9. Các dạng bảng của MySQLMySQLII.9.1. Dạng MyISAMII.9.2. Dạng HEAPII.9.3. Dạng InnoDB
II.9. Các dạng bảng của II.9. Các dạng bảng của MySQL (2)MySQL (2)
Khi tạo bảng bằng lệnh CREATE TABLE bạn có thể lựa chọn dạng bảng (mặc định là dạng MyISAM)
Bảng được tạo ra luôn có file .frm để lưu khuôn dạng, chỉ số và dữ liệu được lưu ở 1 hoặc nhiều file tùy theo dạng bảng mà bạn lựa chọn
Bạn không thể sử dụng lệnh ALTER TABLE để đổi kiểu bảng MySQL hỗ trợ cả 2 dạng bảng
◦ Transaction safe: InnoDB, BDB◦ Not Transaction safe: HEAP, ISAM, MyISAM
Các ưu điểm của dạng Transaction safe◦ An toàn hơn: Ngay cả khi MySQL bị ngắt đột ngột (do lỗi phần mềm hoặc
phần cứng) bạn vẫn có thể khôi phục lại dữ liệu bằng chức năng tự động khôi phục hoặc từ transaction log
◦ Có thể kết hợp 1 dãy các lệnh sau đó thực hiện cùng một lúc bằng lệnh COMMIT
◦ Có thể dùng lệnh ROLLBACK để bỏ qua các thay đổi◦ Nếu việc cập nhật không thành công, dữ liệu sẽ được khôi phục lại ở
trạng thái gần nhất
II.9.1. Dạng MyISAMII.9.1. Dạng MyISAM
MyISAM là dạng bảng mặc định của MySQLFile MYI lưu index, file MYD lưu dữ liệuCác đặc tính của MyISAM
◦ Có thể đọc dữ liệu từ bảng ngay khi có 1 tiến trình đang INSERT
◦ Hỗ trợ file kích thước lớn đến 63 bit◦ Kiểu BLOB và TEXT có thể sử dụng làm khóa
Các vấn đề có thể gặp phải◦ Bảng có thể bị lỗi khi MySQL bị hủy trong khi đang tiến
hành ghi dữ liệu (bao gồm cả lỗi phần mềm, tác động của người dùng hay lỗi phần cứng)
II.9.1. Dạng MyISAM (2)II.9.1. Dạng MyISAM (2)
Các dạng bảng MyISAM Dạng tĩnh (static)
◦ Tất cả các dòng có kích thước bằng nhau (không chứa VARCHAR, BLOB, TEXT)
◦ Tốc độ tìm bản ghi (nhất là trên ổ cứng) cao◦ Dễ phục hồi nếu bị hỏng◦ Tốn ổ cứng
Dạng động (dynamic)◦ Kích thước các dòng không cố định (do đó phải có phần header để thông
báo kích thước mà dòng sử dụng)◦ Sử dụng ít ổ cứng hơn so với kiểu tĩnh◦ Mỗi dòng chỉ sử dụng kích thước tối thiểu mà nó cần khi tạo, nếu mở
rộng, nó sẽ được chia thành nhiều đoạn (tạo ra hiện tượng phân mảnh, để chống phân mảnh sử dụng myisamchk.exe –r)
◦ Để xem thông tin về bảng: myisamchk.exe -ei Dạng nén (compressed)
◦ Dạng bảng chỉ đọc, dùng để lưu trữ thông tin◦ Để nén bảng, sử dụng tiện ích myisampack
II.9.2. Dạng HEAPII.9.2. Dạng HEAPBảng dạng HEAP được lưu trên bộ nhớ, do đó
tốc độ nhanh và thích hợp với các bảng tạmMột số đặc tính của bảng HEAP
◦ Index chỉ được dùng với =, <=> (nhưng rất nhanh)◦ Kích thước của record là cố định◦ Không hỗ trợ kiểu BLOB và TEXT◦ Không hỗ trợ cột AUTO_INCREMENT◦ Để giải phóng bộ nhớ, có thể sử dụng các lệnh
DELETE, TRUNCATE, hay DROP TABLE
II.9.3. Dạng InnoDBII.9.3. Dạng InnoDB
InnoDB là dạng bảng transaction safe với các khả năng COMMIT, ROLLBACK, và phục hồi (cash recovery)
InnoDB là dạng bảng đầu tiên của MySQL hỗ trợ FOREIGN KEY
InnoDB được thiết kế để làm việc tốt trên các bảng có kích thước lớn và có nhiều truy cập cùng một lúc (ví dụ: Slashdot.org: bảng InnoDB có kích thước > 1TB, trung bình 800 lượt insert/update trong 1 giây)
Khác với MyISAM, InnoDB có thể lưu khóa và dữ liệu trên nhiều file khác nhau, thậm chí là trên các Partition riêng
II.10. Làm việc với transaction & II.10. Làm việc với transaction & Locking commandLocking commandII.10.1. START TRANSACTION, COMMIT,
ROLLBACKII.10.2. SAVE POINT, ROLLBACK TO SAVEPOINTII.10.3. LOCK TABLES & UNLOCK TABLES
II.10.1. START TRANSACTION, II.10.1. START TRANSACTION, COMMIT, ROLLBACKCOMMIT, ROLLBACK
MySQL mặc định ở chế độ autocommit (tức là các chỉnh sửa của bạn ngay lập tức được lưu lại trong ổ đĩa)
Nếu sử dụng các bảng transaction-safe (InnoDB, BDB), bạn có thể bỏ chế độ autocommit bằng lệnh◦ SET AUTOCOMMIT = 0◦ Sau đó bạn có thể sử dụng các lệnh
COMMIT để lưu lại các thay đổi trên ổ đĩa ROLLBACK để hủy bỏ các thay đổi
Nếu bỏ autocommit chỉ trong một nhóm các lệnh, bạn có thể sử dụng cú pháp START TRÂNSACTIONSTART TRANSACTION;SELECT @A:=SUM(salary) FROM table1 WHERE type=1;UPDATE table2 SET summmary=@A WHERE type=1;COMMIT;
Một số lệnh liên quan đến khuôn dạng dữ liệu không thể ROLLBACK (CREATE, DROP DATABASE, CREATE, DROP, ALTER TABLE)
II.10.2. SAVE POINT, ROLLBACK TO II.10.2. SAVE POINT, ROLLBACK TO SAVEPOINTSAVEPOINT
Các bảng InnoDB cho phép bạn sử dụng các lệnh: SAVE POINT, ROLLBACK TO SAVEPOINTSAVEPOINT identifierROLLBACK TO SAVEPOINT identifier
II.10.3. LOCK TABLES & UNLOCK II.10.3. LOCK TABLES & UNLOCK TABLESTABLES
LOCK TABLES
tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}
[,tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}]...
UNLOCK TABLES
LOCK TABLES trans READ, customer WRITE;
SELECT SUM(value) FROM trans WHERE customer_id=some_id;
UPDATE customer
SET total_value=sum_from_previous_statement
WHERE customer_id=some_id;
UNLOCK TABLES;
II.10.3. LOCK TABLES & UNLOCK II.10.3. LOCK TABLES & UNLOCK TABLES (2)TABLES (2)Lock tables dùng để đảm bảo không có sự
xung đột dữ liệu khi INSERT, UPDATE, DELETE
Nếu một tiến trình sử dụng lock READ, thì tất cả các tiến trình còn lại chỉ được phép đọc dữ liệu trên bảng
Nếu một tiến trình sử dụng lock WRITE thì chỉ có tiến trình đó được write vào bảng
Lệnh UNLOCK TABLES sử dụng để kết thúc quá trình LOCK.
III.Tối ưu hóa MySQLIII.Tối ưu hóa MySQL
III.1. Những vấn đề chungIII.2. Tối ưu hóa câu lệnh SELECTIII.3. Tối ưu hóa cấu trúc CSDLIII.4. Cấu hình MySQL
III.1. Những vấn đề chungIII.1. Những vấn đề chungTốc độ truy cập ổ cứng
◦Tốc độ truy cập trên các ổ cứng hiện tại là 10ms (100 truy cập trong 1 giây)
◦Để cải tiến tốc độ của bảng trên yếu tố này là rất khó, trừ phi đặt dữ liệu trên nhiều ổ cứng
Tốc độ đọc và ghi trên ổ cứng
III.2. Tối ưu hóa câu lệnh III.2. Tối ưu hóa câu lệnh SELECTSELECT
Một số lưu ý◦ Hệ thống quyền càng phức tạp thì chi phí thời gian càng
cao◦ Để nắm được thời gian thực hiện của 1 hàm, có thể sử
dụng lệnh BENCHMARKmysql> SELECT BENCHMARK(1000000,1+1);+------------------------+| BENCHMARK(1000000,1+1) |+------------------------+| 0 |+------------------------+1 row in set (0.32 sec)
III.2. Tối ưu hóa câu lệnh SELECT III.2. Tối ưu hóa câu lệnh SELECT (2)(2)
III.2.1. Sử dụng EXPLAINIII.2.2. Phương pháp tối ưu hóa
mệnh đề WHERE của MySQLIII.2.3. Phương pháp tối ưu hóa
LEFT JOIN và RIGHT JOIN
III.2.1. Sử dụng EXPLAINIII.2.1. Sử dụng EXPLAIN
EXPLAIN SELECT select_options MySQL sẽ đưa ra cách thức mà nó thực hiện câu lệnh SELECT
(các bảng được JOIN như thế nào? Theo thứ tự nào? – nhớ rằng MySQL sẽ tự động tìm ra thứ tự JOIN các bảng sao cho thích hợp nhất)
Bằng cách quan sát các thông tin trên, bạn sẽ biết phải thêm các Index nào vào bảng để tăng tốc độ Query
Đối với câu lệnh có JOIN, các bảng có liên quan sẽ được liệt kê theo thứ tự mà MySQL sẽ đọc khi thực hiện lệnh SELECT
MySQL thực hiện câu lệnh JOIN theo các bước sau◦ Đọc dòng đầu trong bảng đầu tiên◦ Tìm các dòng thỏa mãn điều kiện trong bảng thứ 2, 3...◦ Khi tất cả các bảng đã được xử lý, chọn các cột từ bảng cuối cùng◦ Sau đó tìm bảng theo thứ tự ngược lại đến khi có nhiều hơn 1 dòng
kết quả. Dòng tiếp theo sẽ được tính từ bảng này và lại tiếp tục với bảng tiếp theo
III.2.1. Sử dụng EXPLAIN III.2.1. Sử dụng EXPLAIN (2)(2)
Lệnh EXPLAIN cung cấp các thông tin sau◦select_type, table, type, possible_keys,◦select_type
SIMPLE: không sử dụng UNION PRIMARY: select đầu tiên trong câu lệnh UNION UNION: các select tiếp theo DEPENTDENT UNION: các select tiếp theo trong câu
lệnh UNION phụ thuộc vào select ngoài SUBQUERY: select đầu tiên trong subquery DEPENDENT SUBQUERY: select đầu tiên phụ thuộc vào
câu lệnh select ngoài DERIVED: câu lệnh select đặt ở mệnh đề FROM
III.2.1. Sử dụng EXPLAIN III.2.1. Sử dụng EXPLAIN (3)(3)
type system: bảng chỉ có 1 dòng const: bảng có nhiều nhất 1 dòng phù hợp, được đọc đầu tiên.
Được sử dụng khi so sánh tất cả các PRIMARY/UNIQUE với một hằng sốSELECT * FROM const_table WHERE primary_key=1;SELECT * FROM const_tableWHERE primary_key_part1=1 AND primary_key_part2=2;
eq-ref: từng dòng của bảng này sẽ được đọc để kết hợp với bảng đứng trước. Được sử dụng khi tất cả các index có mặt trong phép so sánh với toán tử = SELECT * FROM ref_table,other_tableWHERE ref_table.key_column=other_table.column;
SELECT * FROM ref_table,other_tableWHERE ref_table.key_column_part1=other_table.columnAND ref_table.key_column_part2=1;
III.2.1. Sử dụng EXPLAIN III.2.1. Sử dụng EXPLAIN (4)(4)
type:ref: Tất cả các dòng phù hợp của bảng được đọc để
kết hợp với dòng hiện tại của bảng trước. Được sử dụng khi biểu thức so sánh có ít nhất 1 index của bảng ref (kết quả cho ra hơn 1 dòng phù hợp)SELECT * FROM ref_table WHERE key_column=expr;SELECT * FROM ref_table,other_tableWHERE ref_table.key_column=other_table.column;
SELECT * FROM ref_table,other_tableWHERE ref_table.key_column_part1=other_table.columnAND ref_table.key_column_part2=1;
ref_or_null: Giống ref nhưng mở rộng thêm điều kiện tìm kiếm IS NULL
III.2.1. Sử dụng EXPLAIN III.2.1. Sử dụng EXPLAIN (5)(5)
type: range: Các dòng của bảng được chọn trong 1 khoảng của index
SELECT * FROM range_table WHERE key_column = 10;SELECT * FROM range_table WHERE key_column BETWEEN 10 and 20;SELECT * FROM range_table WHERE key_column IN (10,20,30);SELECT * FROM range_table WHERE key_part1= 10 and key_part2 IN (10,20,30);
index: Giống ALL, ngoài việc cây index được sử dụng nên tốc độ sẽ nhanh hơn. Được sử dụng khi chỉ liệt kê trường index của bảng.
ALL: Cả bảng sẽ được sử dụng để kết hợp với bảng đứng trước. Trừ phi là bảng đầu tiên, trong tất cả các trường hợp còn lại đều không tốt (nên tránh bằng cách sử dụng các trường index)
III.2.1. Sử dụng EXPLAIN III.2.1. Sử dụng EXPLAIN (6)(6)
possible_key◦ Chỉ ra các index có thể được sử dụng. Tuy nhiên, nếu thứ tự
các bảng bị thay đổi trong quá trình tối ưu hóa thì có thể index này sẽ không có ích nữa.
key◦ Chỉ ra các index thực sự được sử dụng
key_length◦ Độ dài của khóa được sử dụng
ref◦ Cột hoặc hằng được sử dụng để chọn các dòng trong bảng
rows◦ Số dòng MySQL phải kiểm tra để thực hiện câu lệnh
III.2.1. Sử dụng EXPLAIN III.2.1. Sử dụng EXPLAIN (7)(7)
extra◦ Distinct: Chỉ tìm 1 kết quả thích hợp◦ Not exists: Sử dụng trong phép kết nối LEFT JOIN, khi chọn các
dòng của bảng bên trái không phù hợp với tất cả các dòng của bảng bên phải
◦ Using file sort: Phải thực hiên thêm 1 bước: duyệt qua cả bảng, lưu lại khóa sắp xếp và con trỏ đến dòng tương ứng. Sau đó mới tiến hành JOIN như bình thường
◦ Using index: ◦ Using temporary: ◦ Using where: Mệnh đề WHERE được sử dụng để giới hạn số
lượng các dòng. Nếu bảng của bạn có type=ALL và ko sử dụng mệnh đề WHERE cũng như index thì tất cả các dòng sẽ được liệt kê ra
III.2.2. Phương pháp tối ưu hóa III.2.2. Phương pháp tối ưu hóa mệnh đề WHERE của MySQLmệnh đề WHERE của MySQL
WHERE là mệnh đề được sử dụng nhiều nhất, ko chỉ ở câu lệnh SELECT mà còn trong các lệnh UPDATE & DELETE
Một số các tối ưu thường gặp ở mệnh đề WHERE◦ Bỏ các ngoặc không cần thiết((a AND b) AND c OR (((a AND b) AND (c AND d))))
-> (a AND b AND c) OR (a AND b AND c AND d)
◦ Chuyển các phép so sánh các cột thành hằng (nếu được)(a<b AND b=c) AND a=5
-> b>5 AND b=c AND a=5
◦ Loại bỏ các điều kiện dư thừa(B>=5 AND B=5) OR (B=6 AND 5=5) OR (B=7 AND 5=6)
-> B=5 OR B=6
III.2.2. Phương pháp tối ưu hóa III.2.2. Phương pháp tối ưu hóa mệnh đề WHERE của MySQL (2)mệnh đề WHERE của MySQL (2)
◦Các bảng hằng được đọc trước, bảng hằng là: Bảng rỗng hoặc có 1 dòng Các bảng sử dụng mệnh để WHERE trên
index, key SELECT * FROM t WHERE primary_key=1;
SELECT * FROM t1,t2
WHERE t1.primary_key=1 AND t2.primary_key=t1.id;
III.2.2. Phương pháp tối ưu hóa III.2.2. Phương pháp tối ưu hóa mệnh đề WHERE của MySQL (3)mệnh đề WHERE của MySQL (3)
Các lệnh chạy rất nhanhSELECT COUNT(*) FROM tbl_name;
SELECT MIN(key_part1),MAX(key_part1)
FROM tbl_name;
SELECT MAX(key_part2) FROM tbl_name WHERE key_part1=constant;
SELECT ... FROM tbl_name ORDER BY key_part1,key_part2,... LIMIT 10;
SELECT ... FROM tbl_name ORDER BY key_part1 DESC, key_part2 DESC, ... LIMIT 10;
III.2.3. Phương pháp tối ưu hóa III.2.3. Phương pháp tối ưu hóa LEFT JOINLEFT JOIN
A LEFT JOIN B join_condition◦ Bảng B phụ thuộc vào bảng A và các bảng khác mà A phụ
thuộc◦ Bảng A phụ thuộc vào tất cả các bảng có mặt trong
join_condition (trừ B)◦ join_condition được sử dụng để chọn ra các dòng trên B (ko sử
dụng điều kiện WHERE)◦ Quá trình tối ưu hóa join kết thúc khi các bảng được sắp xếp
theo thứ tự (bảng đọc trước ko phụ thuộc vào bảng sau)◦ Tối ưu hóa mệnh đề WHERE◦ Nếu 1 dòng được tìm thấy trên bảng A (trong mệnh đề WHERE)
nhưng ko có dòng phù hợp trên bảng B, các trường tương ứng trên bảng B được gán giá trị NULL cho dòng này
III.3. Tối ưu hóa cấu trúc III.3. Tối ưu hóa cấu trúc CSDLCSDLIII.3.1. Một số lưu ýIII.3.2. MySQL sử dụng Index như
thế nào?
III.3.1. Một số lưu ýIII.3.1. Một số lưu ý
MySQL được thiết kế với index và dữ liệu đặt ở 2 file khác nhau (trong khi nhiều CSDL lại đặt trong cùng 1 file)
Thiết kế CSDL càng nhỏ càng tốt (MySQL cung cấp cho bạn nhiều loại bảng, cột – lựa chọn chính xác sẽ giúp CSDL có tốc độ cao hơn)◦ Chọn kiểu cột nhỏ nhất có thể (ví dụ MEDIUMINT<INT)◦ Sử dụng NOT NULL nếu có thể, sẽ tiết kiệm 1 bit cho 1 cột
(tránh để cả bảng là NULL)◦ Nếu ko sử dụng các kiểu có kích thước thay đổi (VARCHAR,
BLOB, TEXT) thì kích thước dòng là ko đổi nên tốc độ nhanh hơn nhưng bạn lại chiếm dụng không gian lớn hơn.
◦ Khóa chính càng nhỏ càng tốt◦ Chỉ tạo các index cần thiết
III.3.2. MySQL sử dụng Index như III.3.2. MySQL sử dụng Index như thế nào?thế nào?
Sử dụng index cho phép bạn tìm kiếm bản ghi nhanh hơn (bảng càng lớn thì hiệu quả càng cao)
Tất cả các index (PRIMARY KEY, UNIQUE, INDEX) đều được lưu trên B-tree
Sử dụng Index cho hiệu quả trong các trường hợp sau◦ Tìm kiếm dòng bằng mệnh đề WHERE◦ Kết nối các bảng thông qua index◦ Tìm giá trị lớn nhất, nhỏ nhất◦ Sắp xếp trên index
Chú ý, khi Index của bạn là nhiều cột, tùy thuộc vào thứ tự các cột trong index mà có thể tận dụng index hay không
III.3.2. MySQL sử dụng Index như III.3.2. MySQL sử dụng Index như thế nào? (2)thế nào? (2)
CREATE TABLE test ( id INT NOT NULL, last_name CHAR(30) NOT NULL, first_name CHAR(30) NOT NULL, PRIMARY KEY (id), INDEX name (last_name,first_name));
SELECT * FROM test WHERE last_name="Widenius";SELECT * FROM test WHERE last_name="Widenius" AND first_name="Michael";SELECT * FROM test WHERE last_name="Widenius" AND (first_name="Michael" OR first_name="Monty");SELECT * FROM test WHERE last_name="Widenius" AND first_name >="M" AND first_name < "N";SELECT * FROM test WHERE first_name="Michael";SELECT * FROM test WHERE last_name="Widenius" OR first_name="Michael";
III.3.3. Đóng, mở các bảng
III.3.3. Đóng, mở các bảngIII.3.3. Đóng, mở các bảng
Để biết có bao nhiêu bảng được mở, sử dụng lệnh mysqladmin status, ví dụ trả về:◦ Uptime: 426 Running threads: 1 Questions: 11082 Reloads: 1 Open tables:
12 Hoặc sử dụng lệnh SHOW STATUS Các biến table_cache, max_connections, max_tmp_tables sử dụng để
giới hạn số bảng, connection tối đa Ngoài ra, phải đảm bảo số lượng file table_cache có thể mở được đối
với hệ điều hành của máy chủ Các bảng tạm được đóng nếu
◦ Cache đầy và tiến trình tiếp tục mở 1 bảng ko có trong cache◦ Cache vượt quá table_cache và tiến trình ko sử dụng bảng nằm trong cache
nữa◦ Khi có người gọi mysqladmin refresh, hoặc mysqladmin flush-tables◦ Khi có người sử dụng lệnh FLUSH TABLES
Bạn có thể tự mở và đóng bảng với cú pháp HANDLER◦ HANDLER table_name OPEN◦ HANDLER table_name CLOSE
III.4. Quản trị MySQLIII.4. Quản trị MySQL
III.4.1. Cấu hình MySQLIII.4.2. Bảo mật và hệ thống quyền
truy nhập của MySQLIII.4.3. Quản lý tài khoản người
dùngIII.4.4. Các lệnh quản trị MySQL
III.5.1. Cấu hình MySQLIII.5.1. Cấu hình MySQLmysqld: các tham số
o --ansi: Sử dụng cú pháp SQL chuẩno -b path: Đường dẫn đến nơi cài đặt MySQL, đây là
đường dẫn cơ sở cho các đường dẫn kháco -h path: Đường dẫn đến nơi chứa CSDLo --ini-file file: Thực hiện các lệnh từ file khi khởi động
MySQLo -l file: log ra fileo --log-query-not-using-indexeso --log-slow-querieso -P port: cổng kết nối (TCP/IP)o -u username|userid:
III.5.1. Cấu hình MySQL (2)III.5.1. Cấu hình MySQL (2)
File cấu hình my.ini
[mysqld]port=3306basedir="C:/Program Files/MySQL/MySQL Server 4.1/"datadir="C:/Program Files/MySQL/MySQL Server 4.1/Data/"default-character-set=latin1default-storage-engine=INNODB
III.5.2. Bảo mật và hệ thống quyền III.5.2. Bảo mật và hệ thống quyền truy nhập của MySQLtruy nhập của MySQLMột số lưu ý chungKhông cho phép người dùng nào (trừ root) có
quyền truy cập bảng userKhông bao giờ để password root là trắngHọc cách quản lý phân quyền bằng lệnh
GRANT & REVOKEKhông lưu PASSWORD dưới dạng text mà ko
mã hóa (bạn có thể sử dụng các hàm MD5, SHA1) để mã hóa password
III.5.3. Quản lý tài khoản người III.5.3. Quản lý tài khoản người dùngdùng
III.5.3.1. Lệnh GRANT & REVOKEIII.5.3.2. Tài khoản & mật khẩuIII.5.3.3. Thêm, xóa người dùngIII.5.3.4. Giới hạn tài nguyên người
dùngIII.5.3.5. Thiết lập & duy trì mật
khẩu
III.5.3.1. Lệnh GRANT & III.5.3.1. Lệnh GRANT & REVOKEREVOKE
GRANT priv_type [(column_list)] [,...] ON {tbl_name | * | *.* | db_name.*} TO user_name [IDENTIFIED BY 'password'] [,..] [WITH [GRANT OPTION | MAX_QUERIES_PER_HOUR # | MAX_UPDATES_PER_HOUR # | MAX_CONNECTIONS_PER_HOUR #]]
REVOKE priv_type [(column_list)] [,...] ON {tbl_name | * | *.* | db_name.*} FROM user_name [,...]
REVOKE ALL PRIVILEGES,GRANT FROM user_name [,...];FLUSH PRIVILEGES;
III.5.3.1. Lệnh GRANT & REVOKE (2)III.5.3.1. Lệnh GRANT & REVOKE (2)
GRANT & REVOKE cho phép bạn tạo mới người dùng, cấp và hủy bỏ quyền của người dùng
Quyền trong MySQL được chia làm 4 level◦ Global level: Áp dụng cho tất cả các CSDL trên
server (GRANT/REVOKE ALL ON *.*)◦ Database level: Áp dụng tất cả các bảng trong 1
CSDL xác định (GRANT/REVOKE ALL ON db.*)◦ Table level: Áp dụng cho tất cả các cột trong 1 bảng
xác định (GRANT/REVOKE ALL ON db.table);◦ Column level: Áp dụng cho 1 cột xác định trong
bảng
III.5.3.1. Lệnh GRANT & REVOKE (3)III.5.3.1. Lệnh GRANT & REVOKE (3)
priv_type◦ALL [PRIVILEGES]: Tất cả các quyền (trừ WITH GRANT OPTION)
◦ALTER, CREATE, DELETE, DROP, EXECUTE, INDEX, INSERT, LOCK TABLES, SELECT, SHOW DATABASES, SUPER, UPDATE, USAGE, GRANT OPTION
III.5.3.2. Tài khoản & mật III.5.3.2. Tài khoản & mật khẩukhẩu Các tài khoản và mật khẩu của MySQL độc lập với tài
khoản và mật khẩu của Windows hay UNIX Tài khoản (username) trong MySQL dài tối đa 16 ký tự Mật khẩu trong MySQL được mã hóa bằng hàm
PASSWORD và giải mã bằng hàm ENCRYPT Tài khoản & mật khẩu người dùng trong MySQL được
tạo, cấp và rút quyền bằng lệnh GRANT & REVOKE Để đăng nhập vào MySQL khi đã có tài khoản và mật
khẩu, bạn có thể sử dụng 1 trong các cú pháp sau◦ mysql --user=monty --password=guess database_name◦ mysql -u monty -p database_name◦ mysql -u monty -pguess database_name
III.5.3.3. Thêm, xóa người III.5.3.3. Thêm, xóa người dùngdùng
Để thêm, xóa người dùng, bạn phải có quyền admin (thường là đăng nhập với tài khoản root)
Để thêm 1 người dùng, có thể sử dụng các cú pháp sauGRANT ALL PRIVILEGES ON *.* TO monty@localhost IDENTIFIED BY 'some_pass' WITH GRANT OPTION;GRANT ALL PRIVILEGES ON *.* TO monty@'%' IDENTIFIED BY 'some_pass' WITH GRANT OPTION;GRANT RELOAD,PROCESS ON *.* TO admin@localhost;GRANT USAGE ON *.* TO dummy@localhost;
Các lệnh trên tạo ra các người dùng sau:◦ monty: full superuser – có thể kết nối server từ bất kỳ nơi nào,
mật khẩu 'some_pass'◦ admin: người dùng có thể connect từ localhost, không cần
password, có 2 quyền là RELOAD & PROCESS ◦ dummy: người dùng có thể kết nối từ localhost, không cần
password nhưng chẳng có quyền gì
III.5.3.3. Thêm, xóa người III.5.3.3. Thêm, xóa người dùng (2)dùng (2)DROP USER user_name
◦Cho phép xóa người dùng ko quyềnĐể xóa người dùng, theo các
bước sau◦Dùng lệnh SHOW PRIVILEGES để xem
quyền của người dùng◦Xóa các quyền của người dùng với
lệnh REVOKE◦Xóa người dùng không quyền với
DROP USER
III.5.3.4. Giới hạn tài nguyên người III.5.3.4. Giới hạn tài nguyên người dùngdùngĐể đảm bảo an toàn, nên giới
hạn tài nguyên mà người dùng được phép sử dụng◦Số lượng query trong 1 giờ◦Số lượng update trong 1 giờ◦Số lượng connection được cấp trong
1 giờGRANT ... WITH MAX_QUERIES_PER_HOUR N1 MAX_UPDATES_PER_HOUR N2 MAX_CONNECTIONS_PER_HOUR N3;
III.5.3.5. Thiết lập & duy trì mật III.5.3.5. Thiết lập & duy trì mật khẩukhẩu
Mật khẩu người dùng được lưu trong bảng user dưới dạng mã hóa
Để thay đổi mật khẩu người dùng, bạn có thể sử dụng các cú pháp sauSET PASSWORD FOR jeffrey@"%" = PASSWORD('biscuit');
GRANT USAGE ON *.* TO jeffrey@"%" IDENTIFIED BY 'biscuit';
III.5.4. Các lệnh quản trị III.5.4. Các lệnh quản trị MySQLMySQLOPTIMIZE TABLEANALYZE TABLE
III.5.4.1. OPTIMIZE TABLEIII.5.4.1. OPTIMIZE TABLE
OPTIMIZE TABLE tbl_name [, tbl_name] ...
Giống Compact của Access hay Defragment của Windows
Xóa các khoảng trống hình thành do xóa dòng, thay đổi dữ liệu các trường VARCHAR, BLOB, TEXT
III.5.4.2. ANALYZE TABLEIII.5.4.2. ANALYZE TABLEANALYZE TABLE tbl_name [, tbl_name] ...
Tạo lại cây khóa cho bảng