日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

【連載電子書十】Pymysql 數(shù)據(jù)庫(kù)詳解

 O聽_海_軒O 2020-09-10

0. 前言

1. MySQL安裝

2. 建庫(kù), 建表

3. 基礎(chǔ)SQL語(yǔ)句

1. 增加

2. 修改

3. 刪除

4. 查詢

4. 分組查詢

5. 排序

6. 分頁(yè)

7. 多表查詢

1. 子查詢

2. 關(guān)聯(lián)查詢

8. 其他雜七雜八(對(duì)于新手小白了解即可)

9. pymysql

作業(yè):

1. 基本SQL語(yǔ)句(慢慢做,  做一個(gè)月)

2. 使用pymysql完成業(yè)務(wù)線系統(tǒng)開發(fā).

0. 前言

數(shù)據(jù)庫(kù)其實(shí)并不高深, 它就是一個(gè)能存儲(chǔ)數(shù)據(jù)到硬盤上的一個(gè)軟件. 本質(zhì)就是一個(gè)軟件.  數(shù)據(jù)庫(kù)承載了我們目前市面上能見到的絕大多數(shù)的軟件最底層的數(shù)據(jù)支持. 可以這么說(shuō). 如果沒(méi)有數(shù)據(jù),  就沒(méi)有目前互聯(lián)網(wǎng)的高速發(fā)展. 而數(shù)據(jù)庫(kù)作為承載數(shù)據(jù)的載體. 它的地位也是非常高的.

數(shù)據(jù)庫(kù)的分類:

早期, 數(shù)據(jù)庫(kù)分為層次型數(shù)據(jù)庫(kù), 網(wǎng)絡(luò)型數(shù)據(jù)庫(kù)和關(guān)系型數(shù)據(jù)庫(kù),  在今天的互聯(lián)網(wǎng)高速發(fā)展下, 數(shù)據(jù)庫(kù)被分為關(guān)系型數(shù)據(jù)庫(kù)和非關(guān)系型數(shù)據(jù)庫(kù).

關(guān)系型數(shù)據(jù)庫(kù)

關(guān)系型數(shù)據(jù)庫(kù)把復(fù)雜的數(shù)據(jù)邏輯歸納為二元結(jié)構(gòu)(二維表格結(jié)構(gòu)), 并且, 表格與表格之間可以互相的關(guān)聯(lián). 讓數(shù)據(jù)的存儲(chǔ)和查詢都變得更加合理簡(jiǎn)單.

常見的關(guān)系型數(shù)據(jù)庫(kù):

1. MySql. 小巧, 免費(fèi). 功能強(qiáng)大. 目前市場(chǎng)上的大多數(shù)互聯(lián)網(wǎng)公司都在使用.

2. Microsoft SQL Server,  微軟提供的數(shù)據(jù)庫(kù)系統(tǒng). 功能強(qiáng)大. 但只能在windows平臺(tái)使用.

3. Oracle, Oracle公司出品, 功能強(qiáng)大. 數(shù)據(jù)處理速度快. 穩(wěn)定. 缺點(diǎn): 貴. Oracle數(shù)據(jù)庫(kù)下載和使用都免費(fèi), 但是, 如果商用就很貴了.  而且Oracle的維護(hù)成本也要比其他數(shù)據(jù)庫(kù)要高很多.

4. DB2, IMB提供的數(shù)據(jù)庫(kù)系統(tǒng). 主要運(yùn)行在unix上. 一般在我們生活中是很少見到的. 只有在一些對(duì)硬件穩(wěn)定性要求非常高的情況下會(huì)選擇使用. 當(dāng)然. 你想用DB2必須先來(lái)一臺(tái)IMB的服務(wù)器. 那個(gè)價(jià)格爽死你.

非關(guān)系型數(shù)據(jù)庫(kù)

非關(guān)系型數(shù)據(jù)庫(kù)也被稱為NoSql.  首先, SQL是我們操作數(shù)據(jù)庫(kù)的編程語(yǔ)言. 專門為數(shù)據(jù)庫(kù)而設(shè)計(jì)的. NoSql表示Not Only SQL,   NoSQL的產(chǎn)生不是說(shuō)徹底否定關(guān)系型數(shù)據(jù)庫(kù)的存在, 而是對(duì)常見的關(guān)系型數(shù)據(jù)庫(kù)進(jìn)行補(bǔ)充. 目的是更好的為應(yīng)用程序提供數(shù)據(jù)支撐. 傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù)在遇到高并發(fā), 大量數(shù)據(jù)IO請(qǐng)求的時(shí)候會(huì)顯得力不從心. 此時(shí)NoSQL就派上用場(chǎng)了. 主旨是更快的為應(yīng)用提供數(shù)據(jù). 承載更多的并發(fā).

