Python學習筆記 第十二章 mysql

Python學習筆記 第十二章 mysql

1.初識數據庫

image-20210414104045208

通常爲了高可用,還會備份大量的數據到備用數據庫,當運行的數據庫死掉以後能夠接替原來的數據庫python

  • 數據庫的優點mysql

    • 程序穩定性,這樣任意一臺服務器崩潰了,都不會影響數據和另外的服務
    • 數據一致性:全部的數據都存儲在一塊兒,全部的程序操做的數據都是統一的,就不會出現數據不一致的現象
    • 併發:數據庫能夠良好的支持併發,全部程序操做數據庫都是經過網絡,而數據庫自己支持併發的網絡操做,不用本身寫sicket
    • 效率:使用數據庫對數據進行增刪改查的效率要高出咱們本身處理文件不少
  • 什麼是數據linux

    • 描述事物的符號記錄稱之爲數據,能夠是數字、文字、圖片、圖像、聲音、語言等
    • 在計算機中描述一個事物,須要抽取這事物的典型特徵,組成一條記錄,至關於文件的每一行
  • 什麼是數據庫面試

    • 數據庫即存放數據的倉庫,只不過這個倉庫是計算機存儲設備上,並且數據是按必定的格式存放的
    • 數據庫是長期存放在計算機內、有組織、可共享的數據集合
    • 數據庫中的數據按必定的數據模型組織、描述和儲存,具備較小的冗餘度、較高的數據獨立性和以擴展性,並可爲各類用戶共享
  • 什麼是數據庫管理系統(DataBase Management System)簡稱DBMSredis

    • 如何科學地組織和存儲數據,如何高效獲取和維護數據成了關鍵
    • 這用到一個系統軟件-數據庫管理系統:MySQL\Oracle\SQLite]Access\MS SQL Server
    • mysql主要用於大型門戶,如搜狗、新浪,開源(甲骨文)
    • oracle用於銀行、鐵路、飛機場,費用高(甲骨文)
    • sql server,微軟公司的產品,主要應用於大中型企業,如聯想、方正
    • 數據庫管理員(DBA)
  • 概念sql

    • 表:文件 ,存放多行內容、記錄
    • 數據庫:文件夾,用來組織文件、表
    • 數據庫管理系統:軟件,如mysql,管理數據庫
    • 數據庫服務器:一臺計算機(對內存要求較高),運行數據庫管理軟件
  • 數據庫的分類mongodb

    • 相對快
    • key-value來存儲的,沒有表結構
    • {'apple':[名字 年齡 電話號碼 地址]} 只能根據apple查詢,而不能經過電話號碼查詢
    • 通常用於如:快遞 用快遞單號查詢
    • 視頻 電影的id:電影的內容/電影的地址
    • 相對慢
    • 須要表結構
    • sql語句通用
    • 關係型:sqllite\db2\oracle\access\sql server\mysql
    • 非關係型:mongodb\redis\memcache
  • mysql數據庫

    • 是一個關係型數據庫,關係數據庫將數據存放在不一樣的表中,而不是將全部的數據存放在一個大倉庫內,增長速度和靈活性

2.安裝數據庫

https://downloads.mysql.com/archives/community/windows

image-20210414113732405

下載以後點擊安裝包進行安裝安全

image-20210414113754664

image-20210414113842436

image-20210414113949799

image-20210414114015927

image-20210414113914824

環境變量的配置:

在任何目錄下都能找到對應的文件

才能在任意位置輸入命令啓動該應用

windows下

mysql install 安裝mysql服務 mysql服務就被註冊到操做系統中

net start mysql 啓動mysql

net stop mysql 關閉mysql

啓動客戶端鏈接server

mysql -u root -p

輸入密碼

或者 mysql -uroot -p123456

mysql -uroot -p123456

3.操做數據

mysql帳號操做

#進入mysql客戶端
$mysql
mysql> select user();  #查看當前用戶
mysql> exit     # 也能夠用\q quit退出

