PythonWeb全棧工程師必備技能之<MySQL開發篇>
(1)數據庫的CURD:
--基本使用:
1.選擇數據庫:
use 數據庫名稱;
mysql> use test;
Database changed
2.創建數據庫:
create database 數據庫名稱;
mysql> create database test;
Query OK, 1 row affected (0.07 sec)
3.刪除數據庫:
drop database 數據庫名稱;
mysql> drop database test;
Query OK, 0 rows affected (0.05 sec)
4.更新數據庫:
alter database 數據庫名稱 character set 字符集 collate 子句;
mysql> alter database test character set 'utf8';
Query OK, 1 row affected, 1 warning (0.10 sec)
5.創建數據表:
create table 數據表名稱(...) engine=數據庫引擎名稱;
mysql> create table t1(
-> name varchar(255),
-> age int) engine=InnoDB;
Query OK, 0 rows affected (0.09 sec)
6.創建臨時數據表:
服務器創建的臨時表,在session終止時會自動消失。
create temporary table 數據表名;
mysql> create temporary table t2( -- 創建臨時表
-> name varchar(255),
-> age int);
Query OK, 0 rows affected (0.00 sec)
mysql> show tables; -- 臨時表創建後不會顯示
+----------------+
| Tables_in_test |
+----------------+
| t1 |
+----------------+
1 row in set (0.00 sec)
mysql>
mysql>
mysql> select * from t2; -- 查看臨時表的數據
Empty set (0.00 sec)
mysql> exit; -- 退出本次會話後臨時表會刪除
Bye
mysql> select * from t2; -- 查看臨時表的數據會報錯
ERROR 1146 (42S02): Table 'test.t2' doesn't exist
在創建數據表使用create table if not exist 數據表名(...);如果數據表存在的時候就不會存在。
7.根據現有表創建表副本(僅表結構):
create table 新表名 like 原表名;
mysql> select * from t1; -- 向表中插入數據
+-------+------+
| name | age |
+-------+------+
| admin | 18 |
| admin | 18 |
| admin | 18 |
| admin | 18 |
| admin | 18 |
| admin | 18 |
+-------+------+
6 rows in set (0.00 sec)
mysql> create table t1_clone like t1; -- 創建表結構副本
Query OK, 0 rows affected (0.06 sec)
mysql> show tables; -- 查看表
+----------------+
| Tables_in_test |
+----------------+
| t1 |
| t1_clone |
+----------------+
2 rows in set (0.00 sec)
mysql> select * from t1_clone;
Empty set (0.00 sec)
8.根據現有表創建表副本(表結構+數據):
create table 新表名 like 原表名;
insert into 新表名 select * from 原表名;
mysql> create table t1_data like t1;
Query OK, 0 rows affected (0.07 sec)
mysql> insert into t1_data select * from t1;
Query OK, 6 rows affected (0.04 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql> select * from t1_data;
+-------+------+
| name | age |
+-------+------+
| admin | 18 |
| admin | 18 |
| admin | 18 |
| admin | 18 |
| admin | 18 |
| admin | 18 |
+-------+------+
6 rows in set (0.00 sec)
9.刪除數據表:
drop table 數據表名;
drop table 數據表1, 數據表2...;
drop table if exists 數據表名;
mysql> drop table if exists t1_clone, t1_data;
Query OK, 0 rows affected (0.12 sec)
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| t1 |
+----------------+
1 row in set (0.01 sec)
10.索引數據表:
10.1.創建唯一索引:
1)對於單列索引,不允許出現重復值。
alter table 表名 add index 索引名稱(索引列);
create index 索引名稱 on 表名(索引列);
2)對於組合索引,不允許出現重復組合。
alter table 表名 add unique 索引名稱(索引列);
create unique index 索引名稱 on 表名(索引列);
10.2.創建常規(非唯一)索引
會出現值重復的情況。
alter table 表名 add primary key(索引列);
不支持使用create index語句創建索引。
10.3.Fulltext全文索引:
用於全文索引,只用於myisam表。
alter table 表名 add fulltext 索引名稱(索引列);
create fulltext index 索引名稱 on 表名稱(索引列);
10.4.spatial索引:
alter table 表名 add spatial 索引名稱(索引列);
create spatial index 索引名稱 on 表名(索引項);
10.5 Hash索引:
不做介紹
10.6刪除表索引:
drop index 索引名稱 on 表名;
alter table 表名 drop index 索引名稱;
10.7刪除主鍵索引:
drop index `primary` on 表名;
alter index 表名 drop primary key;
10.8索引的分類:
1)數據結構角度:
B+Tree索引
Hash索引:
a) 僅能滿足=或IN或<=>查詢,不能使用範圍查詢
b) 檢索效率高,索引的檢索可以一次定位
c) 只有Memory存儲引擎支持Hash索引
Fulltext索引:
MyISAM和InnoDB都支持
R-Tree索引:
用於對GIS數據類型創建spatial索引
2)物理存儲角度:
聚焦索引
非聚焦索引
3)邏輯角度:
主鍵索引
a) 主鍵索引是一種特殊的唯一索引,不允許有空值
b) 普通索引或單列索引
c) 多列索引(復合索引):是指在多個字段上創建的索引,只有在查詢條件中使用了創建索引的第一個字段,索引才會被使用。復合索引使用的時候遵循最左前綴集合。
d) 唯一索引或非唯一索引
f) 空間索引:MySQL的空間數據類型有:geometry、point、linestring、polygon
MySQL使用spatial關鍵字進行擴展,使得能夠用於創建正規索引類型的語法創建空間索引,必須將其聲明為not null,空間索引只能存儲在存儲引擎為MyISAM的表中。
--更改表結構:
1.更改數據類型:
alter table 表名 modify 列名 數據類型;
alter table 表名 change 列名 列名 數據類型;
更改數據類型同時重命名:
alter table 表名 change 列名 新列名 數據類型;
mysql> desc t1;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| name | varchar(255) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
2 rows in set (0.01 sec)
mysql> alter table t1 change name first_name varchar(255);
Query OK, 0 rows affected (0.11 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc t1;
+------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+-------+
| first_name | varchar(255) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
+------------+--------------+------+-----+---------+-------+
2 rows in set (0.01 sec)
2.更改列名:
alter table 表名 change 列名 新列名 當前列的定義;
rename table 表名 to 新表名;
rename table 表名 to 新表名,表名 to 新表名...;
3.更改存儲引擎:
alter table 表名 engine=引擎名稱;
--元數據:
(1)列出服務器上的數據庫:
show databases;
(2)列出數據庫中的表:
show tables;
(3)顯示數據庫的create database語句:
show create database 數據庫名;
(4)顯示數據庫中的create table語句:
show create table 表名;
(5)顯示表中的類信息:
show columns from 表名;
(6)顯示表中的索引信息:
show index from 表名;
(7)顯示默認數據庫中的表描述信息:
show table status;
(8)顯示指定數據庫中的表描述信息:
show table status from 數據庫名;
--借助infomation_schema獲取元數據:
(1)顯示information_schema數據庫中的表:
show tables in information_schema;
(2)information_schema庫中的各個表:
schema、table、views、routines、triggers、event、parameters、partitions、columns與數據庫、表、視圖、存儲過程、觸發器、事件、表分區和列有關。
files與用於存儲表空間數據的那些文件有關的信息。
table_constraints、key_column_usage與約束條件的表和列有關的信息。
statistics與表索引特性有關的信息。
referential_constraints與外鍵有關的信息。
character_sets、collations、collation_character_set_applicability與支持的字符集、每種字符集的排序規則、以及每種排序規則與其字符集之間的映射關系的信息。
engines、plugins與存儲引擎和服務器插件有關的信息。
user_privileges、schema_privileges、table_privileges、column_privileges與全局、數據庫、表和列的權限分配有關的信息,分別來自於mysql的user、db、tables_priv和column_priv表。
global_variables、session_variables、global_status、global_status全局和會話的系統變量與狀態變量值。
processlist與服務器內執行的線程有關。
--多表查詢:
(1)使用連接實現多表查詢:
mysql> select * from t2;
+------+------------+
| id | first_name |
+------+------------+
| 2 | Hello |
| 2 | World |
| 3 | Hi |
+------+------------+
3 rows in set (0.00 sec)
mysql> select * from t1;
+------+-------+
| id | name |
+------+-------+
| 1 | tom |
| 1 | alice |
| 1 | amy |
+------+-------+
3 rows in set (0.00 sec)
(1.1)內連接:
沒有指定條件,從t1中的表中的每一行數據都與t2表中的每一行數據匹配,這將會形成卡迪爾積!!!
mysql> select * from t1 inner join t2;
+------+-------+------+------------+
| id | name | id | first_name |
+------+-------+------+------------+
| 1 | tom | 2 | Hello |
| 1 | alice | 2 | Hello |
| 1 | amy | 2 | Hello |
| 1 | tom | 2 | World |
| 1 | alice | 2 | World |
| 1 | amy | 2 | World |
| 1 | tom | 3 | Hi |
| 1 | alice | 3 | Hi |
| 1 | amy | 3 | Hi |
+------+-------+------+------------+
9 rows in set (0.00 sec)
加入條件進行過濾:
mysql> select * from t1 inner join t2 where t2.id=t1.id;
Empty set (0.00 sec)
沒有匹配的數據,返回空集。
(1.2)左連接、右連接:
內連接只會顯示在兩個表中都匹配的行,外連接除了顯示同樣的匹配結果,還可以把其他表在另一個表裏沒有匹配出來的行也顯示出來。左連接和右連接屬於外連接。左連接使用left join,右連接使用right join。
左連接的工作方式:
1.先指定用於對兩個表裏的行進行匹配的列。
2.當左表中的數據與右表中的數據匹配的時候,匹配的數據會連接成為一個新的行。
3.當左表中的數據與右表中的數據沒有匹配的時候,將會與右表中的空行作為一個行顯示。
4.右連接與左連接相反。
--向左表中插入匹配的數據:
mysql> insert into t1(id, name) values(2, "Toms");
Query OK, 1 row affected (0.08 sec)
mysql> insert into t1(id, name) values(2, "Toms");
Query OK, 1 row affected (0.04 sec)
mysql> insert into t1(id, name) values(3, "Toms");
Query OK, 1 row affected (0.11 sec)
--執行左連接操作:
mysql> select * from t1 left join t2 on t1.id=t2.id;
+------+-------+------+------------+
| id | name | id | first_name |
+------+-------+------+------------+
| 2 | Toms | 2 | Hello |
| 2 | Toms | 2 | Hello |
| 2 | Toms | 2 | World |
| 2 | Toms | 2 | World |
| 3 | Toms | 3 | Hi |
| 1 | tom | NULL | NULL |
| 1 | alice | NULL | NULL |
| 1 | amy | NULL | NULL |
+------+-------+------+------------+
8 rows in set (0.00 sec)
--執行右連接操作:
mysql> select * from t1 right join t2 on t1.id=t2.id;
+------+------+------+------------+
| id | name | id | first_name |
+------+------+------+------------+
| 2 | Toms | 2 | Hello |
| 2 | Toms | 2 | World |
| 2 | Toms | 2 | Hello |
| 2 | Toms | 2 | World |
| 3 | Toms | 3 | Hi |
+------+------+------+------------+
5 rows in set (0.00 sec)
(2)使用子查詢實現多表檢索:
(2.1)IN、NOT IN查詢:
mysql> select * from t1 where id in (select id from t2);
+------+------+
| id | name |
+------+------+
| 2 | Toms |
| 2 | Toms |
| 3 | Toms |
+------+------+
3 rows in set (0.00 sec)
(2.2)帶關系比較運算符的子查詢:
帶有比較運算符的子查詢是指父查詢與子查詢之間用比較運算符進行連接。當用戶確切知道內層查詢返回單個值時,可以用>、<、=、>=、<=、!=或<>等比較運算符。
mysql> select * from t1 where id < (select id from t2 where id=3);
+------+-------+
| id | name |
+------+-------+
| 1 | tom |
| 1 | alice |
| 1 | amy |
| 2 | Toms |
| 2 | Toms |
+------+-------+
5 rows in set (0.00 sec)
(2.3)ALL、ANY、SOME子查詢:
a)當比較的值小於等於子查詢返回的每個值的時候,<=ALL的結果為真。
b)當比較的值小於等於子查詢返回的任意值的時候,<=ANY的結果為真。
c)SOME與ANY同義。
(2.4)exists、not exists子查詢:
只會測試某個子查詢是否返回了行。
(2.5)相關子查詢:
相關子查詢引用了外層查詢裏的值,所以他也會依賴於外層查詢。因為有了這種聯系,所以相關子查詢不能脫離外層查詢作為一條獨立的查詢去執行。
(2.6)FROM子句中的子查詢:
在FROM中使用在查詢是為了生成某些值。
Tips:有相當一部分子查詢命令可以改進為連接。連接的效率有時會比子查詢的更好,因此如果使用一條select語句需要花費很長時間才能執行完畢,那麽可以嘗試把它改寫為一個連接。
(3)使用UNION實現多表查詢:
mysql> create table t1(
-> id int,
-> name varchar(255)
-> );
Query OK, 0 rows affected (0.05 sec)
mysql> create table t2(
-> id int,
-> first_name varchar(255)
-> );
Query OK, 0 rows affected (0.05 sec)
mysql> create table t3(
-> id int,
-> last_name varchar(255)
-> );
Query OK, 0 rows affected (0.04 sec)
mysql> insert into t1(id, name)values(1, 'xiaowang');
Query OK, 1 row affected (0.07 sec)
mysql> insert into t1(id, name)values(2, 'xiaoli');
Query OK, 1 row affected (0.11 sec)
mysql> insert into t2(id, first_name)values(1, 'xiao');
Query OK, 1 row affected (0.10 sec)
mysql> insert into t2(id, first_name)values(2, 'xiao');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t3(id, last_name)values(1, 'wang');
Query OK, 1 row affected (0.08 sec)
mysql> insert into t3(id, last_name)values(1, 'li');
Query OK, 1 row affected (0.00 sec)
mysql> select t1.id from t1 union select t2.id from t2 union select t3.id from t3;
+------+
| id |
+------+
| 1 |
| 2 |
+------+
2 rows in set (0.00 sec)
union的特性:
a)列名和數據類型:
union的結果集裏的列名來自於第一個select語句裏的列名。union中的第二個以及後面的select必須選取相同個數的列,但是各個列不必具備有相同名字和數據類型。
通常情況下,同一條union語句裏的各響應的列都具備相同的數據類型。如果他們不一樣,那麽MySQL會進行必要的數據轉換。
列是根據位置,而不是根據名字來匹配的。
b)重復行處理:
默認情況下,union會將重復的行去除。如果想保留重復的行,就需要將所有的union改為union all。
c)排序與限制:
如果想將union結果作為一個整體進行排序,那麽需要用括號把每一個select 語句括起來,並在最後那個select語句後面加上order by子句,因為union會使用第一個select語句裏的列名,所以order by必須使用引用的那些名字,而不是最後一個select語句中的名字。
如果想要限制返回的行數,可以在句末加入limit語句。
至於多表更新與刪除類似於多表查詢。
插入語句:
insert into 表名稱 values(...);
insert into 表名稱(...) values(...);
更新語句:
update 表名稱 set 列名稱=值 where 條件;
刪除語句:
delete from 表名稱 where 條件;
(2)事務、視圖、存儲過程:
(2.1)創建並執行事務:
事務是指一組SQL語句,這是一個執行單位,並且在必要的時候可以取消,因為並不是所有的SQL語句都執行成功。
事務的處理是通過提交和回滾實現的,如果某個是事務中的全部語句執行成功,那麽可以把它提交到數據庫永久的記錄到數據庫,如果SQL在執行過程中出現錯誤,事務在出錯之前將會回滾到原來的狀態。
事務的另一個用途是確保某個操作所涉及的行不會在你正在使用的數據在被其他客戶端使用,雖然MySQL提供了對資源的鎖定功能,但是仍然不能保證每一個數據庫的操作都能達到預想的結果。
事務將多條SQL語句定義為一個單位,可以防止在多客戶端環境中可能會發生並發問題。
事務通常具有ACID四個特性:原子性、一致性、獨立性、持久性。
原子性:構成事務的所有的語句會是一個邏輯單元。
一致性:數據庫在事務的執行前後都是一致的,不能執行事務的一部分。
獨立性:事物之間不應該相互影響。
持久性:當事務執行完成時會被永久的保存在數據庫中。
默認情況下,MySQL的運行模式是自動提交的,也就是沒條語句所做的更改會立即提交到數據庫,實際上這是每條語句被當做事務來執行了。如果想要顯式的執行事務,那麽就需要禁用自動提交模式,並主動告知MySQL什麽時候提交數據。
調用start transaction;或begin;語句,掛起自動提交模式,再執行本次事務的SQL語句,最後使用commit;語句來結束事務。如果在事務執行過程中出現錯誤,使用rollback;語句來回滾事務。
事務執行完成之後會回到開始事務之前的模式,如果自動提交模式本來就是金庸的,那麽當結束當前事務的時候會執行下一個事務。
另一個執行事務的方法是set autocommit=0;來關閉事務,使用set autocommit=1;來開啟事務。
(2.2)回滾部分事務:
回滾整個事務可以使用rollback;語句實現,當需要回滾部分事務的時候,可以使用設置事務保存點來實現。
mysql> create table t1 (id int) engine=InnoDB;
Query OK, 0 rows affected (0.12 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t1 values(1);
Query OK, 1 row affected (0.01 sec)
mysql> insert into t1 values(2);
Query OK, 1 row affected (0.00 sec)
mysql> savepoint my;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t1 values(3);
Query OK, 1 row affected (0.00 sec)
mysql> rollback to savepoint my;
Query OK, 0 rows affected (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.08 sec)
mysql> select * from t1;
+------+
| id |
+------+
| 1 |
| 2 |
+------+
2 rows in set (0.00 sec)
(2.3)事務隔離:
由於MySQL是一個多用戶數據庫系統,所以不同客戶端可能會在同一時間內修改數據。像MyISAM之類的存儲引擎使用了表級的鎖機制,以保證不同的客戶端不能在同一時間修改同一個表。但是這種做法在大量更新操作時,難以保證很好的並發性能。InnDB存儲引擎采用的是另一個方法,它是用了比較底層的輸定方式,為客戶端提供更加細致的表訪問控制機制。InnoDB存儲引擎是行級鎖定,多個客戶端不能同時操作一行數據。InnoDB存儲引擎實現的事務隔離級別功能能夠讓客戶端對他們想要看到的數據能通過其他事務進行修改。InnoDB提供多種不同的隔離級別:
問題:
a)臟讀:在某個事務沒有計較的情況下其他事務就能看到這些修改,因此其他事務認為這是修改過的數據,即使那個對數據進行操作的事務進行回滾,從而導致數據行並沒有發生修改,而其他事務以為是修改過的。
b)不可重復讀:同一個事務使用同一條select語句在每一次讀取時會得到不同的結果。如果同一個事務執行兩次select語句,另一個事務在上一個事務執行select語句之間執行了數據修改語句,就會發生不可重復讀的情況。
c)幻影行:一個事務突然看到一個以前沒有見過的行,加入某個事務在執行select語句之後,另一個事務執行了insert語句,如果第一個事務再執行select語句將會看到新增的行,但是這是不存在的,因為第二個事務沒有提交。
4種事務隔離級別:
a)read uncommitted:它允許某個事務看到其他事務尚未提交的修改。
b)read committed:允許某個事務看到其他事務已經提交的行修改。
c)repeatable read:如果某個事務同時執行兩條select語句,其結果可能是重復的。
d)serializable:與repeatable read類似,但是對事物的隔離更加徹底,主要表現在:只有等到當前事務執行完成才會執行其他事務。
InnoDB的默認事務隔離級別是:repeatable read。
更改默認的事務隔離級別:
a)在啟動服務器程序的時候用使用--transaction-isolation選項
b)服務器運行時使用set transaction語句
set global transaction isoation level 級別;
set session transaction isolation level 級別;
set transaction isolation level 級別;
(3)外鍵:
父表找那個的鍵值可以關聯兩個表,子表裏的索引會引用父表裏的索引。子表的索引值必須與父表中的索引值想匹配或者被設置為NULL,以表明咋父表裏不存在與之對應的行。子表中的索引就是外鍵,在外鍵的關系中不會出現不匹配的情況,這就是參照完整性。
constraint 約束名稱 foreign key 外鍵名稱(索引列) references 表名(索引列) on delete 動作 on update 動作
constraint子句:如果提供這個子句,那麽他會為外鍵提供一個名字,如果省略它,那麽InnoDB存儲引擎會創建它。
foreign key 子句:外鍵名稱就是外鍵ID,即使提供外鍵ID也會被忽略,只有InnoDB為這個外鍵自動創建索引時才會起作用。
references子句:會列出父表及其索引的名字,讓子表裏的外鍵可以引用他們。
on delete子句:可以用它來指定在父表刪除行的時候,子表中的記錄進行何種操作:
a)on delete on action /on delete restrict子句:與on delete子句一樣,默認行為是拒絕在父表中刪除行的時候子表的行仍被引用的那些行。
b)on delete cascade 子句:在父表中刪除行的時候子表相關聯的行也會被刪除。
c)on delete set null 子句:在父表刪除行的時候子表相關聯的行會被置為NULL。
on update子句:
a)on delete on action /on delete restrict子句:與on delete子句一樣,默認行為是拒絕在父表中更新行的時候子表的行仍被引用的那些行。
b)on delete cascade 子句:在父表中更新行的時候子表相關聯的行也會被更新。
c)on delete set null 子句:在父表更新行的時候子表相關聯的行會被置為NULL。
(4)視圖:
視圖是一種存儲對象,是一種虛擬表。視圖提供了一種簡單的運行復雜查詢的方式。
創建視圖:
create view 視圖名稱 as
SQL語句...;
修改視圖:
alter view 視圖名稱 as
SQL語句...;
刪除視圖:
drop view 視圖名稱;
(5)存儲程序:
是一種存儲對象,具有多種形式。
mysql> select * from t1;
+------+-------+
| id | name |
+------+-------+
| 1 | tom |
| 2 | amy |
| 3 | alice |
+------+-------+
3 rows in set (0.00 sec)
(5.1)存儲函數:
用在表達式中返回某個計算的結果。
mysql> delimiter $
mysql> create function func(number int)
-> returns int
-> reads sql data
-> begin
-> return (select id from t1 where id=number);
-> end$
Query OK, 0 rows affected (0.12 sec)
mysql> delimiter ;
mysql> select func(2);
+---------+
| func(2) |
+---------+
| 2 |
+---------+
1 row in set (0.00 sec)
(5.2)存儲過程:
不會直接返回結果,但是可以用來完成一般的運算。
mysql> create procedure proc(number int)
-> begin
-> select * from t1;
-> end$
Query OK, 0 rows affected (0.12 sec)
mysql> delimiter ;
mysql> call proc(1);
+------+-------+
| id | name |
+------+-------+
| 1 | tom |
| 2 | amy |
| 3 | alice |
+------+-------+
3 rows in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
存儲過程使用的參數類型:
在參數列表裏的參數名前面使用IN、OUT、INOUT。如果沒有指定參數類型,默認使用IN。
mysql> delimiter $
mysql> create procedure count_id(IN id_number int, OUT count_number int)
-> begin
-> set count_number = (select count(id) from t1 where id > id_number);
-> end$
Query OK, 0 rows affected (0.04 sec)
mysql> delimiter ;
mysql> call count_id(1, @count_number);
Query OK, 0 rows affected (0.01 sec)
mysql> select @count_number;
+---------------+
| @count_number |
+---------------+
| 2 |
+---------------+
1 row in set (0.00 sec)
(5.3)觸發器:
與表關聯在一起,當表執行insert、delete、update語句進行修改的時候會自動執行。觸發器的定義包含有一條會在觸發器激活的時候執行的語句。
觸發器的幾個好處:
a)觸發器可以檢查或修改將被插入或用來更新那些數據行。這就意味著我們可以利用觸發器實現數據完整性約束,觸發器也可以用來過濾數據。
b)觸發器可以基於某個表達式來為某個列提供默認值。
c)觸發器可以在行刪除或者是更新之前先檢查當前行的內容。
create trigger 觸發器名稱
{before|after}
{insert|update|delete}
on 表名
for each row 觸發器內容;
觸發器內容:
begin
SQL語句...;
end
new與old:
在insert觸發器中,new用來表示即將(before)或者是已經(after)插入的數據。
在update觸發器中,old用來表示即將或者是已經被修改的原數據,new用來表示即將或者修改為的數據。
在delete觸發器中,old用來表示即將或者已經被刪除的原數據。
使用方法:new.列名,old是只讀的,而new是可以在觸發器中使用set賦值的,這樣不會再次觸發觸發器造成循環調用。
查看觸發器:show trigger;
刪除觸發器:drop trigger [if exists] 觸發器名稱;
觸發器的執行順序:
我們建立的數據庫一般都是 InnoDB 數據庫,其上建立的表是事務性表,也就是事務安全的。這時,若SQL語句或觸發器執行失敗,MySQL 會回滾事務,有:
a)如果 BEFORE 觸發器執行失敗,SQL 無法正確執行。
b)SQL 執行失敗時,AFTER 型觸發器不會觸發。
c)AFTER 類型的觸發器執行失敗,SQL 會回滾。
(5.4)事件:
會根據在預定的時刻自動執行。
MySQL有一個事件調度器,它可以定時激活多個數據庫操作,事件就是一個與計劃相關聯的存儲程序。
計劃會定義事件執行的時間或次數,並且還可以定義事件何時強行退出。
事件非常適合於執行那些無人值守的系統管理任務。
默認情況下,事件調度器並不會運行,因此必須先啟用它才能使用事件。
配置服務器:
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
default_authentication_plugin=mysql_native_password
event_scheduler=ON # 寫入本行配置
查看事件調度器的狀態:
mysql> show variables like 'event_scheduler';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| event_scheduler | ON |
+-----------------+-------+
1 row in set (0.04 sec)
如果要在運行時停止或者是啟動:
set global event_scheduler = OFF;
set global event_scheduler = ON;
創建事件:
create event 事件名稱 on schedule {at 日期時間 | every 正則表達式 區間 [starts 日期時間] [ends 日期時間]} do 事件內容
事件內容可以是一條簡單的SQL語句,也可以是有begin和end構成的復合語句。
啟用與禁用事件:
alter event 事件名稱 disable;
alter event 事件名稱 enable;
未完待續...
PythonWeb全棧工程師必備技能之<MySQL開發篇>