常見的非關(guān)系型數(shù)據(jù):

1. Redis 可以對(duì)數(shù)據(jù)進(jìn)行緩存(內(nèi)存), 也可以持久化保存數(shù)據(jù)(硬盤). 非常容易搭建集群以及主從復(fù)制.

2. Memcache     主要是對(duì)數(shù)據(jù)進(jìn)行緩存(內(nèi)存)

3. MongoDB      是一個(gè)介于nosql數(shù)據(jù)庫(kù)和mysql數(shù)據(jù)庫(kù)之間的一個(gè)數(shù)據(jù)存儲(chǔ)系統(tǒng)

4. Elasticsearch  一個(gè)全文檢索的搜索引擎.

我們前期的重點(diǎn)在mysql上. 原因有

1. Mysql免費(fèi), 而且小巧, 無(wú)論是安裝還是使用都非常的簡(jiǎn)單容易

2. 功能強(qiáng)大. 麻雀雖小五臟俱全, 各個(gè)大型數(shù)據(jù)庫(kù)擁有的功能它幾乎都支持

3. 市場(chǎng)認(rèn)可度高.

1. MySQL安裝

mysql是一個(gè)小型的DBMS, 但是麻雀雖小, 五臟俱全.  各種大型數(shù)據(jù)庫(kù)的操作MySQL都有,  首先, 我們來(lái)安裝一下MySQL.  

首先, 去官網(wǎng)下載MySQL

不同平臺(tái)有不同的安裝方案:

windows:  https://dev./downloads/installer/

下面是安裝windows需要的插件

裝完了. 配置一下下環(huán)境變量

把上面那個(gè)路徑扔到path里面

確定, 一路保存確認(rèn)就可以了.  很easy好吧.

測(cè)試: 打開cmd. 輸入命令:

mysql -u root -p

回車之后, 輸入密碼.  最終見到以下內(nèi)容, 視為沒(méi)毛病

navicat安裝:

激活過(guò)程自己想辦法吧....

2. 建庫(kù), 建表

數(shù)據(jù)庫(kù)系統(tǒng)包括:

數(shù)據(jù)庫(kù)(DB): 存放數(shù)據(jù)的地方, 主要是存儲(chǔ)數(shù)據(jù)的硬件以及存儲(chǔ)的數(shù)據(jù)結(jié)構(gòu)算法.

數(shù)據(jù)庫(kù)管理系統(tǒng)(DBMS): 用來(lái)操縱數(shù)據(jù)庫(kù)的地方. DBMS是數(shù)據(jù)庫(kù)系統(tǒng)的基礎(chǔ)與核心. 我們程序員最關(guān)心的就是這里. DBMS也是我們操縱數(shù)據(jù)庫(kù)唯一的途徑和手段.

大部分的DBMS提供了

DCL(Data Control Language), 數(shù)據(jù)庫(kù)控制語(yǔ)言, 主要是對(duì)用戶或者角色進(jìn)行授權(quán).

DDL(data definition language),  數(shù)據(jù)定義語(yǔ)言. 主要用來(lái)創(chuàng)建和刪除數(shù)據(jù)表的.

DML(data manipulation language),數(shù)據(jù)操縱語(yǔ)言, 這個(gè)是我們關(guān)注的核心. 專門用來(lái)操縱數(shù)據(jù)的. 比如, 添加數(shù)據(jù), 刪除數(shù)據(jù), 修改數(shù)據(jù), 查詢數(shù)據(jù)等等.

DDL: 數(shù)據(jù)定義語(yǔ)句

1. 創(chuàng)建數(shù)據(jù)庫(kù), 在mysql中, 保存數(shù)據(jù)最大的單位就是數(shù)據(jù)庫(kù). 一般中小型項(xiàng)目都是一個(gè)項(xiàng)目一個(gè)數(shù)據(jù)庫(kù). 如果遇見大型項(xiàng)目, 單一的數(shù)據(jù)庫(kù)可能就撐不住前端的數(shù)據(jù)量了. 此時(shí)可能會(huì)涉及到多數(shù)據(jù)庫(kù)設(shè)計(jì). 我們剛?cè)腴T, 先學(xué)習(xí)但數(shù)據(jù)庫(kù)操作.

 -- 創(chuàng)建數(shù)據(jù)庫(kù)
-- CREATE DATABASE 數(shù)據(jù)庫(kù)名;
 
-- 創(chuàng)建數(shù)據(jù)庫(kù), 指定字符集
 CREATE DATABASE IF NOT EXISTS 數(shù)據(jù)庫(kù)名 DEFAULT CHARSET UTF8mb4;
 -- 刪除數(shù)據(jù)庫(kù)