# 默認用戶登錄以後並無實際操做的權限
# 須要使用管理員root用戶登錄
$ mysql -uroot -p   # mysql5.6默認是沒有密碼的
#遇到password直接按回車鍵
mysql> set password = password('root'); # 給當前數據庫設置密碼

# 建立帳號
# create user '用戶名'@'主機ip/主機域名' identified by '密碼';
mysql> create user 'wrr'@'192.168.10.%'   IDENTIFIED BY '123';# 指示網段
mysql> create user 'wrr'@'192.168.10.5'   # 指示某機器能夠鏈接
mysql> create user 'wrr'@'%'                    #指示全部機器均可以鏈接  
mysql> show grants for 'wrr'@'192.168.10.5';查看某個用戶的權限 
# 遠程登錄
$ mysql -uroot -p123 -h 192.168.10.3

# 給帳號受權
#grant select on 數據庫名.* to '用戶名'@'主機的ip/主機域名'
mysql> grant all on *.* to 'wrr'@'%';
#grant 權限類型
#grant all 給全部的權限
#grant select,insert 給查詢和插入的權限
mysql> flush privileges;    # 刷新使受權當即生效

# 建立帳號並受權
mysql> grant all on *.* to 'wrr'@'%' identified by '123'
  • 基本操做
    • show databases; 查看全部數據庫
    • create database 數據庫名; 建立一個數據庫
    • use 數據庫; 切換到數據庫下
    • show tables; 查看這個庫下有多少表
    • drop database 數據庫名;刪除數據庫
  • 操做表
    • 能看到多少個字段、類型,可是看不到編碼,引擎,具體的約束信息只能看到一部分
    • 能查字段、類型、長度、編碼、引擎、約束
    • 字段名 類型[(寬度) 約束條件]
    • create table 表名(name char(20), age int); 建立一張表
    • show create table 表名;
    • desc student; describe 表名; 查看錶結構
    • drop table 表名; 刪除表
  • 操做數據
    • delete from 表; 是不會清空自增字段的offset(偏移量)值
    • truncate table 表; 會清空表和自增字段的偏移量
    • 寫入數據的方式
    • insert into 表 values (值1,值2, 值3) 這張表有多少的字段就須要按照字段的順序寫入多少個值
    • insert into 表 values (值1,值2,值3),(值1,值2,值3)一次性寫入多條數據
    • insert into 表 (字段1,字段2) values (值1,值2) 制定字段名寫入,能夠任意選擇表中你須要寫入的字段進行寫入
    • 插入數據:insert into student values('apple', 18);
    • 查詢數據: select * from student;
    • 修改數據:update student set age=20 where name='apple'; 注意修改的須要加上where
    • 刪除數據:delete from student where name='apple';

4.SQL語句

SQL語言主要用於存取數據、查詢數據、更新數據和管理關係數據庫系統,SQL語言由IBM開發。SQL語言分爲3種類型:

  一、DDL語句 數據庫定義語言(defined): 數據庫、表、視圖、索引、存儲過程,例如CREATE DROP ALTER

  二、DML語句 數據庫操縱語言(manager): 插入數據INSERT、刪除數據DELETE、更新數據UPDATE、查詢數據SELECT

  三、DCL語句 數據庫控制語言(control): 例如控制用戶的訪問權限GRANT、REVOKE

5.存儲引擎- 存儲數據的方式

show engines; 查看支持的存儲引擎

image-20210414151358374

show variables like '%engin%'; 查看默認的引擎

image-20210414154412699

Support:mysql是否支持這種存儲引擎

mysql5.6 默認爲Innodb存儲引擎

Myisam 在mysql5.5以前默認的存儲引擎 表鎖

操做數據的代碼-》 存儲引擎 - 〉數據

(1)數據存儲在硬盤上

