@(python)[筆記]
目錄
一、數(shù)據(jù)庫操作
1.1 數(shù)據(jù)庫管理
1.1.1 顯示
1.1.2 用戶管理
1.1.3 授權(quán)管理
1.2 數(shù)據(jù)表操作
1.2.1 創(chuàng)建表
數(shù)據(jù)類型
修飾符
1.2.2 刪除表
1.2.3 清空表
1.2.4 修改表
1.3 表內(nèi)容操作
1.3.1 增
1.3.2 刪
1.3.3 改
1.3.4 查
1.3.5 復雜查詢
二、Python操作MySQL
2.1 下載安裝
2.2 使用操作
2.2.1 執(zhí)行查詢操作
2.2.2 寫庫操作必須提交commit
2.2.3 直接獲取新增數(shù)據(jù)的自增ID
2.2.4 將查詢結(jié)果以字典形式返回
一欲险、數(shù)據(jù)庫操作
SQL語句分類:
SQL語句分為:
(1) DQL(數(shù)據(jù)查詢語言):select
(2) DDL(數(shù)據(jù)定義語言):create/drop/alter/truncate
(3) DML(數(shù)據(jù)操縱語言):insert/update/delete
(4) TCL(事務(wù)控制語言):commit/rollback/savepoint
(5) DCL(數(shù)據(jù)控制語言):grant/revoke
1.1 數(shù)據(jù)庫管理
1.1.1 顯示
SHOW DATABASES
//顯示所有數(shù)據(jù)庫
SHOW TABLES
//顯示所有數(shù)據(jù)表
USE db_name
//使用某個數(shù)據(jù)庫
默認的數(shù)據(jù)庫功能介紹
- mysql - 用戶權(quán)限相關(guān)數(shù)據(jù)
- test - 用于用戶測試數(shù)據(jù)
- information_schema - MySQL本身架構(gòu)相關(guān)數(shù)據(jù)
1.1.2 用戶管理
創(chuàng)建用戶
create user '用戶名'@'IP地址' identified by '密碼';
刪除用戶
drop user '用戶名'@'IP地址';
修改用戶
rename user '用戶名'@'IP地址'; to '新用戶名'@'IP地址';;
修改密碼
set password for '用戶名'@'IP地址' = Password('新密碼')
PS:用戶權(quán)限相關(guān)數(shù)據(jù)保存在mysql數(shù)據(jù)庫的user表中台谍,所以也可以直接對其進行操作(不建議)
1.1.3 授權(quán)管理
show grants for '用戶'@'IP地址'; -- 查看權(quán)限
grant 權(quán)限 on 數(shù)據(jù)庫.表 to '用戶'@'IP地址'; -- 授權(quán)
revoke 權(quán)限 on 數(shù)據(jù)庫.表 from '用戶'@'IP地址'; -- 取消權(quán)限
權(quán)限列表
權(quán)限名稱 | 權(quán)限功能 |
---|---|
all privileges | 除grant外的所有權(quán)限 |
select | 僅查權(quán)限 |
select,insert | 查和插入權(quán)限 |
usage | 無訪問權(quán)限 |
alter | 使用alter table |
alter routine | 使用alter procedure和drop procedure |
create | 使用create table |
create routine | 使用create procedure |
create temporary tables | 使用create temporary tables |
create user | 使用create user须喂、drop user、rename user和revoke all privileges |
create view | 使用create view |
delete | 使用delete |
drop | 使用drop table |
execute | 使用call和存儲過程 |
file | 使用select into outfile 和 load data infile |
grant option | 使用grant 和 revoke |
index | 使用index |
insert | 使用insert |
lock tables | 使用lock table |
process | 使用show full processlist |
select | 使用select |
show databases | 使用show databases |
show view | 使用show view |
update | 使用update |
reload | 使用flush |
shutdown | 使用mysqladmin shutdown(關(guān)閉MySQL) |
super | <dbff><dc42><dbff><dc08>使用change master趁蕊、kill坞生、logs、purge掷伙、master和set global是己。還>允許mysqladmin<dbff><dd57><dbff><dd58><dbff><dc8a><dbff><dc8b>調(diào)試登陸 |
replication client | 服務(wù)器位置的訪問 |
replication slave | 由復制從屬使用 |
對于數(shù)據(jù)庫
對于目標數(shù)據(jù)庫以及內(nèi)部其他:
數(shù)據(jù)庫表示 | 說明 |
---|---|
數(shù)據(jù)庫名.* | 數(shù)據(jù)庫中的所有 |
數(shù)據(jù)庫名.表 | 指定數(shù)據(jù)庫中的某張表 |
數(shù)據(jù)庫名.存儲過程 | 指定數(shù)據(jù)庫中的存儲過程 |
*.* | 所有數(shù)據(jù)庫 |
對于用戶和IP地址
表示方法 | 說明 |
---|---|
用戶名@IP地址 | 用戶只能在改IP下才能訪問 |
用戶名@192.168.1.% | 用戶只能在改IP段下才能訪問(通配符%表示任意) |
用戶名@% | 用戶可以再任意IP下訪問(默認IP地址為%) |
刷新權(quán)限列表
flush privileges
//將數(shù)據(jù)讀取到內(nèi)存中,從而立即生效
root忘記密碼解決辦法
# 啟動免授權(quán)服務(wù)端
mysqld --skip-grant-tables
# 客戶端
mysql -u root -p
# 修改用戶名密碼
update mysql.user set authentication_string=password('666') where user='root';
#刷新權(quán)限列表
flush privileges;
1.2 數(shù)據(jù)表操作
1.2.1 創(chuàng)建表
create table 表名(
列名 類型 是否可以為空炎咖,
列名 類型 是否可以為空
)ENGINE=InnoDB DEFAULT CHARSET=utf8
數(shù)據(jù)類型
1. 數(shù)值類型
數(shù)值類型 | 字節(jié) | 范圍(有符號) | 范圍(無符號) | 用途 |
---|---|---|---|---|
TINYINT 整數(shù) | 1字節(jié) | (-128赃泡,127) | (0,255) | 小整數(shù)值 |
SMALLINT 整數(shù) | 2字節(jié) | (-32 768乘盼,32 767) | (0升熊,65 535) | 大整數(shù)值 |
MEDIUMINT 整數(shù) | 3字節(jié) | (-8 388 608,8 388 607) | (0绸栅,16 777 215) | 大整數(shù)值 |
INT或INTEGER 整數(shù) | 4字節(jié) | (-2 147 483 648级野,2 147 483 647) | (0,4 294 967 295) | 大整數(shù)值 |
BIGINT 整數(shù) | 8字節(jié) | (-9 233 372 036 854 775 808粹胯,9 223 372 036 854 775 807) | (0蓖柔,18 446 744 073 709 551 615) | 極大整數(shù)值 |
FLOAT 浮點數(shù) | 4字節(jié) | (-3.402 823 466 E+38,1.175 494 351 E-38) | (0风纠,3.402 823 466 351 E+38) | 單精度浮點數(shù)值 |
DOUBLE 浮點數(shù) | 8字節(jié) | (1.797 693 134 862 315 7 E+308况鸣,2.225 073 858 507 201 4 E-308) | 0,(2.225 073 858 507 201 4 E-308竹观,1.797 693 134 862 315 7 E+308) | 雙精度浮點數(shù)值 |
DECIMAL 浮點數(shù) | 未知 | 未知 | 未知 | 絕對精度 |
2. 字符串類型
字符串類型 | 字節(jié)大小 | 描述及存儲需求 |
---|---|---|
CHAR | 0-255字節(jié) | 定長字符串 |
VARCHAR | 0-255字節(jié) | 變長字符串 |
TINYBLOB | 0-255字節(jié) | 不超過 255 個字符的二進制字符串 |
TINYTEXT | 0-255字節(jié) | 短文本字符串 |
BLOB | 0-65535字節(jié) | 二進制形式的長文本數(shù)據(jù) |
TEXT | 0-65535字節(jié) | 長文本數(shù)據(jù) |
MEDIUMBLOB | 0-16 777 215字節(jié) | 二進制形式的中等長度文本數(shù)據(jù) |
MEDIUMTEXT | 0-16 777 215字節(jié) | 中等長度文本數(shù)據(jù) |
LOGNGBLOB | 0-4 294 967 295字節(jié) | 二進制形式的極大文本數(shù)據(jù) |
LONGTEXT | 0-4 294 967 295字節(jié) | 極大文本數(shù)據(jù) |
VARBINARY(M) | 允許長度0-M個字節(jié)的定長字節(jié)符串镐捧,值的長度+1個字節(jié) | |
BINARY(M) | 允許長度0-M個字節(jié)的定長字節(jié)符串 |
3. 日期和時間類型
類型 | 大星彼鳌(字節(jié)) | 范圍 | 格式 | 用途 |
---|---|---|---|---|
DATE | 4 | 1000-01-01/9999-12-31 | YYYY-MM-DD | 日期值 |
TIME | 3 | '-838:59:59'/'838:59:59' | HH:MM:SS | 時間值或持續(xù)時間 |
YEAR | 1 | 1901/2155 | YYYY | 年份值 |
DATETIME | 8 | 1000-01-01 00:00:00/9999-12-31 23:59:59 | YYYY-MM-DD HH:MM:SS | 混合日期和時間值 |
TIMESTAMP | 4 | 1970-01-01 00:00:00/2037 年某時 | YYYYMMDD HHMMSS | 混合日期和時間值,時間戳 |
4. ENUM枚舉類型
ENUM 類型因為只允許在集合中取得一個值懂酱,有點類似于單選項竹习。在處理相互排拆的數(shù)據(jù)時容易讓人理解,比如人類的性別列牺。ENUM 類型字段可以從集合中取得一個值或使用 null 值整陌。
5. SET 集合類型
SET 類型與 ENUM 類型相似但不相同。SET 類型可以從預定義的集合中取得任意數(shù)量的值瞎领。并且與 ENUM 類型相同的是任何試圖在 SET 類型字段中插入非預定義的值都會使
MySQL 插入一個空字符串泌辫。如果插入一個即有合法的元素又有非法的元素的記錄,MySQL 將會保留合法的元素默刚,除去非法的元素甥郑。
修飾符
- NOT NULL / NULL 表示是否可為空
- **DEFAULT Null ** 表示默認值為Null
- auto_increment ** 表示自增,注意:**1.每個表只允許有一列為自增列荤西;2. 對于自增列澜搅,必須是索引(含主鍵);3. 對于自增邪锌,可以設(shè)置步長和起始值勉躺。
- primary key 表示設(shè)為主鍵,注意:主鍵觅丰,是一種特殊的唯一索引饵溅,不允許有空值,如果主鍵使用單個列妇萄,則它的值必須唯一蜕企,如果是多列,則其組合必須是唯一冠句。
- 設(shè)置外鍵:constraint fk_name foreign key 字段名 references 外表名(字段名)轻掩,加粗字體為關(guān)鍵字,fk_name為自定義的外鍵名懦底。
- UNSIGNED 修飾符規(guī)定字段只保存正值唇牧。
1.2.2 刪除表
drop table 表名
1.2.3 清空表
delete from 表名 //不會清空自增ID
truncate table 表名 //會將自增ID也清空
1.2.4 修改表
添加列:alter table 表名 add 列名 類型
刪除列:alter table 表名 drop column 列名
修改列:
alter table 表名 modify column 列名 類型; -- 類型
alter table 表名 change 原列名 新列名 類型; -- 列名,類型
添加主鍵:
alter table 表名 add primary key(列名);
刪除主鍵:
alter table 表名 drop primary key;
alter table 表名 modify 列名 int, drop primary key;
添加外鍵:alter table 從表 add constraint 外鍵名稱(形如:FK_從表_主表) foreign key 從表(外鍵字段) references 主表(主鍵字段);
刪除外鍵:alter table 表名 drop foreign key 外鍵名稱
修改默認值:ALTER TABLE testalter_tbl ALTER i SET DEFAULT 1000;
刪除默認值:ALTER TABLE testalter_tbl ALTER i DROP DEFAULT;
1.3 表內(nèi)容操作
1.3.1 增
insert into 表 (列名,列名...) values (值,值,值...)
insert into 表 (列名,列名...) values (值,值,值...),(值,值,值...) //一次插入多行
insert into 表 (列名,列名...) select (列名,列名...) from 表 //插入的值是從其它表查詢到的結(jié)果
1.3.2 刪
delete from 表 //清空表內(nèi)容
delete from 表 where id=1 and name='alex' //根據(jù)指定條件刪除對應的行
1.3.3 改
update 表 set name = 'alex' where id>1
1.3.4 查
查詢語法:
SELECT *|field1,filed2 ... FROM tab_name
WHERE 條件
GROUP BY field
HAVING 篩選
ORDER BY field
LIMIT 限制條數(shù)
Mysql在執(zhí)行sql語句時的執(zhí)行順序:
-- from where select group by having order by
select * from 表
select * from 表 where id > 1
select nid,name,gender as gg from 表 where id > 1
select distinct gender from student; //distinct 可以讓相同的值只出現(xiàn)一次
1.3.5 復雜查詢
a聚唐、條件
select * from 表 where id > 1 and name != 'alex' and num = 12;
select * from 表 where id between 5 and 16;
select * from 表 where id in (11,22,33)
select * from 表 where id not in (11,22,33)
select * from 表 where id in (select nid from 表)
b丐重、通配符
select * from 表 where name like 'ale%' - ale開頭的所有(多個字符串)
select * from 表 where name like 'ale_' - ale開頭的所有(一個字符)
c、限制
select * from 表 limit 5; - 前5行
select * from 表 limit 4,5; - 從第4行開始的5行
select * from 表 limit 5 offset 4 - 從第4行開始的5行
注意:跟NULL作比較時杆查,不能使用=等于號扮惦,要用 is
d、排序
select * from 表 order by 列 asc - 根據(jù) “列” 從小到大排列
select * from 表 order by 列 desc - 根據(jù) “列” 從大到小排列
select * from 表 order by 列1 desc,列2 asc - 根據(jù) “列1” 從大到小排列亲桦,如果相同則按列2從小到大排序
e径缅、分組
select num from 表 group by num
select num,nid from 表 group by num,nid
select num,nid from 表 where nid > 10 group by num,nid order nid desc
select num,nid,count(*),sum(score),max(score),min(score) from 表 group by num,nid
select num from 表 group by num having max(id) > 10
計算男生和女生的平均年齡:
select avg(age) from student group by gender;
注意:特別的:group by 必須在where之后掺栅,order by之前。having 后跟過濾條件纳猪,只能跟group by 一起用,用于將group by分組后的結(jié)果再次過濾桃笙;分組的主要目的就是做聚合計算的氏堤。
- sum() 求和
- min() 求最小值
- max() 求最大值
- avg() 求平均值
- count() 求次數(shù)
- count()* 統(tǒng)計符合條件的記錄條數(shù)
聚合函數(shù)的括號中填一個列名,例如:sum(number)表示計算number這一列數(shù)值的和搏明。
f鼠锈、連表
無對應關(guān)系則不顯示
select A.num, A.name, B.name
from A,B
Where A.nid = B.nid
無對應關(guān)系則不顯示
select A.num, A.name, B.name
from A inner join B
on A.nid = B.nid
A表所有顯示,如果B中無對應關(guān)系星著,則值為null
select A.num, A.name, B.name
from A left join B
on A.nid = B.nid
B表所有顯示购笆,如果B中無對應關(guān)系,則值為null
select A.num, A.name, B.name
from A right join B
on A.nid = B.nid
g虚循、組合
組合同欠,自動處理重合
select nickname
from A
union
select name
from B
組合,不處理重合
select nickname
from A
union all
select name
from B
h横缔、正則表達式過濾
REGEXP或者RLIKE
支持正則表達式過濾
select * from 表 where name like '^ale' //查找name是以ale開頭的行
二铺遂、Python操作MySQL
在Python中操作MySQL用pymysql
模塊,其使用方法和MySQLdb
幾乎相同茎刚。
2.1 下載安裝
pip3 install pymysql
2.2 使用操作
2.2.1 執(zhí)行查詢操作
import pymysql
# 創(chuàng)建連接
conn = pymysql.Connect(host="127.0.0.1",
port=3306,
user="root",
password="123456",
database="study",
charset="utf8")
# 創(chuàng)建游標襟锐,利用游標支數(shù)據(jù)庫取數(shù)據(jù)
cursor = conn.cursor()
#執(zhí)行SQL,返回值v是受影響的行數(shù)
v = cursor.execute('select * from student')
result = cursor.fetchall() #獲取返回的全部數(shù)據(jù)膛锭,元組形式
# result = cursor.fetchone() #獲取返回的第1條數(shù)據(jù)
# result = cursor.fetchmany(2) #獲取返回的指定行數(shù)的數(shù)據(jù)粮坞,不指定行數(shù),默認只獲取一行數(shù)據(jù)初狰,返回元組形式
print(result)
#關(guān)閉游標
cursor.close()
#關(guān)閉連接
conn.close()
注意:
fetchone()
有一個數(shù)據(jù)指針莫杈,獲取一行,就會跳到下一行跷究,不能返回姓迅。
實例:讀取數(shù)據(jù)庫,驗證用戶登錄
#通過讀數(shù)據(jù)庫驗證用戶登錄
import pymysql
username = input("請輸入用戶名:")
password = input("請輸入密碼:")
try:
# 創(chuàng)建連接
conn = pymysql.Connect(host="127.0.0.1",
port=3306,
user="root",
password="123456",
database="study",
charset="utf8")
# 創(chuàng)建游標俊马,利用游標支數(shù)據(jù)庫取數(shù)據(jù)
cursor = conn.cursor()
sql = 'select * from userinfo where username="%s" and password="%s" '%(username,password)
cursor.execute(sql)
result = cursor.fetchall() #獲取返回的全部數(shù)據(jù)丁存,元組形式
if result:
print("登錄成功")
else:
print("賬號或密碼錯誤")
except Exception as e:
print(e)
raise
finally:
cursor.close()
conn.close()
注意:以上代碼有SQL注入的漏洞,請看如下演示
演示一:輸入正確用戶名和密碼
演示二: 輸入用戶名:alex" -- , 輸入任意密碼
解析:由上圖可以看出柴我,用戶名和密碼都是錯誤的解寝,也可以通過驗證。這是為什么呢艘儒?我們來解析一下通過用戶名和密碼生成的SQL聋伦。通過字符串替換夫偶,我們可以得到這樣一條SQL:
select * from userinfo where username="alex" -- " and password="sdfsfsd"
。從這條SQL可以看出觉增,username="alex"
后面被--
注釋了(--
是SQL語言中的注釋符)兵拢,后面的語句就不能被mysql解析了,所以不管密碼輸入的是什么逾礁,都會被忽略掉说铃。
演示三:輸入用戶名:xxx" or 1=1 -- , 輸入任意密碼
解析:由上圖可以看出,即使不知道數(shù)據(jù)庫中的用戶名和密碼是什么嘹履,也可以通過驗證腻扇。通過字符串替換,我們得到這樣的一條SQL:
select * from userinfo where username="xxx" or 1=1 -- " and password="asdffas"
砾嫉。這條SQL幼苛,1=1
后面被注釋了,而select * from userinfo where username="xxx" or 1=1
是永遠成立的焕刮,可以從數(shù)據(jù)庫獲取到值舶沿,所以可以通過驗證。
改進版《讀取數(shù)據(jù)庫济锄,驗證用戶登錄》
防止被SQL注入
我們在輸入SQL字符串時暑椰,不要自己去做字符串格式化替換,可以在給execute
方法傳參時荐绝,第一個參數(shù)傳查詢的SQL一汽,第二個參數(shù)傳SQL中要替換的字符串列表。pymysql模塊內(nèi)部會自動替換低滩,在替換時召夹,會將特殊字符替換掉。
#改進版
import pymysql
username = input("請輸入用戶名:")
password = input("請輸入密碼:")
try:
# 創(chuàng)建連接
conn = pymysql.Connect(host="127.0.0.1",
port=3306,
user="root",
password="123456",
database="study",
charset="utf8")
# 創(chuàng)建游標恕沫,利用游標支數(shù)據(jù)庫取數(shù)據(jù)
cursor = conn.cursor()
sql = 'select * from userinfo where username=%s and password=%s '
cursor.execute(sql,[username,password]) #第2個參數(shù)為列表
result = cursor.fetchall() #獲取返回的全部數(shù)據(jù)监憎,元組形式
if result:
print("登錄成功")
else:
print("賬號或密碼錯誤")
except Exception as e:
print(e)
raise
finally:
cursor.close()
conn.close()
演示四:
可以看出,代碼改進后婶溯,就不會再出現(xiàn)被SQL注入了鲸阔。
2.2.2 寫庫操作必須提交commit
對數(shù)據(jù)庫進行增、刪迄委、改操作都必須執(zhí)行提交(commit)操作
import pymysql
# 創(chuàng)建連接
conn = pymysql.Connect(host="127.0.0.1",
port=3306,
user="root",
password="123456",
database="study",
charset="utf8")
cursor = conn.cursor()
#執(zhí)行SQL褐筛,返回值v是受影響的行數(shù)
sql = 'insert into userinfo(username,password) values(%s,%s)'
cursor.execute(sql,["eric","123321"])
#對數(shù)據(jù)庫進行增、刪叙身、改操作都必須執(zhí)行提交(commit)操作
conn.commit()
cursor.close()
conn.close()
2.2.3 直接獲取新增數(shù)據(jù)的自增ID
cursor.lastrowid
方法可以直接獲取新增數(shù)據(jù)的自增ID
需求:現(xiàn)在我想往class班級表中新插入一個班級渔扎,然后再往這個新班級中插入一條學生數(shù)據(jù)(包含班級ID)。
import pymysql
# 創(chuàng)建連接
conn = pymysql.Connect(host="127.0.0.1",
port=3306,
user="root",
password="123456",
database="study",
charset="utf8")
cursor = conn.cursor()
cursor.execute('insert into class(caption) values("三年三班")')
new_class_id = cursor.lastrowid #獲取新增數(shù)據(jù)的自增ID
cursor.execute('insert into student(sname,gender,class_id) values(%s,%s,%s)',["李杰","女",new_class_id])
#對數(shù)據(jù)庫進行增信轿、刪晃痴、改操作都必須執(zhí)行提交(commit)操作
conn.commit()
cursor.close()
conn.close()
2.2.4 將查詢結(jié)果以字典形式返回
需要在conn.cursor()
傳一個參數(shù):conn.cursor(cursor=pymysql.cursors.DictCursor)
import pymysql
conn = pymysql.Connect(host="127.0.0.1",
port=3306,
user="root",
password="123456",
database="study",
charset="utf8")
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute("select * from class")
result = cursor.fetchall()
print(result)
cursor.close()
conn.close()
'''
輸出結(jié)果:
[{'cid': 1, 'caption': '三年二班'}, {'cid': 2, 'caption': '一年三班'}, {'cid': 3, 'caption': '三年一班'}, {'cid'
'''