DROP DATABASE IF EXISTS 數(shù)據(jù)庫(kù)名;
  

2. 表操作.  關(guān)系型數(shù)據(jù)庫(kù)使用二維表的形式來(lái)存儲(chǔ)數(shù)據(jù). 就像Excel差不多. 有行和列. 創(chuàng)建表的時(shí)候我們要指定每一列的含義, 也就是列名, 在后面使用的時(shí)候. 數(shù)據(jù)是以行為單位進(jìn)行查詢的. 然后從行內(nèi)拿到你想要獲取的列. 就拿到你想要的數(shù)據(jù)了

-- 建表語(yǔ)句
 CREATE TABLE IF NOT EXISTS 表名(
列名 類型(長(zhǎng)度) 約束,
    列名 類型(長(zhǎng)度) 約束
);

類型:

數(shù)字一般用int, 還有bit, long等, 但用的不多

字符串: char, varchar. 其中char表示定長(zhǎng)的列. varchar表示不定長(zhǎng)的列

char(32)  如果你只存儲(chǔ)一個(gè)字母. 占用的空間也是32個(gè)

varchar(32) 如果值存儲(chǔ)一個(gè)字母, 你可以認(rèn)為就占用1個(gè)位置.

時(shí)間:

date    年月日

time    小時(shí)分鐘秒

datetime  年月日, 時(shí)分秒

小數(shù):

float     單精度小數(shù)

double 雙精度小數(shù)

decimal  小數(shù)-> 精度可以自己進(jìn)行設(shè)定. 精度高, 誤差小

約束:

主鍵約束: 可以唯一的表示一條數(shù)據(jù), 我們可以使用主鍵來(lái)確定具體的某個(gè)人. 就像我們生活中的身份證號(hào), 通過(guò)身份證號(hào)可以唯一的確定一個(gè)人. 通常我們都是使用主鍵自增來(lái)維護(hù)主鍵.

語(yǔ)法: primary key

主鍵自增: 在添加數(shù)據(jù)的時(shí)候. 主鍵不需要給出具體的值. 由mysql自動(dòng)來(lái)維護(hù)這個(gè)字段, 自動(dòng)的在原有的數(shù)據(jù)基礎(chǔ)上+1.

語(yǔ)法: AUTO_INCREMENT

非空約束: 設(shè)置該列是否可以為空

語(yǔ)法: null 或者 not null

默認(rèn)值: 在沒(méi)有數(shù)據(jù)的情況下, 可以給出默認(rèn)值

default 值

唯一性約束:

unique

 -- 建表語(yǔ)句
CREATE TABLE IF NOT EXISTS stu(
  id int(6) primary key AUTO_INCREMENT,
name varchar(100) not null,
  age int(5) default 0 COMMENT '年齡',
birthday date,
  salary decimal(10, 2) default 0.0,
sno int(5) unique,
  phone char(11) not null unique
);
 -- 刪除表
DROP TABLE IF EXISTS stu;
 -- 修改表字段信息
-- 添加新字段
 ALTER TABLE stu add address VARCHAR(200);
 -- 刪除字段
ALTER TABLE stu DROP COLUMN address;
 
-- 修改字段類型
 ALTER TABLE stu MODIFY sno varchar(32) unique not null;

3. 基礎(chǔ)SQL語(yǔ)句

1. 增加

語(yǔ)法:
insert into (字段1, 字段2, 字段3....) values(1,2,3....)
-- 添加數(shù)據(jù)
insert into person(name, age, phone) values('牛魔王', 88, '19812345678');
-- 一次性添加多條數(shù)據(jù)
insert into person(name, age, phone) values
('小鉆風(fēng)1',22, '18811112221'),
('小鉆風(fēng)2',22, '18811112222'),
('小鉆風(fēng)3',22, '18811112223'),
('小鉆風(fēng)4',22, '18811112224');

2. 修改

語(yǔ)法: 
update 表 set 字段1 =1, 字段2 =2, 字段3 =3 ..... where 條件
-- 修改數(shù)據(jù)
update person set name = '唐僧', age = 29, phone='14722223333' where id = '5';

3. 刪除

語(yǔ)法:
delete from table where 條件
注意: 必須加條件, 否則全表刪除
-- 刪除數(shù)據(jù)
delete from person; --  全表刪除. 慎用
delete from person where id = 3; -- 刪除id=3的數(shù)據(jù)
delete from person where name = '小鉆風(fēng)1'; -- 刪除名字叫小鉆風(fēng)1的數(shù)據(jù)
delete from person where name like '小鉆風(fēng)%'; -- 刪除名字以小鉆風(fēng)開頭的數(shù)據(jù) like表示模糊查找, 小鉆風(fēng)% 表示以小鉆風(fēng)開頭

