目錄:1.數據庫簡介與mysql操做 2.pymysql模塊 3.mysql內置功能 4.索引python
數據庫簡介mysql
數據庫管理軟件程序員
mysql解決的不只僅是數據共享的問題,還有查詢效率,安全性等一系列問題,總之,把程序員從數據管理中解脫出來,專一於本身的程序邏輯的編寫正則表達式
數據:data 描述事物的符號記錄redis
數據庫:DataBase (DB)存放數據的倉庫sql
數據庫中的數據按必定的數據模型組織、描述和儲存,具備較小的冗餘度、較高的數據獨立性和易擴展性,並可爲各類用戶共享mongodb
數據庫管理系統: DataBase Management System (DBMS)數據庫
MySQL 主要用於大型門戶,如搜狗、新浪等,開放源代碼,免費,甲骨文公司安全
Oracle 主要用於銀行、鐵路、飛機場等,功能強大、軟件費用高,甲骨文公司服務器
SQLite
Access、MS SQL Server 主要用於大中型企業,如聯想、方正等,微軟公司
數據庫服務器: 一臺計算機(對內存要求比較高)
數據庫管理系統:如MySQL,一個軟件
數據庫: 即文件夾,用來組織文件/表
表: 即文件,用來存放多行內容/記錄
記錄: 即文件中的一行內容,多個字段的信息組成一條記錄,就是具體內容,事物一系列典型的特徵
數據: 描述事物特徵的符號
數據庫管理軟件分類:
關係型:須要表結構,sqlite,db2,oracle,access,sql server,mysql
非關係型:沒有表結構,key-value存儲,mongodb,redis,memcache
MySQL是一個關係型數據庫管理系統,其實就是一個基於socket編寫的C/S架構的軟件
強調:配置文件中的註釋能夠有中文,可是配置項中不能出現中文
sql語句結束後的分號;相當重要
\c終止一條sql語句運行
mysql -uroot -p123
sql:Structured Query Language 結構化查詢語言
SQL語言主要用於存取數據、查詢數據、更新數據和管理關係數據庫系統,由IBM開發
分爲三類:
DDL語言 數據庫定義語言:數據庫、表、視圖、索引、存儲過程,例如 增create、刪drop、改alter、查show
DML語言 數據庫操縱語言:插入數據insert、刪除數據delete、更新數據update、查詢數據select
DCL語言 數據庫控制語言:例如控制用戶的訪問權限GRANT、REVOKE
操做文件夾(庫):
增:
create database db1 charset utf8; 建立數據庫db1
查:
show create database db1; 指定查看數據庫db1
show databases; 查看全部數據庫
改:
alter database db1 charset gbk; 改數據庫db1的字符編碼
刪:
drop database db1;
操做文件(表):
切換文件夾: use db1; 切到db1這個文件夾下
查看當前所在文件夾:select database();
增:
create table t1(id int,name char);
查:
show create table t1; 查看錶t1 t1 後面能夠加一個\G,一行一行顯示,避免出現表內容太多而顯示出亂的狀況
show tables; 查看當前目錄下全部的表
desc t1; 查看錶t1
改:
alter table t1 modify name char(6); 改表t1的name這行的長度
alter tabel t1 change name NAME char(7);
刪:
drop table t1;
操做文件內容(記錄):
增:
insert t1(id,name) values(1,'egon1'),(2,'egon2'),(3,'egon3');
insert t1 values(4,'egon4'); 就是說能夠不寫(id,name)會默認對應上,也能夠(name,id)這樣後面的values順序也要反過來
insert into t1 values(1,'egon1'),(2,'egon2'),(3,'egon3');
查:
select id,name from db1.t1; (不寫db1的話就默認在當前文件夾下找t1)
select * from db1.t1; 查看db1下表t1的全部內容 不推薦用
改:
update db1.t1 set name="SB"; 把name這一列的數據全都改爲SB
update db1.t1 set name="ALEX" where id=3; 把id是3的這一列的name改爲ALEX
刪:
delete from db1.t1; 把整個t1都刪了
delete from db1.t1 where id=1; 把t1中id是1的刪了
系統數據庫:
information_schema:虛擬庫,不佔磁盤空間,存儲的事數據庫啓動後的一些參數,如用戶表信息、列信息、權限信息、字符信息等
performance_schema:MySQL 5.5 開始新增的一個數據庫:主要用於收集數據庫服務器性能參數,記錄處理查詢請求時發生的各類事件、鎖等現象
mysql:受權庫,主要存儲系統用戶的權限信息
test:MySQL數據庫系統自動建立的測試數據庫
建立數據庫:
create database 數據庫名 charset utf8;
數據庫名命名規則:
能夠由字母、數字、下劃線、@、#、$,區分大小寫,惟一性,不能使用關鍵字,如create select,不能單獨使用數字,最長128位
什麼是存儲引擎?
存儲引擎就是表的類型,針對不一樣的數據類型有不一樣的存儲引擎,即有不一樣的表的類型
查看MySQL支持的存儲引擎:
show engines;
有不少種innodb,memory,blackhole,myisam等,存儲機制不一樣
默認使用InnoDB存儲引擎
指定表類型,即存儲引擎
create table t1(id int)engine=innodb;
create table t2(id int)engine=memory;
create table t3(id int)engine=blackhole;
create table t4(id int)engine=myisam;
表:
id,name,age等這些都是字段,它們對應的一行行內容稱爲記錄
建立表:
create table 表名(
字段名1 類型[(寬度) 約束條件],
字段名2 類型[(寬度) 約束條件],
字段名3 類型[(寬度) 約束條件],
字段名4 類型[(寬度) 約束條件]
)
最後一個字段名不要加,逗號,否則會報錯
同一張表中,字段名不能重複
寬度和約束條件可選
字段名和類型是必須的
修改表:
改表名:
alter table 表名
rename 新表名;
字段名能夠進行增add刪drop改modify/change
查能夠用desc t1 或者 select * from t1 或者show create table t1
增長字段:
alter table 表名
add 字段名 數據類型[約束條件],
add 字段名 數據類型[約束條件];
alter table 表名
add 字段名 數據類型[約束條件] first;
alter table 表名
add 字段名 數據類型[約束條件] after 字段名;
刪除字段
alter table 表名
drop 字段名;
修改字段
alter table 表名
modify 字段名 數據類型[約束條件];
alter table 表名
change 舊字段名 新字段名 舊數據類型[約束條件];
alter table 表名
change 舊字段名 新字段名 新數據類型[約束條件];
複製表:
複製表結構+記錄:
create table 新表名 select 字段名 from 原始表;
只複製表結構:
create table 新表名 select 字段名 from 原始表 where 1=2;
加上限制條件1=2,條件爲假,那就查不到記錄,只有結構
create table 新表名 like 原始表; 也是隻複製表結構
刪除表:
drop table 表名
對字段名的限制條件:數據類型必寫,寬度和約束條件選擇寫,約束條件裏面主鍵最好要寫
數據類型:
1.數字
整型:徹底沒有必要指定顯示寬度,使用默認的11就OK,默認是有符號的,能夠用(id int unsigned)這樣就是無符號的了
tinyint 小整數,有符號-128~127 無符號0~255 1個字節
int 整數 有符號-2147483648~2147483647 無符號0~4294967295 4個bytes就是32個bit就是2**32
bigint 大整數 有符號-9223372036854775808~9223372036854775807 無符號0~18446744073709551615 8個字節
小數:
float 單精度浮點數,隨着小數增多,精度變得不許確 4個字節 float[(m,d)] m是數字總個數,最大值255,d是小數點後個數,最大值30
double 雙精度浮點數,隨着小數增多,精度高於float,但也會變得不許確 8個字節 double[(m,d)] m是數字總個數,最大值255,d是小數點後個數,最大值30
decimal 定點數類型,準確的小數值,隨着小數增多,始終精準,對於精確數值計算時須要用此類型,其內部按照字符串存儲
decimal[(m,d)] m是數字總個數,最大值65,d是小數點後個數,最大值30
2.字符串
括號內的參數就是字符的個數
char:定長 簡單粗暴 浪費空間 存取速度快,字符長度範圍0-255,存儲時會往右填充空格來知足長度
varchar 變長 精準 節省空間 存取速度慢,字符長度範圍0-65535,存儲真實內容,不填充空格
存儲時會在真實數據前加1-2bytes的前綴,真實數據小於255bytes用1個bytes前綴,大於255用2個
length函數查看字節數
char——length函數查看字符數
大部分狀況下用char,跟查詢無關的能夠用varchar
3.時間類型
date 2018-05-24 範圍是1000-01-01到9999-12-31
time 20:44:20 範圍是-838:59:59到838:59:59
datetime 2018-05-24 20:44:20 範圍是1000-01-01 00:00:00 到 9999-12-31 23:59:59
timestamp 2018-05-24 20:44:20 範圍是1970-01-01 00:00:00 到2037年某時
year 2018 範圍是1901-2155
最經常使用的是datetime
datetime與timestamp的區別:
1.datetime的日期範圍是1001-9999年,而timestamp是1970-2038年
2.datetime存儲時間與時區無關,timestamp與時區有關,顯示的值也依賴於時區
3.datetime使用8個字節存儲,timestamp使用4個字節,空間利用率更高
4.datetime默認值是null,timestamp默認值是當前時間
4.枚舉類型與集合類型
枚舉類型 enum 單選 只能從給定的範圍內選一個值
集合類型 set 多選 能夠在給定的範圍內選擇一個或一個以上
約束條件:
與數據類型的寬度同樣,都是可選參數
做用是保證數據的完整性和一致性
主要分爲:
primary key (pk) 標識該字段爲該表的主鍵,能夠惟一的標識記錄
foreign key (pk) 標識該字段爲該表的外鍵
not null 標識該字段不能爲空
unique key (uk) 標識該字段的值是惟一的
auto_increment 標識該字段的值自動增加
default 爲該字段設置默認值
unsigned 無符號
zerofill 使用0填充
not null與default
是否可空,null表示可空,not null表示不可空
default爲默認值,建立列時能夠指定默認值,若是插入數據時未主動設置,則自動添加默認值
unique key
標識該字段的值是惟一的
單列惟一:
1.字段後加unique
2.unique(字段名)
聯合惟一:
unique(字段名1,字段名2) 兩個合到一塊兒是惟一的就行,其中一個出現重合沒事
primary key
對於innodb存儲引擎,一張表必須有一個主鍵
primary key字段的值,從約束的角度講就是不爲空且惟一(not null unique)
一個表中能夠單列作主鍵,能夠多列作主鍵(複合主鍵),可是一個表中只能有一個主鍵
單列作主鍵:
一般將id字段設置爲主鍵
1.not null unique
2.在某個字段後加primary key
3.在全部字段後單獨定義primary key(主鍵名)
多列作主鍵:
primary key(字段名1,字段名2)
auto_increment
約束字段爲自增加,被約束的字段必須同時被key約束(unique key,primary key)
好比約束id,給表添加值的時候,若是不指定id就默認自動增加,也能夠指定
對於自增字段,再用delete刪除後,再插入值,該字段仍按照刪除前的位置繼續增加 delete from t1;
應該用truncate清空表,清空後再插入值就從頭開始了 truncate t1;
在建立完表後,修改自增字段的起始值 alter table t1 auto_increment=3;就是從3開始自增
也能夠在建立表時指定auto_increment的初始值,初始值的設置爲表選項,應該放在括號外
show variables like 'auto_increment'查看auto_increment相關的變量
atuo_increment_increment 步長,默認爲1
auto_increment_offset 起始偏移量,默認爲1,就是起始值
設置步長:
set session auto_increment_increment=5; 把當前會話的步長設置爲5
set global atuo_increment_increment=5; 把全局的步長設置爲5,重啓後就默認是這個了
設置起始偏移量:
seeeet global auto_increment_offset=6;這樣就會有問題,起始偏移量要小於等於步長
foreign key
外鍵,創建表之間的關係
仍是少用,儘可能在應用程序上設計兩個表之間的關係,由於若是從數據庫裏把兩張表關聯到一塊兒的話會有強耦合,影響擴展性
1.先創建表關係
先建被關聯的表t2,且t2的被關聯字段必須是惟一的
再建關聯的表
在全部的字段名後加上foreign key(字段名) references t2(字段名) on delete cascade on update cascade放在括號裏面
2.再插入數據 刪除同步 更新同步
先往被關聯表插入記錄,再往關聯表插入記錄
如何找出兩張表之間的關係
1.先站在左表的角度去找
是否左表的多條記錄能夠對應右表的一條記錄,若是是則證實左表的一個字段foreign key右表的一個字段
2.再站在右表的角度去找
是否右表的多條記錄能夠對應左表的一條記錄,若是是則證實右表的一個字段foreign key左表的一個字段
3.總結:
多對一:
只有步驟1成立,則是左表多對一右表
只有步驟2成立,則是右表多對一左表
多對多
步驟1和2同時成立,多對多的關係,須要定義一個這兩張表的關係表來專門存放二者的關係
一對一
步驟1和2都不成立,而是左表的一條記錄對應右表的一條記錄,反之亦然
這種狀況很簡單,就是在左表foreign key右表的基礎上,將左表的外鍵字段設置成unique便可
其中,多對多時存放關係的表:
create table author2book(
id int not null unique auto_increment,
author_id int not null,
book_id int not null,
constraint fk_author foreign key(author_id) references author(id)
on delete cascade on update cascade,
constraint fk_book foreign key(book_id) references book(id)
on delete cascade on update cascade,
primary key(author_id,book_id)
); # constraint fk_author 這部分能夠不寫 是在給這部分外鍵起名字
8.3.4完整性約束 最後有一個練習題
記錄:
插入數據:
1.插入完整數據,順序插入
insert into 表名(字段名1,字段名2) values(值1,值2);
insert into 表名 values(值1,值2);
2.指定字段插入數據
insert into 表名(字段名1,字段名2) values(值1,值2);
3.插入多條記錄
insert into 表名 values
(值1,值2),
(值1,值2),
(值1,值2),
(值1,值2);
4.插入查詢結果
insert into 表名(字段名1,字段名2)
select (字段名1,字段名2) from 表2
where ...;
更新數據
update 表名 set
字段名1=值1,
字段名2=值2,
where ...;
刪除數據
delete from 表名 where ...; delete主要用於有篩選條件時的刪除某些內容
所有清空用 truncate 表名
查詢數據
select id,name from db1.t1; (不寫db1的話就默認在當前文件夾下找t1)
select * from db1.t1; 查看db1下表t1的全部內容 不推薦用
單表查詢:
執行優先級:from > where > group by > having > select > distinct > order by > limit
語法順序:
select distinct 字段1,地段2,字段3 from 庫名.表名
where 條件
group by 分組條件
having 過濾
order by 排序字段
limit n 限制條數;
簡單查詢:這些都是加在select後面的
distinct 避免重複
字段能夠進行四則運算和起別名
select salary*12 as money from t1;
salary能夠進行運算,經過as起別名賦值給money,這個as能夠不寫
能夠本身定義顯示格式
select concat('姓名:',name) from t1; 相似於python中的格式化字符串
同樣的也能夠用as起別名
select concat_ws(':',name,age,sex) from t1;用這種形式,第一個傳分隔符進去
where 約束:
1.比較運算符:> < >= <= <> !=
2.between 80 and 100 值在80到100之間 not between
3.in(80,80,100) 值是80或90或100
4.like 'egon%' 能夠是% 或 _
% 表示任意多個字符 _ 表示一個字符,能夠寫多個下劃線_
5.邏輯運算符:在多個條件直接可使用邏輯運算符 and or not
6.is null 判斷某個字段是否爲null,不能用=
group by 分組查詢
首先,分組發生在where以後,分組是基於where獲得的記錄而進行的
不要按照像id這種分組,由於id你們都不同,分組等於沒分
分組指的是將全部記錄按照某個相同字段進行歸類
能夠按照任意字段分組,可是分組完畢後,好比group by post,只能查看post這個字段,若是想查看組內信息,須要藉助聚合函數
單獨使用group by 關鍵字分組
select post from t1 group by post;
與group_concat()函數一塊兒使用
select post,group_cancat(name) from t1 group by post; # 按照崗位分組,並查看組內成員名
能夠用as起別名 放在from以前
與聚合函數一塊兒使用
select post,count(id) as count from t1 group by post; # 按照崗位分組,並查看每組有多少人
聚合函數:
聚合的是組的內容,如果沒有分組,則默認總體一組
count max min avg sum
having 過濾
執行的優先級 where > group by > having
where 發生在group by以前,所以where中能夠有任意字段,但絕對不能使用聚合函數
having發生在group by以後,所以having可使用分組的字段,沒法直接獲取其餘字段,可使用聚合函數
order by 查詢排序
能夠單列排序,也能夠多列排序,多列排序時用,隔開,排序結果按字段順序
asc升序 desc降序
select * from t1 order by salary asc;
limit 限制查詢的記錄數
select * from t1 order by salary desc limit 3; # 查三條
select * from t1 order by salary desc limit 0,5; # 從0開始,查5條
能夠用做分頁功能
使用正則表達式查詢
select * from t1 where name regexp '^ale';
多表查詢:
先建表
多表鏈接查詢:
select語句執行順序:
from > on > join > where > group by > having > select > distinct > order by > limit
外鏈接語法:
select 字段列表
from 表1 inner|left|right join 表2
on 表1.字段 = 表2.字段;
1.交叉鏈接:不適用任何匹配條件,生成笛卡爾積
2.內鏈接:只鏈接匹配的行,找兩張表共有的部分,至關於利用條件從笛卡爾積結果中篩選出了正確結果
select t1.id,ti.name,t1.age.t1.sex,t2.name from t1 inner join t2 on t1.dep_id=t2.id;
3.外鏈接之左鏈接:優先顯示左表所有記錄
以左表爲準,本質上就是在內鏈接的基礎上增長了左邊有右邊沒有的記錄
select t1.id,ti.name,t2.name as depart_name from t1 left join t2 on t1.dep_id=t2.id;
4.外鏈接之右鏈接:優先顯示右表所有記錄
以右表爲準,本質上就是在內鏈接的基礎上增長了右邊有左邊沒有的記錄
select t1.id,t1.name,t2.name as depart_name from t1 right join t2 on t1.dep_id=t2.id;
5.全外鏈接:顯示左右兩個表所有記錄
在內鏈接的基礎上增長右邊有左邊沒有和左邊有右邊沒有的記錄
mysql不支持全外鏈接full join這種寫法
可使用如下方式:
select * from t1 left join t2 on t1.dep_id=t2.id
union
select * from t1 right join t2 on t1.dep_id=t2.id;
符合條件鏈接查詢
select t1.name,t2.name from ti inner join t2 on t1.dep_id=t2.id where age > 25;
select t1.id,t1.name,t1.age,t2.name from t1 inner join t2 on t1.dep_id=t2.id order by age asc;
子查詢
1.子查詢是將一個查詢語句嵌套在另外一個查詢語句中
2.內層查詢語句的查詢結果能夠爲外層查詢語句提供查詢條件
3.子查詢中能夠包含:in\not in\any\all\exists\not exists等關鍵字
4.還能夠包含比較運算符:= 、!= 、> 、>= 、<= 、< 、<>
帶in關鍵字的子查詢 經常使用
select id,name from t2
where id in
(select dep_id from t1 group by dep_id having avg(age) > 25);
select name from t1
where dep_id in
(select id from t2 where name='技術');
帶比較運算符的子查詢 經常使用
select name,age from t1 where age > (select avg(age) from t1);
帶exists關鍵字的子查詢 瞭解
exists關鍵字表示存在,在使用exists關鍵字時,內存查詢語句不返回查詢記錄,而是返回一個真假值
返回True時,外層語句進行查詢,返回False時,外層語句不進行查詢
select * from t1
where exists
(select id from t2 where id=200);
select * from t1
where exists
(select id from t2 where id=204);
select id,name from t1;獲得一張新的表,輸出到屏幕中,能夠保存:
(select id,name from t1) as t0;這樣就把新的表保存下來了,能夠進行操做
權限管理:
1.建立帳號
本地帳號 create user 'egon1'@'localhost' identified by '123'; mysql -uegon1 -p123
遠程帳號 create user 'egon2'@'192.168.31.10' identified by '123'; mysql -uegon2 -p123 -h服務端ip
遠程帳號 create user 'egon3'@'192.168.31.%' identified by '123'; mysql -uegon3 -p123 -h服務端ip 31這個網段的ip均可以
遠程帳號 create user 'egon4'@'%' identified by '123'; mysql -uegon2 -p123 -h服務端ip 全網段均可以登
2.受權
user
db
tables_priv
columns_priv
grant all on *.* to 'root'@'%' identified by '123';
flush privileges;
建立帳號並受權,全部權限,再刷新一遍就當即生效了
pymysql
基本使用
實例:
import pymysql
user = input('user >>:').strip()
pwd = input('password >>:').strip()
# 創建鏈接
conn = pymysql.connect(
host='192.168.1.100',
port=3306,
user='root',
password='123',
db='db1',
charset='utf8'
)
# 拿到遊標
cursor = conn.cursor()
# 執行sql語句
sql = 'select * from userinfo where user = "%s" and pwd = "%s"' % (user, pwd)
rows = cursor.execute(sql) #受影響的行數
這兩行容易出bug,因此應該按照下面這兩行來寫
# sql = 'select * from userinfo where user = %s and pwd = %s'
# rows = cursor.execute(sql, (user, pwd)) # 字符串拼接不加"" 傳值用元組的形式
# 關閉遊標和鏈接
cursor.close()
conn.close()
# 判斷
if rows:
print('login successful')
else:
print('login failure')
sql注入
sql語句一旦出現-- 這後面的內容就都被註釋掉了
增刪改查
建鏈接 >> 拿到遊標 >> 執行sql語句 >> 關閉 這個順序是固定的
增刪改:insert換成相應的sql語句就能夠
import pymysql
# 創建鏈接
conn = pymysql.connect(
host='192.168.1.100',
port=3306,
user='root',
password='123',
db='db1',
charset='utf8'
)
# 拿到遊標
cursor = conn.cursor()
# 執行sql語句
sql = 'insert into userinfo(user, pwd) values(%s, %s)'
rows = cursor.execute(sql, ('wxx', '123')) # 一次插入一條,這個是受影響的行數
rows1 = cursor.executemany(sql, [('zhao', '123'), ('qian', '234'), ('sun', '345')]) # 一次插入多條
print(cursor.lastrowid) # 自增id在插入新數據時從哪一個id開始
print(rows)
print(rows1)
conn.commit() # 必定要加這個纔會真正的修改數據庫
cursor.close()
conn.close()
查:
import pymysql
# 創建鏈接
conn = pymysql.connect(
host='192.168.1.100',
port=3306,
user='root',
password='123',
db='db1',
charset='utf8'
)
# 拿到遊標
cursor = conn.cursor(pymysql.cursors.DictCursor) # 以字典的格式拿到
# 執行sql語句
sql = 'select * from userinfo'
rows = cursor.execute(sql)
print(cursor.fetchone()) # 一次取一行
# print(cursor.fetchmany(2)) # 能夠指定一次取幾個,從相對位置開始移動
# print(cursor.fetchall()) # 能夠取全部的,從相對位置開始移動,就是看前面取了多少了接着取
# cursor.scroll(3, mode='relative') # 相對移動,從當前位置跳過3個開始取值
cursor.scroll(3, mode='absolute') # 絕對移動,從頭開始跳3個開始取值
print(cursor.fetchmany(2))
print(cursor.fetchall())
cursor.close()
conn.close()
mysql內置功能:
視圖、觸發器、流程控制、函數、事物均可以封裝到存儲過程當中
這些都是mysql提供的內置功能,徹底能夠本身用python寫sql語句來本身實現
視圖:
視圖是用來查的,單張表時可能能夠改,涉及多張表時千萬別改
視圖是一個虛擬表,其本質是根據sql語句獲取動態的數據集併爲其命名,用戶使用時只需使用名稱便可獲取結果集,能夠將該結果集當作表來使用
使用視圖咱們能夠把查詢結果中的臨時表摘出來,方便操做,可是視圖有明顯的效率問題,而且視圖是存放在數據庫中的,過度依賴視圖會出現強耦合,不利於擴展
效率甚至不如咱們本身寫子查詢高,所以不推薦使用視圖
create view teacher_view as select tid from teacher where tname='李平老師';
觸發器:
使用觸發器能夠定製用戶對錶進行增刪改操做時先後的行爲,注意!沒有查詢
建立觸發器:
插入前:
create trigger tri_before_insert_tb1 before insert on tb1 for each row
begin
...
end;
插入後:
create trigger tri_after_insert_bt1 after insert on tb1 for each row
begin
...
end;
刪除前:
create trigger tri_before_delete_tb1 before delete on tb1 for each row
begin
...
end;
刪除後:
create trigger tri_after_delete_tb1 after delete on tb1 for eacch row
begin
...
end;
更新前:
create trigger tri_before_update_tb1 before update on tb1 for each row
begin
...
end;
更新後:
create trigger tri_after_update_tb1 after update on tb1 for each row
begin
...
end;
先準備表,再建立觸發器,以下,再執行插入操做
delimiter //
create trigger tri_after_insert_cmd after insert on cmd for each row
begin
if new.success='no' then # 等值判斷只有一個等號
insert into errlog(err_cmd,err_time) values(new.cmd,new.sub_time); # 必須加分號
end if; # 必須加分號
end //
delimiter ;
new表示即將插入的數據行,old表示即將刪除的數據行
刪除觸發器:
drop trigger tri_after_insert_cmd;
存儲過程:
包含一系列可執行的sql語句,存放於mysql中,經過調用它的名字能夠調用其內部的一堆sql
使用存儲過程的優勢:
用於替代程序寫的sql語句,實現程序與sql解耦
基於網絡傳輸,傳別名的數據量小,而直接傳sql數據量大
使用存儲過程的缺點:
程序員擴展功能不方便
程序與數據庫結合使用的三種方式:
1.mysql:編寫存儲過程 程序:調用存儲過程
2.程序:純sql語句內 運行效率高
3.程序:類和對象即ORM,基於面向對象寫 開發效率高,一般用這種
建立簡單存儲過程(無參):
delimiter // # 這個是在自定義sql語句的結束符,能夠用// 也能夠用其餘的
create procedure p1()
begin
select * from blog;
insert into blog(name,sub_time) values('xxx',now());
end //
delimiter ;
在mysql中調用時:call p1()
在python中基於pymysql調用時: cursor.callproc('p1')
print(cursor.fetchall())
建立存儲過程(有參):
能夠接收的參數:
1. in 僅用於傳入參數用
2. out 僅用於返回值用
3. inout 便可以傳入又能夠當作返回值
in:
delimiter //
create procedure p2(
in n1 int,
in n2 int
)
begin
select * from blog where id > n1;
end //
delimiter ;
在mysql中調用時:call p2(3,2)
在python中基於pymysql調用時:cursor.callproc('p2',(3,2))
print(cursor.fetchall())
out:
delimiter //
create procedure p3(
in n1 int,
out res int
)
begin
select * from blog where id > n1;
set res = 1;
end //
delimiter ;
在mysql中調用時:
set @res=0; # 0表明假,執行失敗,1表明真,執行成功 設定返回值的初始值
call p3(3,@res); # 拿到select執行結果
select @res; # 拿到運行的返回值
在python中基於pymysql調用時:
cursor.callproc('p3',(3,0)) # 0至關於set @res=0 這個內部過程是@_p3_0=3,@_p3_1=0
print(cursor.fetchall()) # 查詢select的查詢結果
cursor.execute('select @_p3_0,@_p3_1;') # @_p3_0表明第一個參數@_p3_1表明第二個參數
print(cursor.fetchall())
inout:
delimiter //
create procedure p4(
inout n1 int
)
begin
select * from blog where id > n1;
set n1 = 1;
end //
delimiter ;
在mysql中調用時:
set @x=3;
call p4(@x);
select @x;
在python中基於pymysql調用時:
cursor.callproc('p4',(3,))
print(cursor.fetchall()) # 查詢select的查詢結果
cursor.execute('select @_p4_0;')
print(cursor.fetchall())
事物:
用於將某些操做的多個sql語句做爲原子性操做,一旦有某一個出現錯誤,便可回滾到原來的狀態,從而保證數據庫數據完整性
要麼所有都執行成功,要麼所有都不成功
start transaction;
sql語句;
sql語句;
sql語句;
sql語句;
commit; 若是不寫這個,roolback回滾就能回到以前的狀態
函數:用於sql語句中
1.數學函數:
round(x,y) 返回參數x的四捨五入的有y位小數的值
rand() 返回0到1之間的隨機值
2.聚合函數
avg()
count()
min()
max()
sum()
group_concat() 返回由屬於一組的列值鏈接組合而成的結果
3.字符串函數
4.日期和時間函數
重點:date_format(date,format) 根據format字符串格式化date的值
5.控制流函數
流程控制:
if
while循環
索引:
索引的目的在於提升查詢效率
本質上是經過不斷的縮小想要獲取數據的範圍來篩選出最終想要的結果,同時把隨機的事件變成順序的事件
也就是說,有了這種索引機制,咱們能夠老是用同一種查找方式來鎖定數據
mysql索引管理
1.功能:加速查找,並且primary key unique等也是索引
2.mysql中經常使用索引
普通索引:
index
惟一索引:
primary key 主鍵索引
unique 惟一索引
聯合索引:
primary key(id,name) 聯合主鍵索引
unique(id,name) 聯合惟一索引
index(id,name) 聯合普通索引
3.索引的兩大類型hash與btree
hash類型:查詢單挑快,範圍查詢慢
btree類型: b+樹,層數越多,數據量指數級增加(innodb默認用這個) innodb表的索引會存放於s1.ibd文件中
innodb是索引組織表,即表中數據按照主鍵順序存放
b+樹索引能夠分爲彙集索引和輔助索引
無論是彙集索引仍是輔助索引,其內部都是B+樹的形式,即高度是平衡的,葉子結點存放着全部的數據。
彙集索引與輔助索引不一樣的是:葉子結點存放的是不是一整行的信息,輔助索引的葉子節點不包含行記錄的所有數據
彙集索引的好處:
對主鍵的排序查找和範圍查找速度很是快
範圍查詢,即若是要查找主鍵某一範圍內的數據,經過葉子節點的上層中間節點就能夠獲得頁的範圍
4.建立和刪除索引
方法一:建立表時
create table 表名(
字段名1 數據類型[約束性條件],
字段名2 數據類型[約束性條件],
字段名3 數據類型[約束性條件],
[unique | fulltext | spatial] index|key
[索引名] (字段名[(長度)] [asc|desc])
); []內的能夠不寫
方法二:create在已存在的表上建立索引
create [unique | fulltext | spatial] index 索引名
on 表名(字段名[(長度)] [asc|desc]);
方法三:alter table 在已存在的表上建立索引
alter table 表名 add [unique | fulltext | spatial] index 索引名 (字段名[(長度)] [asc|desc]);