1. 程式人生 > >數據庫(六)

數據庫(六)

.com 負責 相關 地方 sel 技術分享 har 但是 你在

前言

本篇博客學習 mysql 的用戶管理和使用 python 操作 mysql 的一個模塊 pymysql。

mysql 用戶管理

因為數據安全對於互聯網公司來說是最重要的,不可能隨便分配 root 賬戶,應該按照不同開發崗位分配不同的賬戶和權限。

用戶管理相關表

mysql> use mysql;
mysql> show tables;

技術分享圖片

用戶對數據庫的權限順序

mysql 將與用戶相關的數據放在 mysql庫中,

user->db->tables_priv->columns_priv

如果用戶擁有對所有庫的訪問權,則存儲在 user 中;

如果用戶擁有對部分庫的使用權,則存儲在 db 中;

如果用戶擁有對部分表的使用權,則存儲在 tables_priv 中;

如果用戶擁有對表中某些字段的使用權,則存儲在 columns_priv 中。

用戶授權設置

創建新賬戶

mysql> create user 用戶名@ip identified by ‘密碼‘;
mysql> create user [email protected] identified by ‘123‘;

創建成功後會在 user 表中查看到:

mysql> select * from user\G;

技術分享圖片

這樣創建的賬戶是沒有任何權限的,可以看出關於權限字段的值全為 N,接下來需要給 musibii 賬號分配權限了。

授予用戶最高權限

mysql> grant all on *.* to [email protected] identified by ‘123‘;

如果 musibii 賬號不存在,那麽會在授予權限的時候自動創建賬號。

現在查看一下 musibii 賬號的權限關系:

技術分享圖片

授予授予權限

現在除了 grant_priv 權限其他權限都有了,這個權限是授權權限。通過 root 賬戶授予:

mysql> grant all on *.* to [email protected] identified by ‘123‘ with grant option;

技術分享圖片

現在可以說這個賬號就是一個 root 賬戶,但是只能在本機登陸。

授予在任何地方登陸權限

mysql> grant all on *.* to musibii@‘%‘ identified by ‘123‘;

技術分享圖片

現在 host 字段對應的值變為了%,意味著可以在任何主機登陸該數據庫了。

設置只能訪問某個庫

mysql> grant all on day46 to eureka@‘%‘ identified by ‘123‘;

這樣設置的用戶權限信息存儲在 db 中,但是不知道為什麽在 db 中沒有賬戶信息。。。

設置能能訪問某個庫中的某個表

mysql> grant all on day46.emp to thales@‘%‘ identified by ‘123‘;

技術分享圖片

設置只能增刪查改權限

mysql> grant select(name) on day46.emp to thales@‘%‘ identified by ‘123‘;

技術分享圖片

這樣 thales 用戶就只能對 emp 表中的 name 字段進行查詢操作了。

用戶收權設置

收回某個賬號的所有權限

mysql> revoke all privileges [column] on db.table from user@‘host‘;
mysql> revoke all privileges on *.* from musibii@‘127.0.0.1‘;

查詢 user 表中的權限信息,發現除了授權權限其他權限都沒有了:

技術分享圖片

不過在修改權限之後需要刷新權限表:

mysql> flush privileges;

註意:如何授予權限就應該如何收回權限,因為不同的權限存儲在不同的表中

刪除用戶

mysql> drop user 用戶名@主機;

當你在雲服務器部署了 mysql 環境時,你的程序無法直接連擊服務器,需要授予在任意一臺電腦登陸的權限

mysql> grant all on *.* to 用戶名@‘%‘ identified by 密碼 with grant option;

pymysql

pymysql 連接數據庫

import pymysql

conn = pymysql.connect(
    host=‘127.0.0.1‘,
    port=3306,
    user=‘root‘,
    password=‘123‘,
    database=‘day46‘,
    charset=‘utf8‘)

操作數據庫

cursor 遊標對象,負責執行 sql 語句,獲取返回的數據

cursor = conn.cursor()
sql = ‘select *from emp‘
res = cursor.execute(sql) # 返回值是本次查詢的記錄條數

# 獲取一條記錄
print(cursor.fetchone())
# 接著獲取
print(cursor.fetchone())
# 提取所有結果
print(cursor.fetchall())

技術分享圖片

print(fetchamany(3))

運行結果

((3, ‘關羽‘, ‘男‘, ‘市場‘, ‘員工‘, 4000.0), (4, ‘孫權‘, ‘男‘, ‘行政‘, ‘總監‘, 6000.0), (5, ‘周瑜‘, ‘男‘, ‘行政‘, ‘員工‘, 5000.0))

參數是指定獲取的數據條數。

控制遊標位置

cursor.scroll(1,mode=‘relative) # 遊標從當前位置往後移動一條記錄
cursor.scroll(1,mode=‘absolute‘) # 遊標從開始位置往後移動一條記錄

獲取結果使用字典表示

指定使用字典類型的遊標,默認是元祖類型

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

技術分享圖片
在 python 使用代碼執行了增刪查改後只是在內存中修改了值,想要修改數據庫中的值需要提交操作

conn.commit()

這樣修改的值才會改變。

sql 註入

import pymysql

conn = pymysql.connect(
    host=‘127.0.0.1‘,
    port=3306,
    user=‘root‘,
    password=‘password‘,
    database=‘day46‘,
    charset=‘utf8‘)


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

name = input(‘用戶名‘)
pwd = input(‘密碼‘)

sql = ‘select * from user where name = "%s" and pwd = "%s"‘ % (name, password)

res = cursor.execute(sql)
if res:
    print(‘登陸成功‘)
else:
    print(‘登陸失敗‘)

註入寫法

技術分享圖片

避免方式:

  1. 再輸入時加上正則判斷,不允許輸入與 sql 相關的關鍵詞。這種方式無法避免代理服務器發起的攻擊;
  2. 2.在服務端,執行 sql 前進行判斷。

pymysql 中已經做了處理,只要將參數的拼接交給 mysql 來完成就能夠避免攻擊。

代碼實現

name = input(‘用戶名‘)
pwd = input(‘密碼‘)

sql = ‘select * from user where name = %s and password = %s‘

res = cursor.execute(sql, (name,pwd)) # 這樣執行 sql 語句就可以避免攻擊。

數據庫(六)