4. 查詢

select  *|[distinct]字段1, 字段2, 字段3... from 表 where 條件 [group by] [having] [order by]
-- 查詢出person表中的所有數(shù)據(jù)
select  * from person;
-- 查詢部分字段
select id, name, age from person;
-- 給查詢出來(lái)的數(shù)據(jù)進(jìn)行重命名
select id as '主鍵ID', name as '名字', age as '年齡' from person;

上條件:

-- 查詢出年齡大于20歲的人
select * from person where age > 20;
-- 查詢電話號(hào)是14722223333的人
select * from person where phone = '14722223333';
-- 查詢年齡是空的人
select * from person where age is null;  
-- 年齡在2022之間的人
select * from person where age BETWEEN 20 and 22;
-- 查詢手機(jī)號(hào)是13778787878,14722223333,18811111111的人
select * from person where phone in (13778787878,14722223333,18811111111);
-- 多個(gè)where條件, 可以使用and, or進(jìn)行連接
-- 查詢年齡大于19 手機(jī)號(hào)以14開頭的人
select * from person where age > 19 and phone like '14%';
-- 查詢年齡大于20 或者名字是唐僧的人
select * from person where age > 20 or name = '唐僧';

4. 分組查詢

分組查詢: 按組進(jìn)行查詢, 分組需要使用group by語(yǔ)句

-- 分組查詢.
-- 根據(jù)名字和年齡進(jìn)行分組. 
select age, name from person group by age, name;

分組查詢一般配合聚合函數(shù)一起使用.

sum() 求和

avg() 平均值

max() 最大值

min() 最小值

count() 計(jì)數(shù)

-- 聚合函數(shù)
-- 查詢所有人的平均年齡
select avg(age) from person
-- 查詢每個(gè)班級(jí)的平均年齡
select cls, avg(age) from person group by cls;
-- 查詢每個(gè)班的人數(shù)
select cls, count(id) from person group by cls;
-- 查詢每個(gè)班級(jí)年齡最大的學(xué)生
select cls, max(age) from person group by cls;
-- 查詢每個(gè)班級(jí)年齡最小的學(xué)生
select cls, min(age) from person group by cls;
-- 查詢每個(gè)班級(jí)的年齡總和
select cls, sum(age) from person group by cls;

使用having子句可以對(duì)分組查詢之后的結(jié)果進(jìn)行篩選.

-- 查詢平均年齡大有20的班級(jí)信息
select cls, avg(age) from person group by cls having avg(age) > 20;

having和where都可以做數(shù)據(jù)的篩選. 區(qū)別是:

where是在原始數(shù)據(jù)上進(jìn)行數(shù)據(jù)篩選

having是在分組計(jì)算之后的結(jié)果進(jìn)行篩選.

它們起作用的時(shí)機(jī)是不一樣的

5. 排序

使用order by子句可以完成數(shù)據(jù)的排序工作

-- 按照年齡的從小到大排序
select * from person order by age;
select * from person order by age asc;
-- 按照年齡的從大到小排序
select * from person order by age desc;

6. 分頁(yè)

-- 分頁(yè)查詢
select * from student limit 0, 10  -- 從第0條開始查詢, 查詢10條數(shù)據(jù)
select * from student limit 10, 10 -- 從第10條開始查詢, 查詢10條數(shù)據(jù)
-- 查詢第n頁(yè)數(shù)據(jù)
select * from student limit (n-1)*pageSize, pageSize;

7. 多表查詢

首先, 在一個(gè)項(xiàng)目里肯定不能都把數(shù)據(jù)放在一張表里.  比如, 我們把員工信息都存放在一張表里:

大家觀察一下.  員工信息沒(méi)問(wèn)題. 但是員工相應(yīng)的部門信息就有大量的數(shù)據(jù)冗余.  如果一直用這樣的數(shù)據(jù)來(lái)保存數(shù)據(jù).  那么冗余的數(shù)據(jù)會(huì)占用大量的硬盤存儲(chǔ)空間. 數(shù)據(jù)庫(kù)的利用率就變的很低. 所以此時(shí)我們要考慮. 把部門信息單獨(dú)的拿到另一張表里. 然后把部門表的主鍵引入到員工表里. 這樣從結(jié)構(gòu)和邏輯上講, 效果是一樣的. 但是存儲(chǔ)空間就會(huì)節(jié)省很多.

分表:

員工表

部門表

這樣, 我們通過(guò)查詢員工表信息就能知道員工的deptId, 再通過(guò)deptId,到部門表就能找到該員工對(duì)應(yīng)的部門信息. 最終查詢出的數(shù)據(jù)是一致的.

