數據庫-用戶管理與pymysql

mysql用戶管理

!這是dba的活兒!,可是萬一公司沒有dba?python

mysql用戶指的是什麼?mysql

咱們每一次在操做前都須要指定帳號和密碼,這個帳號就是mysql的用戶;sql

爲何要管理?數據庫

一個公司不可能只有一個工程師,大公司,不不只有不少工程師 還有不少不一樣部門,可是數據庫服務器只有一個,你們都要訪問,這就涉及到用戶和權限問題了服務器

一個工程師對應一個帳戶,微信

哪些工程師能夠操做哪些數據庫,哪些表,甚至哪些字段,均可以進行控制,例如,騰訊,有qq和微信不一樣項目,qq的工程師,就不該該去訪問微信項目的數據;ide

mysql是如何管理的

mysql本質上是一款cs軟件,它具有用戶認證!函數

咱們有沒有作過用戶認證呢? ATM! 購物車,都作過,fetch

咱們是如何實現的?寫入文件,mysql也是同樣的,code

只不過它把文件稱爲表

那麼要怎麼添加帳戶呢?

把用戶信息寫入表中就能夠了

權限相關表

來看看它都把數據放在哪一個表中了!

自帶的mysql數據庫,四個表用於存儲帳戶信息以及權限
user
db
table_priv
columns_priv

權限優先級

user->db->table_priv->columns_priv

select *from user;
#因爲字段較多 以表格形式展現 會比較亂,能夠添加\G來縱向顯示
select *from user\G;

內置root帳戶字段信息解析

建立帳號語句

create user 用戶名@"ip地址"  "identified" by 密碼;
create user tom@"192.168.101" identified by "123";

該語句表面tom只能在101機器上使用,別的機器就沒法登陸

用%能夠表示在任意機器可用

注意:該方式建立的帳號沒有任何權限 因此瞭解便可

受權語句

受權:

受權語句執行時若是帳號不存在會自動建立帳號 因此更推薦使用

注意:默認只有root才能爲其餘帳號受權

grant all on *.* to tom@"localhost" identified by "123";
#該語句中的all 增刪改查全部權限 可是不包括grant權限
#*.* 表示任何數據庫 任何表 存儲在user表

grant all on *.* to toms@"%" identified by "123";
# host 爲% 表示 該帳戶能夠在任何主機上登陸可是不包括localhost
grant all on *.* to toms@"localhost" identified by "123";
# 繼續執行 上述語句保證localhost也能夠登陸該帳戶




grant all on db.* to tom@"localhost" identified by "123" 
#db.* 該用戶能夠操做db數據庫的任何表 存儲在 db表


grant all on db.t1 to tom@"localhost" identified by "123" 
#db.* 該用戶能夠操做db數據庫的t1表 存儲在 table_privi表


grant select(id) on db.t1 to tom@"localhost" identified by "123" 
#精確到字段 和  操做級別
#該用戶只能查詢 db下的t1表 



grant all on *.* to tom@"localhost" identified by "123" with grant option;
#with grant option 表示該帳戶能夠將權限授予其餘用戶



REVOKE all privileges [column]   on db.table from user@"host";
#收回權限


drop user@"host"
#刪除用戶

flush privileges;
#刷新權限表 一些時候權限信息可能會有所延遲 能夠執行該語句當即刷新權限信息

pymysql模塊

pymysql是python提供的一個mysql客戶端模塊,用於與mysql服務器創建鏈接,發送查詢,並獲取結果等;

基本使用:

import pymysql
# 1.創建鏈接
try:
    conn = pymysql.connect(host="127.0.0.1",port=3306,user="root",password="",db="day46",)
    print("鏈接服務器成功!")
    #2.獲取遊標對象
    cursor = conn.cursor()
    #3.執行sql語句
    count = cursor.execute("select *from user")
    print("結果數量: %s" % count)

    # 提取結果
    # print(cursor.fetchall())
    # print(cursor.fetchone())
    # print(cursor.fetchmany(1))

    # 移動遊標位置  相對當前位置
    cursor.scroll(1,"relative")
    cursor.scroll(-1, "relative")
    print(cursor.fetchone())

    # 移動遊標位置  使用絕對位置
    cursor.scroll(0, "absolute")
    print(cursor.fetchone())

    print(cursor.fetchall())
    # 注意 遊標移動到末尾後沒法在讀取到數據 若需重複讀取數據,須要使用scroll來移動遊標

