|
目錄
一、用戶管理
1.用戶權(quán)限
1.方法:
2.權(quán)限相關(guān)表:
# 自帶的MySQL庫(kù)中,有以下四個(gè)表用于存儲(chǔ)用戶信息以及權(quán)限
user # 所有用戶信息都會(huì)存儲(chǔ)在里面,無(wú)論權(quán)限有多少
db # 存放擁有對(duì)庫(kù)操作的權(quán)限的用戶信息
table_priv # 存放僅擁有對(duì)表操作的權(quán)限的用戶信息
columns_priv # 存儲(chǔ)僅擁有對(duì)字段操作權(quán)限的用戶信息
# 權(quán)限優(yōu)先級(jí)
user -> db -> table_priv -> columns_priv
# 查看表中內(nèi)容,由于字段太多,以表格形式展示會(huì)比較亂,可以添加\G來(lái)縱向顯示
select * from user \G; # 可以查看用戶所擁有的權(quán)限
3.操作權(quán)限:
- 可以通過(guò)select/update/delete/insert/drop等等,設(shè)置操作權(quán)限
2.授權(quán)
1.創(chuàng)建用戶和刪除用戶
# 創(chuàng)建用戶時(shí),需要三個(gè)信息:賬戶名、IP地址、密碼
# 其中IP地址是用來(lái)限制該賬戶的登陸設(shè)備的,也就是讓其只能在指定的機(jī)器上登陸
# 我們可以用通配符"%"來(lái)表示可以在任意IP地址端的計(jì)算機(jī)上登陸(不包括主機(jī)地址)
# 要想包括主機(jī),我們?nèi)稳恍枰由希篶reate user 用戶名@'127.0.0.1' identified by '密碼';
# 注意:主機(jī)IP可以用localhost代替
# 語(yǔ)法:
create user 用戶名@IP地址 identified by '密碼';
# 只有root賬戶可以創(chuàng)建用戶(有其他方法可以讓超級(jí)用戶也獲得該權(quán)限)
# 在下面會(huì)講
# 刪除用戶(會(huì)同時(shí)刪除其所有權(quán)限)
drop user 用戶名@IP地址;
2.權(quán)限管理
1.授權(quán)給用戶,可以自由選擇對(duì)創(chuàng)建用戶的權(quán)限設(shè)置
2.用這種方法時(shí),其實(shí)也覆蓋了創(chuàng)建用戶的操作,因此一般直接用這種方法進(jìn)行創(chuàng)建用戶并授權(quán)
# 1.給創(chuàng)建用戶授權(quán):可以對(duì)所有庫(kù)、所有表、所有字段進(jìn)行增刪改查操作
grant all on *.* to 用戶名@IP地址 identified by '密碼';
# all表示對(duì)所有字段擁有增刪改查的權(quán)限
# *.*中第一個(gè)*表示所有庫(kù),第二個(gè)*表示所有表
# 2.創(chuàng)建擁有和root用戶一樣權(quán)限的超級(jí)用戶,并且可以在任何主機(jī)上登陸
# with grant option表示可以將root所擁有的權(quán)限授予其他用戶
grant all on *.* to 用戶名@"%" identified by '密碼' with grant option;
grant all on *.* to 用戶名@localhost identified by '密碼' with grant option; # 用來(lái)保證在localhost也可以登陸該賬戶
# 3.設(shè)置相應(yīng)的權(quán)限
# 3.1 授權(quán)可以操作指定庫(kù)中的任何表的操作權(quán)限
grant all on 庫(kù)名.* to 用戶名@IP地址 identified by '密碼';
grant all on mydb.* to 'king'@'%' identified by '123';
select * from db \G;
# 3.2 授權(quán)指定庫(kù)中指定表的操作權(quán)限(可以精確到操作級(jí)別)
grant all on 庫(kù)名.表名 to 用戶名@IP地址 identified by '密碼';
grant all on mydb.emp to 'jojo'@'127.0.0.1' identified by '222';
grant select on mydb.student to 'Timor'@'127.0.0.1' identified by '666' -- 只能對(duì)該表進(jìn)行查看;
select * from tables_priv \G -- 查看是否存在該用戶;
# 3.3 授權(quán)指定庫(kù)中指定表中的某個(gè)字段的操作權(quán)限(精確到字段和操作級(jí)別,不能使用*來(lái)表示對(duì)所有字段的操作限制)
grant select(字段) on 庫(kù)名.表名 to 用戶名@IP地址 identified by '密碼';
grant update(name) on mydb.emp to 'liu'@'192.151.11.201' identified by '333' -- 只能更新name字段的信息;
select * from columns_priv \G;
# 4.刷新權(quán)限
flush privileges;
# 5.收回權(quán)限
revoke all privileges 字段名 on 庫(kù)名.表名 from 用戶名@IP地址;
revoke all on *.* from 用戶名@IP地址;
二、可視化MySQL軟件(客戶端)
1.MySQL-workbench
三、pymysql模塊
pymysql是python提供的一個(gè)mysql客戶端模塊,用于與mysql服務(wù)器建立連接,發(fā)送查詢,并獲取結(jié)果等
1.簡(jiǎn)單的對(duì)庫(kù)操作
import pymysql
try:
# 1.建立連接,并獲得連接對(duì)象
conn = pymysql.Connect(
host = '127.0.0.1',
port = 3306,
user = 'root',
password = '',
db = 'mydb',
)
print('連接服務(wù)器成功')
# 2.獲取游標(biāo)對(duì)象
cursor = conn.cursor(pymysql.cursors.DictCursor) # 如果不加任何參數(shù),則提取結(jié)果顯示的是元組類型,使用pymysql.cursors.DictCursor,可以更換為字典類型的游標(biāo)
# 3.定制SQL語(yǔ)句
sql = 'select * from student' # 里面不用加分號(hào)
# 4.發(fā)送SQL語(yǔ)句,并得到搜索結(jié)果的個(gè)數(shù)
count = cursor.execute(sql)
print(f'結(jié)果個(gè)數(shù):{count}')
# 5.提取結(jié)果(通過(guò)游標(biāo)對(duì)象)
print(cursor.fetchall()) # 提取全部結(jié)果
print(cursor.fetchmany(2)) # 通過(guò)參數(shù),提取指定個(gè)數(shù)的結(jié)果
print(cursor.fetchone()) # 僅提取一個(gè)結(jié)果
# 6.移動(dòng)游標(biāo),可以多次提取結(jié)果
# 使用相對(duì)位置
# 游標(biāo)當(dāng)前所在位置的值的索引是0,可以正負(fù)數(shù)字來(lái)移動(dòng)游標(biāo)
cursor.scroll(-1, 'relative') # 游標(biāo)當(dāng)前所在位置向前(左)移動(dòng)一位
print(cursor.fetchone())
cursor.scroll(1, 'realative') # 游標(biāo)向當(dāng)前位置的后面(右)移動(dòng)一位
print(cursor.fetchone())
# 使用絕對(duì)位置
# 規(guī)定了所有值的索引,第一個(gè)值的索引是0,依次累加,游標(biāo)根據(jù)索引來(lái)查找值的位置
cursor.scroll(1, 'absolute') # 游標(biāo)指向索引為1的值
print(cursor.fetchone())
# 7.捕獲異常
except Exception as e:
print('連接服務(wù)器失敗')
print(e)
finally: # 無(wú)論如何后面的代碼都會(huì)執(zhí)行
# 8.關(guān)閉游標(biāo)
if cursor:
cursor.close()
print('關(guān)閉游標(biāo)')
# 9.關(guān)閉連接
if conn:
conn.close()
print('關(guān)閉連接')
2.SQL注入攻擊
1.通過(guò)按照SQL語(yǔ)法來(lái)編寫帶有攻擊目的的SQL語(yǔ)句作為參數(shù),插入到原始語(yǔ)句中,讓數(shù)據(jù)庫(kù)執(zhí)行,進(jìn)而導(dǎo)致數(shù)據(jù)庫(kù)中的數(shù)據(jù)不安全
2.案例:
# 登陸示例:
# 1.連接服務(wù)器
# 2.用戶認(rèn)證(在數(shù)據(jù)庫(kù)中進(jìn)行)
# 3.發(fā)送指令
# 4.提取結(jié)果
import pymysql
try:
conn = pymysql.Connect(
host = '127.0.0.1', # 如果是本機(jī),則可以忽略
port = 3306, # 如果沒(méi)改過(guò),可以忽略
user = 'root',
password = '123',
database = 'mydb'
)
cursor = conn.cursor(pymysql.cursor.DictCursor)
login_username = input('username>>>')
login_password = input('password>>>')
sql = "select * from login where name = '%s' and password = '%s'" %(login_username, login_password)
count = cursor.execute(sql)
if count:
print('ok')
else:
print('error')
except Exception as e:
print(e)
finally:
if cursor: cursor.close()
if conn: conn.close()
'''嘗試在用戶名中輸入以下內(nèi)容,密碼隨意
jerry' — ass
或者連用戶名都不用寫
' or 1 = 1 -- asaa
'''
# 1.客戶端在發(fā)送sql給服務(wù)器前進(jìn)行re判斷,這樣的問(wèn)題在于一些程序可以模擬客戶端直接發(fā)送請(qǐng)求給服務(wù)器
# 2.在服務(wù)器端將sql交給mysql是作進(jìn)一步處理,相關(guān)的代碼其實(shí)pymysql已經(jīng)做了封裝
# 3.我們只要保證不要自己來(lái)拼接sql語(yǔ)句即可,將拼接參數(shù)操作交給pymysql.
try:
conn = pymysql.connect(host="127.0.0.1",port=3306,user="root",password="",db="day46",)
print("連接服務(wù)器成功!")
cursor = conn.cursor(pymysql.cursors.DictCursor)
user = input("username:")
password = input("password:")
sql = "select *from user where name = %s and password = %s"
print(sql)
count = cursor.execute(sql,(user,password)) # 參數(shù)交給模塊
if count:
print("登錄成功!")
else:
print("登錄失敗!")
except Exception as e:
print(type(e),e)
finally:
if cursor: cursor.close()
if conn: conn.close()
3.編寫注冊(cè):
# 注意: pymysql自動(dòng)開啟了事務(wù),所以我們自己在合適的位置提交
import pymysql
conn = pymysql.connect(
host = "127.0.0.1", #如果是本機(jī) 可以忽略
port = 3306, # 如果沒(méi)改過(guò) 可以忽略
user = "root", #必填
password = "111", #必填
database = "day42", #必填,
#autocommit=False # 開啟自動(dòng)提交 不常用....
)
c = conn.cursor(pymysql.cursors.DictCursor)
name = input("name:")
pwd = input("pwd:")
sql = "select *from user where name = %s"
if c.execute(sql,(name,)):
print("用戶名已存在!")
else:
sql2 = "insert into user values(%s,%s)"
if c.execute(sql2,(name,pwd)):
print("注冊(cè)成功!")
conn.commit() # 調(diào)用連接對(duì)象的提交函數(shù)
else:
print("注冊(cè)失敗!")
c.close()
conn.close()
3.pymysql對(duì)于事務(wù)的應(yīng)用
import pymysql
conn = pymysql.connect(
host = "127.0.0.1", #如果是本機(jī) 可以忽略
port = 3306, # 如果沒(méi)改過(guò) 可以忽略
user = "root", #必填
password = "111", #必填
database = "day42", #必填,
autocommit=True # 開啟自動(dòng)提交 不常用....
)
c = conn.cursor(pymysql.cursors.DictCursor)
try:
c.execute("start transaction;")
sql1 = "update user set money = money - 1000 where name = 'jack'"
c.execute(sql1)
sql2 = "update user set moneys = money 1000 where name = 'rose'"
c.execute(sql2)
c.execute("commit;")
except:
c.execute("rollback;")
c.close()
conn.close()
4.pymysql對(duì)于存儲(chǔ)過(guò)程的應(yīng)用
# 創(chuàng)建名為add1的存儲(chǔ)過(guò)程
delimiter |
create procedure add1(in a int,in b int,out c int)
begin
set c = a b;
end|
delimiter ;
import pymysql
conn = pymysql.connect(
host = "127.0.0.1", #如果是本機(jī) 可以忽略
port = 3306, # 如果沒(méi)改過(guò) 可以忽略
user = "root", #必填
password = "111", #必填
database = "day42", #必填,
autocommit=True # 開啟自動(dòng)提交 不常用....
)
c = conn.cursor(pymysql.cursors.DictCursor)
res = c.callproc("add1",(1,2,1212)) # @_add1_0 @_add1_1 @_add1_2
c.execute("select @_add1_2")
print(c.fetchone())
# 調(diào)用存儲(chǔ)過(guò)程時(shí),傳入?yún)?shù),會(huì)自動(dòng)定義成變量,
# 命名方式 @_過(guò)程的名稱_參數(shù)的索引 從0開始 來(lái)源:https://www./content-2-372451.html
|