OK, 分表結(jié)束了. 但是, 這里我們必須要保證員工表中的deptId的數(shù)據(jù)來(lái)源必須是部門表. 如果deptId是胡亂填寫的. 那該員工的部門信息就是錯(cuò)誤的. 為了保證數(shù)據(jù)的一致性和安全性. 我們此時(shí)需要對(duì)deptId這一列數(shù)據(jù)進(jìn)行約束. 該約束被稱為外鍵約束.

外鍵約束: 某字段的數(shù)據(jù)值來(lái)源必須來(lái)自于xxx表的xxx字段. 通常我們都是把另一張表的主鍵拿到當(dāng)前表來(lái)做外鍵.  在本案例中, 我們就可以把部門表的id拿到員工表中做外鍵. 外鍵的名字叫deptId

create table dept(
id int(10) primary key auto_increment,
deptName VARCHAR(200),
deptLeader VARCHAR(200),
deptDesc VARCHAR(200)
);
-- 然后創(chuàng)建employee表, 并添加外鍵
CREATE TABLE employee (
id int(10) primary key auto_increment,
name varchar(60),
age int(3),
deptId int(10),
constraint fk_emp_dept_id FOREIGN KEY (deptId) REFERENCES dept(id)  # 添加外鍵約束
);

多表聯(lián)合查詢:

1. 子查詢

-- 子查詢
-- 查詢'明教'的員工信息
select * from employee 
where deptId in (
select id from dept where dept.deptName = '明教'
);
-- 查詢員工和部門的全部信息
select * from employee, dept where employee.deptId = dept.id;
-- 查詢'峨眉派'的平均工資
select avg(salary), deptName from employee, dept
where deptId in (
select dept.id from dept where deptName = '峨眉派'
) and employee.deptId = dept.id group by deptName;

2. 關(guān)聯(lián)查詢

在sql語(yǔ)句中. 還有一種語(yǔ)法可以讓兩張甚至多張表進(jìn)行關(guān)聯(lián)查詢.

1. inner join  內(nèi)連接

2. left join  左連

3. right join 右連

select * from A xxx join B on A.字段1 = b.字段2
表示:  A表和B表鏈接. 通過(guò)A表的字段1和b表的字段2進(jìn)行連接. 通常on后面的都是主外鍵關(guān)系
-- 查詢員工和部門的全部信息
-- 內(nèi)連接
select * from employee inner join dept on employee.deptId = dept.id;
-- 左聯(lián)
select * from employee left join dept on employee.deptId = dept.id;
-- 右聯(lián)
select * from employee right join dept on employee.deptId = dept.id;

8. 其他雜七雜八(對(duì)于新手小白了解即可)

索引. 當(dāng)我們的數(shù)據(jù)量很大的時(shí)候. 查詢的速度會(huì)明顯的下降.  尤其涉及到全表檢索的時(shí)候, 此時(shí)查詢效率會(huì)低到令人發(fā)指.  在數(shù)據(jù)庫(kù)系統(tǒng)中, 可以通過(guò)添加索引來(lái)加快查詢的速度.

索引: 按照一定的數(shù)據(jù)結(jié)構(gòu), 將該列的數(shù)據(jù)進(jìn)行特殊處理. 用來(lái)提高查詢速度.

默認(rèn)情況下, 我們?cè)O(shè)計(jì)的每一個(gè)主鍵, 都會(huì)自動(dòng)把主鍵設(shè)置成索引. 所以我們查詢的時(shí)候. 如果是按照主鍵來(lái)搜索數(shù)據(jù), 查詢的效率和速度都是最快的.

索引的優(yōu)點(diǎn): 提高查詢速度

索引的缺點(diǎn): 由于每次添加新數(shù)據(jù)都會(huì)讓索引重新進(jìn)行排列. 如果頻繁的涉及添加和刪除數(shù)據(jù). 反而會(huì)讓數(shù)據(jù)庫(kù)的執(zhí)行效率變低.

 -- 創(chuàng)建索引
create index student_name_index on student(sname);
 -- 刪除索引
drop index student_name_index on student;

當(dāng)我們遇見復(fù)雜的sql語(yǔ)句的時(shí)候. 我們可以把一部分查詢的結(jié)果(sql) 保存在視圖. 方便后面查詢的時(shí)候可以簡(jiǎn)化sql語(yǔ)句.

-- 創(chuàng)建視圖
create view my_view as
select sname, score from student s inner join sc on s.sid = sc.sid
-- 使用視圖來(lái)查詢數(shù)據(jù)
select * from my_view;
-- 刪除視圖
drop view my_view;

注意: 視圖只是簡(jiǎn)化查詢的sql語(yǔ)句. 并不能提高性能. 也就是說(shuō)以上代碼和不適用視圖的查詢效率是一致的.

