數據庫(六)
前言
本篇博客學習 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(‘登陸失敗‘)
註入寫法
避免方式:
- 再輸入時加上正則判斷,不允許輸入與 sql 相關的關鍵詞。這種方式無法避免代理服務器發起的攻擊;
- 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 語句就可以避免攻擊。
數據庫(六)