數據和索引存儲在一塊兒 2個文件  Innodb存儲引擎 數據持久化

  • 數據索引一個文件

  • 表結構一個文件

  • Transactions:事務,保持數據安全

    Supports transactions:支持事務,保證數據的完整性,將多個操做變成原子性操做

    開啓事務-》 執行原子性操做-〉提交事務

    row-level locking:行級鎖:修改的行少的時候使用,修改數據頻繁的時候

    表級鎖:批量修改多行,對於大量數據的同時修改

    foreign keys:外鍵,約束兩張表中的關聯字段不能隨意的添加、刪除,下降數據增刪改的出錯率

    學生表中能夠添加學生的姓名和年齡,再設置一個id 一、2

    在班級表裏設置id 一、2分別表示一班和二班,顯示對應的班級人數

    可是想要在學生表中id能夠設置爲3,若是想要學生表的id根據班級表存在的id進行設置,那麼可給id加上外鍵,當id設置爲3會報錯

    而且當學生表中有設置id爲2的,那麼班級表中的二班不能刪除

數據和索引不須要存儲在一塊兒 3個文件 Myisam存儲引擎 數據持久化

  • 數據
  • 表的結構
  • 索引(查詢的時候使用的一個目錄結構)
  • 只支持表鎖

(2)數據存在內存中,也就是說斷電數據消失 1個文件 Memory 存儲引擎

  • 表結構

  • MEMORY:Hash based基於哈希的,存儲在內存中,useful for temporary tables對臨時表很是有用

通常像首頁的熱點新聞就會存儲在memory中,查找不到再到大表中查找

面試題:

你瞭解mysql存儲引擎嗎?

你的項目用了什麼存儲引擎?

  • innodb
  • 多個用戶操做的過程當中對同一張表的數據同時作修改
  • innodb支持行級鎖,因此咱們是用來這個存儲引擎
  • 爲了適應程序將來的擴展性,擴展新功能的時候可能會用到...涉及到要維護數據的完整性
  • 項目中有一兩張xx表,之間的外鍵關係是什麼,一張表的修改或者刪除比較頻繁,怕出錯因此作了外鍵約束