觸發(fā)器: 在執(zhí)行某些操作的時(shí)候, 去執(zhí)行一些其他的操作

例如:  假設(shè), 我們現(xiàn)在要?jiǎng)h除一些數(shù)據(jù)庫(kù)中的數(shù)據(jù). 很容易, 寫個(gè)delete語(yǔ)句就OK了. 但是, 如果過(guò)了1個(gè)小時(shí)之后, 我們突然發(fā)現(xiàn)刪除的數(shù)據(jù)是有用的. 想要恢復(fù)回來(lái). 此時(shí)如果沒(méi)有任何的備份和日志存在的話, 幾乎是不可能的. 那怎么辦?  我們可以在刪除數(shù)據(jù)之前, 把要?jiǎng)h除的數(shù)據(jù)備份出來(lái). 保存在另一張表中. 萬(wàn)一要恢復(fù)的話. 直接從另一張表里就可以把數(shù)據(jù)讀取出來(lái). 防止數(shù)據(jù)丟失. 但, 此時(shí)如果我們每次執(zhí)行一條刪除語(yǔ)句之前都要多寫一個(gè)插入語(yǔ)句的話. 就會(huì)顯得很繁瑣. 此時(shí)我們可以把這個(gè)工作交給觸發(fā)器來(lái)完成. 當(dāng)觸發(fā)器設(shè)置好之后. 一旦有人刪除數(shù)據(jù). 就可以自動(dòng)的把你的數(shù)據(jù)保存起來(lái).

CREATE TRIGGER 名字
    BEFORE|AFTER
INSERT|DELETE|UPDATE
    ONFOR EACH ROW
BEGIN
    sql
END;
-- 創(chuàng)建觸發(fā)器
CREATE TRIGGER trigger_student_del
BEFORE DELETE
ON student FOR EACH ROW
BEGIN
insert into student_backup(sname, sage, ssex) values (old.sname, old.sage, old.ssex);
END;
-- 刪除學(xué)生信息
delete from student where sid = 3
-- 查看
select * from student;
select * from student_backup;
-- 刪除觸發(fā)器
drop trigger trigger_student_del;

old在觸發(fā)器里表示要?jiǎng)h除的舊數(shù)據(jù). 也可以認(rèn)為是現(xiàn)在目前數(shù)據(jù)庫(kù)中的數(shù)據(jù), 在刪除的時(shí)候拿到的就是old

new表示新數(shù)據(jù). 即. 即將進(jìn)入數(shù)據(jù)庫(kù)的數(shù)據(jù). 在新增的時(shí)候拿到的就是new

在修改數(shù)據(jù)的時(shí)候, 原來(lái)的數(shù)據(jù)用old表示, 新數(shù)據(jù)用new來(lái)表示

9. pymysql

1. 安裝pymysql

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pymysql

2. 使用pymysql 完成數(shù)據(jù)庫(kù)連接

import pymysql
from pymysql.cursors import DictCursor
# 連接數(shù)據(jù)庫(kù)
db = pymysql.connect('127.0.0.1', 'root', 'test123456', 'homework')
# 獲取游標(biāo)
cursor = db.cursor(DictCursor) # 結(jié)果保存在字典中. 默認(rèn)保存在元組中
# 執(zhí)行sql
cursor.execute('select version()') # 執(zhí)行sql語(yǔ)句
# 拿到結(jié)果
print(cursor.fetchone())  # 拿一個(gè)結(jié)果
print(cursor.fetchall()) # 拿出所有結(jié)果
print(cursor.fetchmany(10))  # 拿出n個(gè)數(shù)據(jù)

3. 使用pymysql完成各種數(shù)據(jù)庫(kù)操作(增刪改)

import pymysql
from pymysql.cursors import DictCursor
# 連接數(shù)據(jù)庫(kù)
db = pymysql.connect('127.0.0.1', 'root', 'test123456', 'homework')
cursor = db.cursor(DictCursor)
try:
    sql = 'INSERT INTO student(sname, sage, ssex) VALUE ('馬虎疼', 18, 1)'
cursor.execute(sql)
    db.commit()  # 提交事務(wù). 保證數(shù)據(jù)沒(méi)問(wèn)題
except Exception as e:
    db.rollback()  # 事務(wù)回滾. 回到原來(lái)狀態(tài)
print(e)
finally:
    cursor.close()  # 關(guān)閉游標(biāo)
db.close() # 關(guān)閉鏈接

4. 查詢操作

import pymysql
from pymysql.cursors import DictCursor
db = pymysql.connect('127.0.0.1', 'root', 'test123456', 'homework')
cursor = db.cursor(DictCursor)
sql = 'select * from student'
cursor.execute(sql)
# lst = cursor.fetchall() # 獲取查詢結(jié)果
# print(lst)
for row in cursor:  # 直接循環(huán)出結(jié)果
print(row)

