1. 程式人生 > >mysql內置功能

mysql內置功能

ont 了解 user 執行 速度 teacher import 語句 python

一、視圖

create view course2teacher as select * from course inner join teacher on course.teacher_id = teacher.tid;  # 只有表結構,沒有表數據,因為它的數據是基於其他表的。不建議使用,因為以後擴展sql語句的時候,視圖也需要跟著修改。

# 修改視圖
alter view teacher_view as select * from course where cid>3;

# 刪除視圖
drop view teacher_view


-- 2.觸發器  (一般不用,這個在應用程序級別能做,在應用程序級別能幹的活還是去自己幹好,以後擴展方便)
#準備表 CREATE TABLE cmd ( id INT PRIMARY KEY auto_increment, USER CHAR (32), priv CHAR (10), cmd CHAR (64), sub_time datetime, #提交時間 success enum (yes, no) #0代表執行失敗 ); CREATE TABLE errlog ( id INT PRIMARY KEY auto_increment, err_cmd CHAR (64), err_time datetime
); #創建觸發器 delimiter // # 定義sql語句的結束語 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 ; # 把結束符號還原回來 #往表cmd中插入記錄,觸發觸發器,根據IF的條件決定是否插入錯誤日誌
INSERT cmd ( USER, priv, cmd, sub_time, success ) VALUES (egon,0755,ls -l /etc,NOW(),yes), (egon,0755,cat /etc/passwd,NOW(),no), (egon,0755,useradd xxx,NOW(),no), (egon,0755,ps aux,NOW(),yes); # 刪除觸發器 drop trigger tri_after_insert_cmd; -- 3 存儲過程 # (1) 無參存儲過程 delimiter // create procedure p1() BEGIN select * from db7.teacher; END // delimiter ; # MySQL中調用 call p1(); # Python中調用 cursor.callproc(p1) # (2) 有參存儲過程。不但要指定是接收還是返回,還要指定類型 delimiter // create procedure p2(in n1 int,in n2 int,out res int) BEGIN select * from db7.teacher where tid > n1 and tid < n2; set res = 1; END // delimiter ; # inout 可進可出 了解就行 # MySQL中調用 set @x=0 call p2(2,4,@x); select @x; # 查看返回值結果 # Python中調用 cursor.callproc(p2,(2,4,0)) # @_p2_0=2,@_p2_1=4,@_p2_2=0 cursor.excute(select @_p3_2) cursor.fetchall() ## 應用程序和數據庫結合使用 ### 方式一: MySQL: 編寫存儲過程 python:調用存儲過程 ### 方式二: Python:編寫純生SQL MySQL:什麽都不用幹 ### 方式三: Python:ORM --> 純生SQL MySQL: # 運行效率方式二高,開發效率方式三高(運行效率比方式二慢不了多少),我們主要是用方式三,偶爾用方式二,很少會去用方式一,除非一個人應用程序開發和DBA開發都很厲害。

pymysql儲存過程的執行

# 1、增刪改
import pymysql

# 建立鏈接
conn = pymysql.connect(
    host=127.0.0.1,
    port=3306,
    user=root,
    password=112233,
    db=db7,
    charset=utf8
)
# 拿遊標
cursor = conn.cursor(pymysql.cursors.DictCursor)

# 執行sql
# cursor.callproc(‘p1‘)
# print(cursor.fetchall())

cursor.callproc(p2, (2, 4, 0))  # @_p2_)=2,@_p2_1=4,@_p3_2=0
cursor.execute(select @_p2_2)
print(cursor.fetchone())  # {‘@_p2_2‘: 1}


# 關閉遊標和鏈接
cursor.close()
conn.close()

二、事物

create table user(
id int primary key auto_increment,
name char(32),
balance int
);

insert into user(name,balance)
values
(wsb,1000),
(egon,1000),
(ysb,1000);

#原子操作
start transaction;
update user set balance=900 where name=wsb; #買支付100元
update user set balance=1010 where name=egon; #中介拿走10元
update user set balance=1090 where name=ysb; #賣家拿到90元
commit;

#出現異常,回滾到初始狀態
start transaction;
update user set balance=900 where name=wsb; #買支付100元
update user set balance=1010 where name=egon; #中介拿走10元
uppdate user set balance=1090 where name=ysb; #賣家拿到90元,出現異常沒有拿到
rollback;
commit;

三、函數和流程控制

#1 準備表和記錄
CREATE TABLE blog (
    id INT PRIMARY KEY auto_increment,
    NAME CHAR (32),
    sub_time datetime
);

INSERT blog (NAME, sub_time)
VALUES
    (第1篇,2015-03-01 11:31:21),
    (第2篇,2015-03-11 16:31:21),
    (第3篇,2016-07-01 10:21:31),
    (第4篇,2016-07-22 09:23:21),
    (第5篇,2016-07-23 10:11:11),
    (第6篇,2016-07-25 11:21:31),
    (第7篇,2017-03-01 15:33:21),
    (第8篇,2017-03-01 17:32:21),
    (第9篇,2017-03-01 18:31:21);
   
#2. 提取sub_time字段的值,按照格式後的結果即"年月"來分組

select date_format(sub_time,%Y-%m),count(id) from blog group by date_format(sub_time,%Y-%m);

四、索引原理

#1. 準備表
create table s1(
id int,
name varchar(20),
gender char(6),
email varchar(50)
);

#2. 創建存儲過程,實現批量插入記錄
delimiter $$ #
create procedure auto_insert1()
BEGIN
    declare i int default 1;
    while (i<3000000) do
        insert into s1 values(i,egon,male,concat(egon,i,@oldboy));
        set i=i+1;
    end while;
END$$
delimiter ; 

#3. 查看存儲過程
show create procedure auto_insert1\G 

#4. 調用存儲過程
call auto_insert1();

#無索引:mysql根本就不知道到底是否存在id等於333333333的記錄,只能把數據表從頭到尾掃描一遍,此時有多少個磁盤塊就需要進行多少IO操作,所以查詢速度很慢
mysql> select * from s1 where id=333333333;
Empty set (0.33 sec)

# 創立索引前
select count(id) from s1 where id = 1000
1 row in set (0.80 sec)

# 創立索引
create index idx_id on s1(id)
Query OK, 0 rows affected (2.63 sec)
Records: 0  Duplicates: 0  Warnings: 0

# 創立索引後
select count(id) from s1 where id = 1000;
1 row in set (0.00 sec)

mysql內置功能