6.mysql數據類型

  • 數字 和 bool

    • 最多表示10位數
    • 默認是有符號的
    • 無符號 unsigned 0, + 若是填入負數會顯示warning 並查看的時候顯示爲可表示範圍的最小值如0
    • tinyint 一個字節 有符號數範圍 -128,127
    • int 四個字節 有符號數範圍 -2147483648,2147483647 超過最大的位數顯示的仍是2147483647 不約束長度
    • float 四個字節 float(5,2) 123.32 前面表示一共多少位,後面表示小數點位數 會四捨五入
    • double 八個字節 同float 表示的範圍更廣
    • decimal 默認爲decimal(10, 0) 十位整數 依賴於前面和後面的值
  • 字符串

    • 變長存儲,節省空間,存取速度慢
    • 'apple' 'apple5'
    • 定長存儲,浪費空間,節省時間
    • 'apple' 'apple .......'
    • char  0-255字節 經常使用於身份證號、手機號、qq號(12位的qq更多)、username(12-18)、password(10-16)

    • varchar 0-65535字節 經常使用於評論、朋友圈、微博

      image-20210414165233853

  • 時間

    • 若是像datetime也實現相似的功能,能夠利用show create table 表名 查看timestamp的字段後面的內容
    • 在新建datetime數據類型的時候也加上一樣的內容便可
    • create table t5(id int, dt datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
    • datetime 八個字節20210415121900 表示範圍1000-01-01 00:00:00/9999-12-31 23:59:59

    • year 一個字節 1901/2155

    • date 三個字節 20210415 表示範圍1000-01-01/9999-12-31

    • time 三個字節 121900 表示範圍 '-838:59:59'/'838:59:59'

    • timestamp 四個字節 1970-01-01 00:00:00/2038 默認值爲當前時間戳 不能爲空 更新其餘數據的時候自動按照當前的時間戳更新最新的時間戳,像登錄的時候,能夠記錄最後一次登錄的時間

      image-20210414164226282

  • enum/set

    按照必定的範圍選擇

    • hobby set('抽菸', '喝酒', '燙頭'); 愛好能夠多選
    • gender enum('male', 'female');  性別能夠設置爲單選
    • enum 單選行爲
    • set 多選行爲

7.完整性約束

無符號的:只和數字有關 unsigned

不能爲空 not null

默認值 default

不能重複 unique 值不能重複,null能夠寫入多個 第一個被定義爲非空+惟一的那一列會成爲這張表的primary key

聯合惟一 unique

create table t14(
	id int,
  server_name char(12),
  ip char(15),
  port char(5),
  unique(ip, port)
);

自增 auto_increment 只能對數字有效,自帶非空約束,至少是unique的約束以後才能使用auto_increment

create table t16(
	id int primary key auto_increment,
	name char(12)
)

主鍵:非空+惟一約束 = 主鍵 primary key 一張表只能定義一個主鍵 若是不指定主鍵 默認是第一個非空+惟一

聯合主鍵 primary key( )

create table t17(
	id int,
  server_name char(12),
  ip char(15),
  port char(5),
  primary key(ip, port)
);

外鍵: foreign key (本身的字段) references 外表(外表字段)

外表字段必須至少是惟一的

學生表

create table student(
	id int primary key auto_increment,
  name char(12) not null,
  gender enum('male', 'female') default 'male',
  class_id int,
  foreign key(class_id) references class_t(cid)
);

班級表

create table class_t(
	cid int primary key auto_increment,
  cname char(12) not null,
  startd date
);

須要先創建班級表,而且寫入數據,讓學生表能夠關聯到

且學生表內有關聯到班級表的,須要修改班級或者刪除,才能對班級表進行修改或者刪除

須要級聯更新、級聯刪除,能夠在foreign key(class_id) references class_t(cid) on update cascade on delete cascade

刪除班級表中一個班,那學生表中關聯這一個班的數據也會刪除

注意空字符串' '和空null在數據庫中不同

8.修改表

語法:
1. 修改表名
      ALTER TABLE 表名 
                      RENAME 新表名;

2. 增長字段
      ALTER TABLE 表名
                      ADD 字段名  數據類型 [完整性約束條件…],
                      ADD 字段名  數據類型 [完整性約束條件…];
                            
3. 刪除字段
      ALTER TABLE 表名 
                      DROP 字段名;

4. 修改字段
      ALTER TABLE 表名 
                      MODIFY  字段名 數據類型 [完整性約束條件…];
      ALTER TABLE 表名 
                      CHANGE 舊字段名 新字段名 舊數據類型 [完整性約束條件…];
      ALTER TABLE 表名 
                      CHANGE 舊字段名 新字段名 新數據類型 [完整性約束條件…];

5.修改字段排列順序/在增長的時候指定字段位置
    ALTER TABLE 表名
                     ADD 字段名  數據類型 [完整性約束條件…]  FIRST;
    ALTER TABLE 表名
                     ADD 字段名  數據類型 [完整性約束條件…]  AFTER 字段名;
    ALTER TABLE 表名
                     CHANGE 字段名  舊字段名 新字段名 新數據類型 [完整性約束條件…]  FIRST;
    ALTER TABLE 表名
                     MODIFY 字段名  數據類型 [完整性約束條件…]  AFTER 字段名;

9.表與表之間的關係

多對一:

  • 學生-班級

  • 多個學生是一個班級的

  • 學生表有一個外鍵關聯班級

  • 書籍-做者

  • 商品-訂單

多對多:

  • 學生-班級  多對一 多個學生對應一個班級
  • 班級-學生 多對一 多個班級對應一個學生
  • 多建立一張表,關聯兩個外鍵,表示學生id和班級id

一對一:

  • 客戶-學生
  • 客戶id unique
  • 學生id foreign key unique

10.查詢

select * from employee;

select id,name from employee;               查詢幾個字段

select id,name as n from employee;        查詢出來的時候重命名(加as)

select id,name n from employee;             查詢出來的時候重命名(空格)

select distinct post from employee;         查詢結果去除重複項

select distinct age,sex from employee;    查詢的結果只有當年齡和性別都重複纔會是重複項

select emo_name,salary*12 as annual_salary from employee;  四則運算(計算年薪)

select concat(emp_name,':',salary) from employee;  拼接concat,有時候姓和名的拼接

select concat_ws('|','apple','male'); 默認以第一個字符爲拼接符進行拼接後面的內容

結合case語句  case ... end

selcet
	(
		case
    when emp_name = 'apple' then
    	emp_name
    when emp_name = 'banana' then
    	concat(emp_name, 'BIGSB')
    else
    	concat(emp_name, 'SB')
  	end
  ) as new_name
from employee;

where 約束

篩選符合條件的行

  • 比較運算符: > < >= <=  !=
  • between 80 and 100 值在80到100之間
  • in(80, 90, 100) 值是80或者90或者100
  • like 'e%' 模糊匹配
    • 通配符能夠是%或者'_',%表示任意多個字符,'_'表示一個字符
  • 邏輯運算符: and or not
  • 正則
    • regexp '^j' 以j開頭的
    • regex 'g$' 以g結尾

分組

group by :

根據誰分組,能夠求這個組的總人數,最大值,最小值,平均值,求和,可是求出來的值只和分組字段對應

並不和其餘任何字段對應,這個時候查出來的全部字段都不生效

聚合

count(根據分組計數) max min sum avg

select sex,count(sex) from employee group by sex; 顯示男女分別有多少人

select age,count(age) from employee group by age; 顯示不一樣的年齡有多少人

更好的查看

select post,group_concat(emp_name) from employee group by post; 會自動拼接,可是拿不到每個的值

選擇各個部門最低工資的人

select post,emp_name,min(salary) from employee group by post;  這是錯誤的,由於分組顯示的姓名不是真正工資最低的,是分組出來

找不到對應的人

having 過濾語句

在having條件中可使用聚合函數

適合去篩選符合條件的某一組數據,而不是某一行數據

先分組,再過濾:求人數大於xx的性別,求年齡大於多少人的年齡

獲取每一個部門的平均工資篩選出平均值大於10000的部門

select post,avg(salary) from employee group by post having avg(salary) > 10000;

order by 查詢排序

默認升序排 asc

降序 desc

select * from employee order by selery; 根據薪資從小到大排

select * from employee order by age desc; 根據年齡從大到小排

select * from employee order by age,salary desc; 先根據年齡從小到大排,年齡相同,再根據薪資從大到小排

limit m,n

limit n 取前幾條數據 不寫m默認爲0

select * from employee order by selery desc limit 3; 只取薪資最高的前三我的的數據

limit m,n 從第m+1項開始取n項

limit n offset m 與上面相同,從m+1項開始取n項

11.多表查詢

連表查詢

一張department表,一張employee員工表

select * from department, employee; 會產生一個大表,表是笛卡爾積的形式產生的

select * from department, employee where department.id = dep_id; id有多個須要指定是department仍是employee表裏的

所謂連表:

  • 老是在鏈接的時候建立一張大表,裏面存放的是兩張表的笛卡爾積
  • 再根據條件進行篩選就能夠了
  • where 條件 group by 分組 order by limit 均可以正常使用

表與表之間的鏈接方式:

  • select * from 表1,表2 where 條件
  • 內鏈接 inner join ... on ...
    • 必須左表和右表中條件相互匹配的項纔會顯示出來
    • select * from 表1inner join 表2 on 條件
    • select * from department inner join employee on department.id = employee.dep_id;
    • select * from department as d1 inner join employee as e1 on d1.id = e1.dep_id;           注意是先作連表,因此重命名能夠用
  • 外鏈接
    • mysql不支持 經過
    • select * from 表1 left join 表2 on 條件
    • union
    • select * from 表1 right join 表2 on 條件
    • 右表顯示所有,左表中的數據必須和右表條件相互匹配的項纔會顯示出來
    • 左表顯示所有,右表中的數據必須和左表條件相互匹配的項纔會顯示出來
    • select * from 表1 left join 表2 on 條件
    • 左外鏈接 left join
    • 右外鏈接 right join
    • 全外鏈接 full join

12.子查詢

  • 帶in的子查詢 select * from 表 where 字段 in (select 字段 from 表 where 條件)
  • 帶比較子查詢 select * from 表 where 字段 > (select 字段 from 表 where 條件)

查詢平均年齡在25歲以上的部門

select dep_id from employee group by dep_id having avg(age)>25;

select name from department where id in (select dep_id from employee group by dep_id having avg(age)>25);

查看技術部員工姓名

select name from employee where dep_id in (select id from department where name='技術');

查詢大於全部人平均年齡的員工名與年齡

select name, age from employee where age>(select avg(age) from employee);

查詢大於部門內平均年齡的員工名與年齡

select name,age from employee as t1 inner join (select dep_id,avg(age) as avg_age from employee group by dep_id) as t2 on t1.dep_id=t2.dep_id where age>avg_age;

exists關鍵字表示存在,使用這個關鍵字以後內層查詢語句不返回查詢的記錄,返回一個真假值,返回True,外層查詢語句將進行查詢,當返回值爲False,外層查詢語句不進行查詢

select * from employee where exists (select id from department where id=200);

13.索引

工做中必備:

建立

刪除

知道用了它會加快查詢速度

面試:

  • 數據準備
  • 讀取一次硬盤時間開銷
    • 尋道時間 0.05ms
    • 3600轉/7200轉 每分鐘 一圈 60/7200 = 0.09ms
    • 找到一圈上的數據平均時間爲0.045ms
    • 從硬盤上讀取一次數據的時間大概是0.1ms
    • cpu每秒可執行5億條指令,0.1ms可執行5萬條cpu指令
    • 磁盤的預讀性原理:每一次讀區硬盤的單位不是你要多少就讀多少,每一次讀數據塊的大小都是固定的,linux 4096字節 -block
  • 新的數據結構-樹
    • root 根節點
    • branch 分支節點
    • leaf 葉子結點
  • mysql中存儲數據的兩種方式
    • 在分支節點不會存儲數據(讓樹的高度儘可能矮,讓查詢一個數據的效率穩定),都是葉子結點存儲數據
    • 葉子結點之間是雙向鏈表,查找範圍很是快
    • 若是不是平衡樹,簡單的樹最差會退化爲線性的
    • 平衡樹 balance tree 簡稱b樹:可以讓查找某一個值的查找速度儘可能平衡,平衡樹不必定是二叉樹
    • b樹改進以後變成B+樹
  • 彙集索引(聚簇索引)和非彙集索引(非聚簇索引、輔助索引)都是用b+樹進行存儲的
    • 葉子結點不存放具體的整行數據,而是存放的這一行的主鍵的值
    • innodb主鍵會默認建立一個彙集索引
    • 全表數據都存儲在葉子結點上
    • 彙集索引的好處是一次就能夠找到對應的值,很差的點就是存儲的數據少,只有Innodb必有彙集索引,且僅有一個主鍵
    • 非彙集索引存儲的是對應的地址,還要查表才能找到數據,優勢是能夠存更多數據,缺點是須要再查表,innodb myisam
  • 索引的建立與刪除
    • create index 索引名 on 表(字段)
    • drop index 索引名 on 表
    • 建立主鍵 primary key 彙集索引+非空+惟一
    • 建立惟一約束 unique 輔助索引+惟一
    • 添加一個普通索引
  • 正確使用索引
    • create index ind_mix on s1(id, name, email);
    • 必須帶着最左邊的列作條件,從出現範圍開始整條索引失效
    • 條件1and條件2 兩個同時成立纔會成立,但凡一個條件不成立則最終結果不成立
    • 條件1or條件2 只要一個條件成立就成立
    • 多個條件的組合,若是使用and鏈接,其中一列使用索引,均可以加快查詢速度,使用or鏈接,必須全部的列含有索引,才能加快查詢速度
    • 條件1建立了索引,若是條件1不知足,那確定不成立,不用再找條件2
    • 條件1建立了索引,若是條件1不知足,那不必定不成立,還要找條件2,若是條件2每索引,那麼查詢的效率仍是低
    • 範圍越大越慢
    • 範圍越小越快
    • 若是like 'a%' 快
    • 若是like '%a' 慢
    • 1/10如下的重複率比較合適建立索引
    • 對哪一個字段建立了索引,就用哪一個字段來查,查詢的字段不是索引字段,查詢的速度也不會加快
    • 在建立索引的時候,應該對區分度比較大的列進行建立索引
    • 範圍
    • 條件列參與運算,或者使用函數會下降索引查詢速度
    • and 和 or
    • 聯合索引:最左前綴原則

函數都是處理簡單的邏輯

存儲過程處理的邏輯比較複雜

複雜的邏輯都是用python代碼來處理

簡單的數據增刪改查用sql解決

覆蓋索引:

查詢過程當中不須要回表

索引合併:

分別建立的兩個索引在某一次查詢中臨時合併成一條索引 a=1 or b=2

執行計劃:

explain select 語句 可以查看sql語句有沒有按照預期執行,能夠查看索引的使用狀況,type等級

慢查詢優化:

  • 首先從mysql的角度優化
    • 把每一句話單獨執行,找哦到效率低的表,優化這句mysql
    • 瞭解業務場景,適當建立索引,幫助查詢
    • 儘可能用連表代替子查詢
    • 確認命中索引的狀況
  • 考慮修改表結構
    • 拆表
    • 把固定的字段往前調整
  • 使用執行計劃,觀察sql的type經過以上調整是否提升

mysql慢日誌:

  • 在mysql的配置中開啓並設置一下
  • 在超過設定時間後,這條sql老是會被記錄下來,這個時候咱們能夠對這些被記錄的sql進行按期優化

14.pymysql模塊

通常都是經過python操做數據

import pymysql

conn = pymysql.connect(host='127.0.0.1', user='root', password='123', database='homework')

cur = conn.cursor() #cursor遊標 默認以元組返回
#cur = conn.cursor(cursor=pymysql.cursors.DictCursoor) #取出來的數據是以字典返回 更浪費空間
cur.execute('select * from student;')

ret = cur.fetchone()
print(ret)  # 拿到一條數據

ret2 = cur.fetchmany(10) # 拿到多條數據
print(ret2)

ret3 = cur.fetchall() # 拿到全部剩餘的數據
print(ret3)
print(cur.rowcount) # 表示拿到多少條數據

cur.close()
conn.close()
#增 刪 改
import pymysql

conn = pymysql.connect(host='127.0.0.1', user='root', password='123', database='homework')

cur = conn.cursor()

try:
	cur.execute('insert into student values(17, "男", 3, "apple")')  #執行了只至關於在內存中插入
	cur.execute('update student set gender ="male" where id=17') # 修改
  cur.execute('delete from student where id=17')
  conn.commit() #提交
except Exception as e:
  print(e)
  conn.rollback() # 回滾

cur.close()
conn.close()

實際在操做中會遇到的問題

結合數據庫和python寫一個登錄

import pymysql

usr = input('username :')
pwd = input('password :')
conn = pymysql.connect(host='127.0.0.1',
                       user='root',
                       password='123',
                       database='test'
												)
conn.cursor()


cur.execute('select * from userinfo where user="%s" and password="%s"'%(usr, pwd))

# select * from userinfo where user = "apple" or 1=1;  --"...    後面的東西註釋了
#sql注入

#最好使用execute自動拼接
cur.execute('select * from userinfo where user=%s and password=%s', (usr, pwd)) #不用拼接,也不用加""

cur.close()
conn.close()

15.數據備份和事務

事務

  • begin #開啓事務
    select age from userinfo where id=1 for update; # 查詢id值,for update 加上行級鎖
    update emp set salary=100000 where id=1; # 完成更新
    commit #提交事務

備份

表和數據的備份

mydqldump.exe

在cmd命令直接執行

mysqldump -h 服務器 -u用戶名 -p密碼 數據庫名 > 備份文件名.sql

回覆數據 在mysql中執行命令

source D:\python\備份文件名.sql

16.小結

數據的

  • insert into 表 values(值)
  • insert into 表(字段1,字段2) values(值1,值2)
  • insert into 表(字段1,字段2) select 字段1,字段2 from 表 2

  • delete from 表 where 條件
  • truncate table 表名

  • update 表 set 字段=值 where 條件

  • select  字段 from 表

    • where 條件 根據條件篩選符合條件的行
    • group by 分組
    • having 過濾條件 根據分組以後的內容進行組的過濾
    • order by 排序
    • limit m,n 從m+1項開始取n項
  • 順序:from 表--> where -> group by -> having  -> select -> order by -> limit m,n

    • 注意重命名不是何時均可以使用的
    • where 條件不能使用select字段的重命名
    • select emp_name as name, age as a from employee order by a;    #order by 可使用select以後的age as a
    • 在mysql中作了having的優化,能夠先找前面是否有重命名,能夠在having後面使用重命名,oracle則沒有
  • 拓展

    • 在執行select語句的時候,其實是經過where,group by,having這幾個語句鎖定對應的行

    • 而後循環每一行執行select語句

    • select name from t where id>2;

      先from t,再where id>2拿到數據,再循環拿到的數據,篩選name字段

    • select name,(select_now()) from t; 一樣也是循環拿到數據進行篩選

若是一個問題既可使用連表查詢也可使用子查詢解決,推薦那個連表查詢,效率更高

習題:

查詢至少有一門可與學號爲1的同窗所學課程相同的同窗的學號和姓名

select sid,sname from student right join (

select distinct student_id from score where cid in (select course_id from score where student_id=1) and student_id != 1;

) as t in student_sid = t.student_id;

查詢課程編號爲‘2’的成績比課程編號‘1’低的全部同窗的學號、姓名

  • 思路:
    • select student_id,sname from student right join
    • (select t1.sid1 from (select student_id as sid2,num as n2 from score where course_id=2) as t2
    • inner join
    • (select student_id as sid1,num as n1 from score where course_id=1) as t1
    • on t1.sid1=t2.sid2 and t2.n2 > t1.n1) as tmp
    • on student_id = tmp.sid1;
    • inner join
    • (select student_id as sid1,num as n1 from score where course_id=1) as t1
    • on t1.sid1=t2.sid2 and t2.n2 > t1.n1;
    • 先把課程編號2的全部學生id,學生成績找出來
    • select student_id as sid2,num as n2 from score where course_id=2;
    • 再把課程編號1的全部學生id,學生成績找出來
    • select student_id as sid1,num as n1 from score where course_id=1;
    • 連表取到知足條件的學生的學號
    • select t1.sid from (select student_id as sid2,num as n2 from score where course_id=2) as t2
    • 連student表找到姓名

正確的使用mysql數據庫

  • 從庫的角度
    • 搭建集羣
    • 讀寫分離
    • 分庫
  • 從表的角度
    • 合理安排表與表之間的關係:該拆的拆,該合的合
    • 把固定長度的字段放在前面
    • 儘可能使用char而不是varchar
  • 從操做數據的角度
    • 建立索引,選擇區分度比較大的列,儘可能選長度比較短的字段建立索引,不要建立沒必要要的索引(拖慢寫入速度,佔空間)
    • 使用索引
    • and 只要有一列索引便可命中
    • or 全部列都有索引纔會命中
    • 查詢的字段不是索引
    • 在條件中使用範圍,結果的範圍越大速度越慢
    • like 'a%' 快,like '%a' 慢且不命中索引
    • 條件列不能參與計算、不能使用函數
    • and / or
    • 聯合索引,遵循最左前綴原則,且從出現範圍開始索引失效
    • 條件中的數據類型和實際字段中的類型必須一致
    • select 字段中應該包含order by中的字段
    • where a between value1 and value2
    • 儘可能在where字段約束數值到一個比較小的範圍:分頁
    • 儘可能使用連表查詢代替子查詢
    • 刪除數據和修改數據的時候條件儘可能使用主鍵
    • 合理的建立和使用索引
相關文章
相關標籤/搜索