5. sql注入以及未來(lái)寫sql的注意事項(xiàng)

import pymysql
from pymysql.cursors import DictCursor
db = pymysql.connect('127.0.0.1', 'root', 'test123456', 'homework')
cursor = db.cursor(DictCursor)
username = input('請(qǐng)輸入用戶名:')
password = input('請(qǐng)輸入密碼:')
sql = f'select * from user where username = '{username}' and password = '{password}''
cursor.execute(sql)
one = cursor.fetchone()
if one:
    print('登錄成功')
else:
print('登錄失敗')
輸入密碼的時(shí)候搞點(diǎn)兒事情
請(qǐng)輸入用戶名:alex
請(qǐng)輸入密碼:1' or '1'='1
登錄成功

神奇的一幕出現(xiàn)了,  為什么會(huì)這樣呢? 我們把sql拼接出來(lái)就知道咋回事兒了

select * from user where username = 'alex' and password = '1' or '1'='1'

注意看最后的條件  1 = 1 百分之百是成立的. 所以. 任何賬戶都能登錄成功. 所以. 這樣的操作是有問(wèn)題的.  那如何避免呢? 使用預(yù)處理方式就可以有效的屏蔽掉sql注入

import pymysql
from pymysql.cursors import DictCursor
db = pymysql.connect('127.0.0.1', 'root', 'test123456', 'homework')
cursor = db.cursor(DictCursor)
username = input('請(qǐng)輸入用戶名:')
password = input('請(qǐng)輸入密碼:')
sql = 'select * from user where username = %(username)s and password = %(password)s'
cursor.execute(sql, {'username': username, 'password': password})
one = cursor.fetchone()
if one:
    print('登錄成功')
else:
print('登錄失敗')

為防止sql注入, 以后寫sql.  盡量這么寫.

作業(yè):

1. 基本SQL語(yǔ)句(慢慢做,  做一個(gè)月)

每個(gè)學(xué)生可以學(xué)習(xí)多門課程, 并且, 每一門課程都有得分.  每一門課程都有老師來(lái)教. 一個(gè)老師可以教多個(gè)學(xué)生.

看題:

  1. 查詢姓“朱”的學(xué)生名單

  2. 查詢同名同性學(xué)生名單,并統(tǒng)計(jì)同名人數(shù)

  3. 查詢每門課程的平均成績(jī),結(jié)果按平均成績(jī)升序排列,平均成績(jī)相同時(shí),按課程號(hào)降序排列

  4. 查詢平均成績(jī)大于85的所有學(xué)生的學(xué)號(hào)、姓名和平均成績(jī)

  5. 查詢課程名稱為“睡覺(jué)”,且分?jǐn)?shù)低于60的學(xué)生姓名和分?jǐn)?shù)

  6. 查詢所有學(xué)生的選課情況

  7. 查詢?nèi)魏我婚T課程成績(jī)?cè)?0分以上的姓名、課程名稱和分?jǐn)?shù)

  8. 查詢每門課程被選修的學(xué)生數(shù)

  9. 查詢不同老師所教不同課程平均分從高到低顯示

  10. 按各科平均成績(jī)從低到高和及格率的百分?jǐn)?shù)從高到低順序

  11. 查詢和“2”號(hào)的同學(xué)學(xué)習(xí)的課程完全相同的其他同學(xué)學(xué)號(hào)和姓名

  12. 查詢學(xué)過(guò)“黃觀”老師所教的所有課的同學(xué)的學(xué)號(hào)、姓名.

  13. 把“SC”表中'黃觀'老師教的課的成績(jī)都更改為此課程的平均成績(jī)

  14. 查詢課程編號(hào)“2”的成績(jī)比課程編號(hào)“1”課程低的所有同學(xué)的學(xué)號(hào)、姓名

  15. 查詢沒(méi)學(xué)過(guò)“黃觀”老師課的同學(xué)的學(xué)號(hào)、姓名.

  16. 查詢平均成績(jī)大于60分的同學(xué)的學(xué)號(hào)和平均成績(jī)

初始化數(shù)據(jù):

DROP DATABASE IF EXISTS `homework`;
CREATE DATABASE `homework`;
USE `homework`;
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for course
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
`cid` int(3) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `cname` varchar(10) DEFAULT NULL,
`tid` int(3) DEFAULT NULL,
  KEY `fk` (`tid`),