except Exception as e:
    print("鏈接服務器失敗.....")
    print(type(e),e)
finally:
    if cursor:
        cursor.close()
        print("關閉遊標")
    if conn:
        conn.close()
        print("關閉連接")

上述代碼中 fetch 相關函數返回值類型爲元組,使用起來不夠方便,咱們能夠在建立遊標時指定遊標類型爲字典類型像這樣:

cursor = conn.cursor(pymysql.cursors.DictCursor)

sql注入攻擊

何爲sql注入

sql注入指的是,用戶在輸入數據時,按照sql的語法,來編寫帶有攻擊目的的sql語句,並插入到原始語句中執行.

例如:登陸功能,須要用戶輸入用戶名和密碼

正常的一個登陸功能代碼以下:

try:
    conn = pymysql.connect(host="127.0.0.1",port=3306,user="root",password="",db="day46",)
    print("鏈接服務器成功!")
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    
    user = input("username:")
    password = input("password:")
    
    count = cursor.execute("select *from user where name = '%s' and password = '%s'" % (user,password))
    if count:
        print("登陸成功!")
    else:
        print("登陸失敗!")
except Exception as e:
    print(type(e),e)
finally:
    if cursor:cursor.close()
    if conn: conn.close()

上述代碼有被注入攻擊的危險

嘗試在用戶名中輸入如下內容,密碼隨意
 jerry' — ass 
或者連用戶名都不用寫
' or 1 = 1 -- asaa

解決方案:

​ 1.客戶端在發送sql給服務器前進行re判斷

​ 這樣的問題在於一些程序能夠模擬客戶端直接發送請求給服務器

​ 2.在服務器端將sql交給mysql是做進一步處理,相關的代碼其實pymysql已經作了封裝

​ 咱們只要保證不要本身來拼接sql語句便可,將拼接參數操做交給pymysql.

try:
    conn = pymysql.connect(host="127.0.0.1",port=3306,user="root",password="",db="day46",)
    print("鏈接服務器成功!")
    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)) # 參數交給模塊
    if count:
        print("登陸成功!")
    else:
        print("登陸失敗!")
except Exception as e:
    print(type(e),e)
finally:
    if cursor:cursor.close()
    if conn: conn.close()

增刪改

import pymysql


# 1.創建鏈接
try:
    conn = pymysql.connect(host="127.0.0.1",port=3306,user="root",password="",db="day46",)
    print("鏈接服務器成功!")
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    
    #增
    #sql = "insert into user values(null,%s,%s,%s)"
    #count = cursor.execute(sql,("tom","man","123321"))
    # 一次性插入多條記錄
    #sql = "insert into user values (null,%s,%s,%s)"
    #count = cursor.executemany(sql, [("周芷若","woman","123"), ("趙敏","woman","321")])
    
    #刪
    # count = cursor.execute("delete from user where id = 1")

    
    #改
    count = cursor.execute("update user set name = '劉大炮' where id = 1")

    if count:
        print("執行成功!")
    else:
        print("執行失敗!")

    # 獲取最新的id
    # print(cursor.lastrowid)
except Exception as e:
    print(type(e),e)

finally:
    if cursor:cursor.close()
    if conn: conn.close()

強調:pymysql 對於數據的增刪改默認都不會生效,必須調用連接對象的commit()來提交修改 或者在建立連接對象時指定爲自動提交;

conn.commit() 
#或者建立連接對象時指定爲自動提交
conn = pymysql.connect(host="127.0.0.1",port=3306,user="root",password="",db="day46",autocommit=True)
相關文章
相關標籤/搜索