CONSTRAINT `fk` FOREIGN KEY (`tid`) REFERENCES `teacher` (`tid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for sc
-- ----------------------------
DROP TABLE IF EXISTS `sc`;
CREATE TABLE `sc` (
`sid` int(3) DEFAULT NULL,
  `cid` int(3) DEFAULT NULL,
`score` int(3) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`sid` int(3) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `sname` varchar(30) DEFAULT NULL,
`sage` int(3) DEFAULT NULL,
  `ssex` int(3) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for teacher
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
  `tid` int(3) NOT NULL PRIMARY KEY  AUTO_INCREMENT,
`tname` varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records
-- ----------------------------
INSERT INTO `course` VALUES ('1', '吃飯', '1');
INSERT INTO `course` VALUES ('2', '睡覺(jué)', '1');
INSERT INTO `course` VALUES ('3', '八股', '2');
INSERT INTO `course` VALUES ('4', '讀書', '2');
INSERT INTO `course` VALUES ('5', '混', '2');
INSERT INTO `course` VALUES ('6', '聽歌', '2');
INSERT INTO `sc` VALUES ('1', '1', '50');
INSERT INTO `sc` VALUES ('1', '2', '50');
INSERT INTO `sc` VALUES ('1', '3', '30');
INSERT INTO `sc` VALUES ('1', '4', '80');
INSERT INTO `sc` VALUES ('1', '5', '10');
INSERT INTO `sc` VALUES ('2', '1', '70');
INSERT INTO `sc` VALUES ('2', '2', '55');
INSERT INTO `sc` VALUES ('2', '3', '35');
INSERT INTO `sc` VALUES ('2', '4', '95');
INSERT INTO `sc` VALUES ('2', '5', '78');
INSERT INTO `sc` VALUES ('3', '1', '55');
INSERT INTO `sc` VALUES ('3', '2', '85');
INSERT INTO `sc` VALUES ('3', '3', '74');
INSERT INTO `sc` VALUES ('3', '4', '47');
INSERT INTO `sc` VALUES ('3', '5', '61');
INSERT INTO `sc` VALUES ('4', '1', '55');
INSERT INTO `sc` VALUES ('4', '2', '87');
INSERT INTO `sc` VALUES ('4', '3', '85');
INSERT INTO `sc` VALUES ('4', '4', '76');
INSERT INTO `sc` VALUES ('4', '5', '87');
INSERT INTO `sc` VALUES ('5', '1', '55');
INSERT INTO `sc` VALUES ('5', '2', '5');
INSERT INTO `sc` VALUES ('5', '3', '3');
INSERT INTO `sc` VALUES ('5', '4', '34');
INSERT INTO `sc` VALUES ('5', '5', '40');
INSERT INTO `sc` VALUES ('6', '1', '100');
INSERT INTO `sc` VALUES ('6', '2', '100');
INSERT INTO `sc` VALUES ('6', '3', '100');
INSERT INTO `sc` VALUES ('6', '4', '75');
INSERT INTO `sc` VALUES ('6', '5', '71');
INSERT INTO `sc` VALUES ('7', '3', '50');
INSERT INTO `sc` VALUES ('7', '4', '55');
INSERT INTO `sc` VALUES ('7', '5', '47');
INSERT INTO `sc` VALUES ('8', '6', '50');
INSERT INTO `sc` VALUES ('9', '6', '55');
INSERT INTO `student` VALUES ('1', '朱元璋', '10', '1');
INSERT INTO `student` VALUES ('2', '朱棣', '20', '1');
INSERT INTO `student` VALUES ('3', '朱高熾', '20', '1');
INSERT INTO `student` VALUES ('4', '朱瞻基', '50', '1');
INSERT INTO `student` VALUES ('5', '萬(wàn)貴妃', '55', '2');
INSERT INTO `student` VALUES ('6', '慈禧', '50', '2');
INSERT INTO `student` VALUES ('7', '小郭子', '40', '1');
INSERT INTO `student` VALUES ('8', '于謙', '55', '1');
INSERT INTO `student` VALUES ('9', '猴哥', '5', '1');
INSERT INTO `teacher` VALUES ('1', '黃觀');
INSERT INTO `teacher` VALUES ('2', '商洛');

2. 使用pymysql完成業(yè)務(wù)線系統(tǒng)開發(fā).  

表關(guān)系:
管理員表:
        ID  用戶名   密碼    郵箱    
業(yè)務(wù)線:
        ID  名稱
主機(jī)表:
        ID  主機(jī)名  密碼  業(yè)務(wù)線ID
需求:
用戶登錄(密碼基于md5且加鹽)
    業(yè)務(wù)線管理:
添加業(yè)務(wù)線
        刪除業(yè)務(wù)線
修改業(yè)務(wù)線
        查看業(yè)務(wù)線
主機(jī)管理(含外鍵):
        添加主機(jī)
刪除主機(jī)
        修改主機(jī)
查看主機(jī)

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多