參考:MySQL數據庫階段學習目錄
數據庫優勢
程序穩定性:程序崩潰不會影響數據和服務
數據一致性:所有數據存儲在一起
並發:數據庫本身支持並發
效率:使用數據庫對數據進行的增刪改查效率要高
數據: 描述事物的符號記錄稱為數據 (Data) 數據庫: 專門用來存儲數據 (DataBase,簡稱DB) mysql: 數據庫軟件 (DataBase Management System 簡稱DBMS) 數據庫管理員 管理數據庫軟件(DBA) 數據庫服務器-:運行數據庫管理軟件 數據庫管理軟件:管理-數據庫 數據庫:即文件夾,用來組織文件/表 表:即文件,用來存放多行內容/多條記錄
數據庫分類
關系型數據庫(表結構):
特點相對慢,數據關聯性強
關系型數據庫 : mysql oracle sqllite sql server db2 access
非關系型數據庫(key,value):
特點相對快,數據與數據的關聯性小
非關系型數據庫 : redis mongodb memcache
區別:
關系型數據庫存儲效率相對低,數據與數據之間關聯緊密
關系型數據庫存儲效率相對高,數據與數據之間的關系是key:value
Mysql語句分為三種(了解)
DDL 語句, 數據庫定義語言:數據庫,表,視圖,索引,存儲過程,例如create,drop,alter
DML 語句,數據庫操縱語言:插入、刪除、更新、查詢數據,insert,delete,update,select
DCL 語句, 數據庫控制語言:用戶的訪問權限,grant,revoke
Mysql 默認三個數據庫:
mysql:保存mysql權限,配置參數,狀態信息,主從配置
information_schema: 保存着mysql維護其他數據庫信息,如庫名,表和訪問權限等
performance_schema:數據庫存儲引擎,監視數據庫運行的資源消耗,資源等待等等
Mysql工作流程:
登錄授權認證安全:
查詢,解析,分析,優化,緩存
存儲過程,觸發器,視圖
存儲和提取數據
存儲數據,表信息,用戶操作日志
MySql 安裝:
路徑不能有中文
路徑不能有特殊字符
python -->python.exe
在任何目錄下都能夠找到python.exe文件
才能在任意位置輸入python命令啟動python解釋器
mysqld install 安裝mysql服務 mysql服務就被注冊到操作系統中 net start mysql 啟動mysql服務 net stop mysql 啟動客戶端連接server mysql -uroot -p123 -h192.168.14.12 mysql>select user(); 查看當前登錄的用戶 mysql>set password = password('123'); 給當前用戶設置密碼 創建一個其他用戶 create user 'guest'@'192.168.14.%' identified by '123'; 給一個用戶授權 grant 權限類型 on ftp.* to 'guest'@'192.168.14.%'; grant all grant select on day37.* to 'guest'@'192.168.14.%'; grant select,insert
cmd管理員

mysqld install 安裝mysql服務 mysql服務就被注冊到操作系統中
net start mysql 啟動mysql服務
net stop mysql

# 默認用戶登陸之后並沒有實際操作的權限 # 需要使用管理員root用戶登陸 mysql -uroot -p # mysql5.6默認是沒有密碼的 #遇到password直接按回車鍵

mysql>select user(); 查看當前登錄的用戶 mysql>set password = password('123'); 給當前用戶設置密碼

# 遠程登陸 啟動客戶端連接server mysql -uroot -p123 -h192.168.14.12 #-p可以加密碼但是不建議 -h寫連接server的ip地址

# 創建一個其他用戶 mysql>create user 'guest'@'192.168.14.%' identified by '123'; 創建 用戶 "guest"@"ip" identified 密碼 # server查看用戶 mysql>mysql -uguest -p123 -h192.16.14.200;
python MySql的安裝 啟動和基礎配置---windows版本
鏈接
mysql為我們提供開源的安裝在各個操作系統上的安裝包,包括ios,linux,windows。
mysql的安裝、啟動和基礎配置 —— linux版本 (https://www.cnblogs.com/Eva-J/articles/9664401.html)
mysql的安裝、啟動和基礎配置 —— mac版本 (https://www.cnblogs.com/Eva-J/articles/9664401.html)
mysql的安裝、啟動和基礎配置 —— windows版本 (https://www.cnblogs.com/Eva-J/articles/9669675.html)
存儲引擎
數據的存儲方式-->存儲引擎
使用不同的存儲引擎,數據是已不同方法存儲的
查看存儲引擎:show engines;
Innodb:
Innodb存儲引擎 mysql5.6之后的默認的存儲引擎
數據和索引存儲在一起 2個文件
數據索引\表結構
數據持久化
支持事務 : 為了保證數據的完整性,將多個操作變成原子性操作 : 保持數據安全
支持行級鎖 : 修改的行少的時候使用 : 修改數據頻繁的操作
支持表級鎖 : 批量修改多行的時候使用 : 對於大量數據的同時修改
支持外鍵 : 約束兩張表中的關聯字段不能隨意的添加\刪除 : 能夠降低數據增刪改的出錯率
Myisam存儲引擎
Myisam存儲引擎 mysql5.5之前的默認的存儲引擎
數據和索引不存儲在一起 3個文件
數據\索引\表結構
數據持久化
只支持表鎖
Memory存儲引擎
Memory存儲引擎
數據存儲在內存中, 1個文件
表結構
數據斷電消失
操作數據庫 查看所有數據庫 show databases; 創建一個數據庫 create database 數據庫名; 切換到這個庫下 use 數據庫的名字 查看這個庫下有多少表 show tables; 操作表 創建一張表 create table student(name char(12),age int); 刪除表名 drop table student 查看表結構 desc student; 操作數據 插入數據 : insert into student values ('wusir',73); 查詢數據 : select * from student; 修改數據 : update student set age=85 where name='alex'; 刪除數據 : delete from student where name = 'alex';
三種方式
寫入數據
insert into 表 values()

寫入數據的方式
insert into 表 values (值1,值2,值3);
這張表有多少的字段,就需要按照字段的順序寫入多少個值
insert into 表 values (值1,值2,值3),(值1,值2,值3),(值1,值2,值3);
一次性寫入多條數據
insert into 表 (字段1,字段3 ) values (值1,值3);
指定字段名寫入,可以任意的選擇表中你需要寫入的字段進行

查表中的數據 select * from 表 查看表結構 desc 表名; 能夠查看到有多少個字段\類型\長度,看不到表編碼,引擎,具體的約束信息只能看到一部分 show create table 表名; 能查看字段\類型\長度\編碼\引擎\約束
常用 int,float

int 不約束長度,最多表示10位數 float(m,n) m 一共多少位, n 小數部分多少位 # int create table t1( id int, # 默認是有符號的 age tinyint unsigned # 如果需要定義無符號的使用unsigned ); # float double create table t2( f1 float(5,2), # 保留2位小數 並四舍五入 f2 float, f3 double(5,2), f4 double ) insert into t2(f2,f4) values(5.1783682169875975,5.1783682169875975179); # float decimal create table t3( f1 float, # 保留2位小數 並四舍五入 d1 double, d2 decimal(30,20), d3 decimal );
常用 time,date,datetime

date 20190620 time 121953 datetime 20190620121900 datetime 年月日時分秒 year 年 date 年月日 time 時分秒 timestamp 時間戳 create table t4( dt datetime, y year, d date, t time, ts timestamp ); mysql> create table t5( -> id int, -> dt datetime NOT NULL # 不能為空 DEFAULT CURRENT_TIMESTAMP # 默認是當前時間 ON UPDATE CURRENT_TIMESTAMP); # 在更新的時候使用當前時間更新字段
常用 char,varchar
char(18) 最多只能表示255個字符
定長存儲,浪費空間,節省時間
'alex' 'alex '
varchar(18) 最多能表示65535個字符
變長存儲,節省空間,存取速度慢
'alex' 'alex4'

適合使用char 身份證號 手機號碼 qq號 username 12-18 password 32 銀行卡號 適合使用varchar 評論 朋友圈 微博 create table t6(c1 char(1),v1 varchar(1),c2 char(8),v2 varchar(8)); create table t6(c1 char,v1 varchar(1),c2 char(8),v2 varchar(8));

enum 單選 枚舉類型,它的值范圍需要在創建表時通過枚舉方式顯示。 set 多選 set類型可以允許值集合中任意選擇1或多個元素進行組合。對超出范圍的內容將不允許注入,而對重復的值將進行自動去重。 create table t8( id int, name char(18), gender enum('male','female') ) create table t9( id int, name char(18), hobby set('抽煙','喝酒','燙頭','洗腳','按摩') ); insert into t9 values (1,'太白','燙頭,抽煙,喝酒,按摩'); insert into t9 values (1,'大壯','洗腳,洗腳,洗腳,按摩,打游戲'); #多選內容要在一個""里

約束某一個字段 無符號的 int unsigned 不能為空 not null 默認值 default 唯一約束 unique 聯合唯一 unique(字段1,字段2) 自增 auto_increment 只能對數字有效.自帶非空約束 至少是unique的約束之后才能使用auto_increment 主鍵 primary key 一張表只能有一個 如果不指定主鍵,默認是第一個非空+唯一 聯合主鍵 primary key(字段1,字段2) 外鍵 Foreign key Foreign key(自己的字段) references 外表(外表字段) 外表字段必須至少是"唯一"的

create table t10(
id int unsigned
);

create table t11( id int unsigned not null, name char(18) not null );

create table t12( id int unsigned not null, name char(18) not null, male enum('male','female') not null default 'male's );
unique

不能重復 unique 值不能重復,但是null可以寫入多個
create table t13(
id1 int unique,
id2 int
)
unique

聯合唯一 unique create table t14( id int, server_name char(12), ip char(15), port char(5), unique(ip,port) );
not null (不能為空)unique(唯一約束)

非空 + 唯一約束 第一個被定義為非空+唯一的那一列會成為這張表的primary key 一張表只能定義一個主鍵 create table t15( id int not null unique, username char(18) not null unique ); create table t16( username char(18) not null unique, id int not null unique ); create table t17( username char(18) not null unique, id int primary key );
primary key 和 not null unique

聯合主鍵 create table t18( id int, server_name char(12), ip char(15) default '', port char(5) default '', primary key(ip,port) );
auto_increment
約束字段為自動增長,被約束的字段必須同時被key約束

create table t20( id int primary key auto_increment, name char(12) ); insert into t20(name) values('alex');
foreign key (class_id) references class (cid))

班級表 create table class( cid int primary key auto_increment, cname char(12) not null, startd date ) 學生表 create table stu( 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(cid) ) create table stu2( 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(cid) on update cascade # 級聯更新 on delete cascade # 級聯刪除 盡量不用 )

修改表名 alter table 表 rename 新表名 增加字段 alter table 表 add age int not null 更改字段順序 alter table 表 add 新字段名 date after 字段名 # 新字段名放在字段名下 刪除字段名 alter table 表 drop 字段名 修改字段類型 alter table 表 modify 字段名 類型() not null alter table 表 change 舊名字 新名字 類型(長度) 約束;
一對一
一對多
多對多
小結
存儲引擎 Innodb mysql5.6之后的默認存儲引擎 2個文件,4個支持(支持事務,行級鎖,表級鎖,外鍵) Myisam mysql5.5之前的默認存儲引擎 3個文件 支持表級鎖 Memory 1個文件 數據斷電消失 數據類型 數字 : bool int float(7,2) 日期 : date time datetime year 字符串 : char 定長 效率高浪費空間 255 varchar 變長 效率低節省空間 65535 enum 和 set : 單選和多選 約束 unsigned 無符號的 not null 非空 default 設置默認值 unique 唯一,不能重復 unique(字段1,字段2,字段3) 聯合唯一 auto_increment 自增 int 必須至少unique字段,自帶not null primary key 主鍵 not null + unique 一張表只能有一個主鍵 foreign key 外鍵 a表中有一個字段關聯b表中的一個unique a表中的是外鍵 建表 create table 表名( 字段名1 類型(長度) 約束, 字段名1 類型(選項) 約束, ); 修改表結構 alter table 表名 rename 新名字; alter table 表名 add 字段名 類型(長度) 約束 after 某字段; alter table 表名 drop 字段名; alter table 表名 modify 字段名 類型(長度) 約束 first; alter table 表名 change 舊字名 新名字 類型(長度) 約束; 表之間的關系 一對一 一對多 多對多 刪除表 drop table 表名;

增 insert into 表(字段,...) values (值,...); insert into t1 value (1,'大壯','male','上課,寫作業'); insert into t1 values(2,'杜相璽','male','寫作業,考試'); insert into t1 values(3,'b哥','male','寫作業'),(4,'庄博','male','考試'); insert into t1(username,hobby) values ('楊得港','上課,寫作業,考試'),('李帥','考試') insert into t2(id,name) select id,username from t1; insert into 表 values (值) insert into 表(字段,字段2) values (值,值2) insert into 表(字段,字段2) select 字段1,字段2 from 表2

刪 清空表 delete from 表; 會清空表,但不會清空自增字段的offset(偏移量)值 truncate table 表; 會清空表和自增字段的偏移量 刪除某一條數據 delete from 表 where 條件;

改 update 表 set 字段=值 where 條件; update 表 set 字段=值,字段=值 where 條件;

select *from 表; select 字段 from 表;

select 舊字段 as 新字段 from 表; select 舊字段 新字段 from 表;
distinct

select distinct 字段 from 表; select distinct age,sex from 表; #顯示表里的age,sex
concat() 函數用於連接字符串

concat() 函數用於連接字符串 select concat('姓名: ',字段,' 年薪: ', 字段) AS 重命名 from 表; concat_ws 第一個參數為分隔符 select concat_ws(':',字段,字段) AS 新表名 from 舊表名

select 字段*數字 from 表; 乘法 select 字段*數字 as 重命名 from 表; select 字段*數字 重命名 from 表;

case when語句 相當於 if條件判斷句 select ( case when emp_name = 'jingliyang' then emp_name when emp_name = 'alex' then CONCAT(emp_name,'_BIGSB') ELSE concat(emp_name, 'SB') END ) as new_name from employee;

1.where條件中不能用select字段的重命名 2.order by 或者having可以使用select字段的重命名 主要是因為order by 在select語句之后才執行 having經過了mysql的特殊處理,使得它能夠感知到select語句中的重命名
拓展
在執行select語句的時候,實際上是通過where,group by,having這幾個語句鎖定對應的行
然后循環每一行執行select語句
篩選所有符合條件的行

where 篩選所有符合條件的行 比較運算符 > < >= <= <> != 范圍 between 10000 and 20000 要1w-2w之間的 in (10000,20000) 只要10000或者20000的 模糊匹配 like % 通配符 表示任意長度的任意內容 _ 通配符 一個字符長度的任意內容 regexp '^a' 'g$' 邏輯運算 not\and\or

select 字段 from 表 where post='sale'; # post='sale' 是判斷條件

select 字段,字段 from 表名 where post="teacher" and salary>10000; #表名后面是判斷條件

select 字段0,字段1 from 表 where 字段1 between 10000 and 20000; # 判斷字段1在 10000和20000范圍內 select 字段0,字段1 from 表 where 字段1 not between 10000 and 20000;# 判斷字段1不在 10000和20000內

關鍵字IS NULL(判斷某個字段是否為NULL不能用等號,需要用IS) select 字段1,字段2 from 表 where 字段2 is null; #判斷字段2為空的 select 字段1,字段2 from 表 where 字段2 is not null; #判斷字段2不為空的

select 字段1,字段2 from 表 where salary=3000 or salary=3500 or salary=4000 or salary=9000 ; select 字段1,字段2 from 表 where 字段2 in(3000,3500,4000,9000); select 字段1,字段2 from 表 where 字典2 not in(3000,3500,4000,9000);

like % 通配符 表示任意長度的任意內容 select*from 表 where 字段 like '%g%'; _ 通配符 一個字符長度的任意內容 regexp 正則 '^a' #開頭^ 'g$' #$結尾

group by 根據誰分組,可以求這個組的總人數,最大值,最小值,平均值,求和 但是這個求出來的值只是和分組字段對應並不和其他任何字段對應,這個時候查出來的所有其他字段都不生效. 單獨使用GROUP BY關鍵字分組 select post from 表 group by post; 只能篩選行,不能篩選列 注意:我們按照post字段分組,那么select查詢的字段只能是post,想要獲取組內的其他相關信息,需要借助函數 group by與聚合函數一起使用 select sex,count(id) from 表 group by sex;

count 求個數
max 求最大值
min 求最小值
sum 求和
avg 求平均

沒有聚合函數 SELECT post,emp_name FROM employee GROUP BY post; select 字段1,字段2 from 表 group by 字段1

# 執行優先級從高到低:where > group by > having 1. Where 發生在分組group by之前,因而Where中可以有任意字段,但是絕對不能使用聚合函數。 2. Having發生在分組group by之后,因而Having中可以使用分組的字段,無法直接取到其他字段,可以使用聚合函數

having過濾 select post,avg(salary) from employee group by post having avg(salary)>10000; select 字段, 聚合函數 from 表 group by 字段 having 聚合函數>10000

默認是升序 asc(升序) 降序 desc select *from 表 order by age #從小到大看年齡 select *from 表 order by age desc #從大到小看年齡 select *from 表 order by 字段1,字段2 desc #字段1從小到大,字段2從大到小 優先根據age從小到大排,在age相同的情況下,再根據薪資從大到小排

select *from 表 order by 字段 desc limit 1; #取第一個 select *from 表 order by 字段 desc limit 3; #取前三個 select *from 表 order by 字段 desc limit 2,1; #取第3個 limit m,n 從m+1項開始,取n項 如果不寫m,m默認為0 # limit m,n 和 limit n offset m一樣的意思
多表查詢
有兩種: 連表查 內連接 必須左表和右表中條件互相匹配的項才會被顯示出來 表1 inner join 表2 on 條件 外鏈接 會顯示條件不匹配的項 left join 左表顯示全部,右表中的數據必須和左表條件互相匹配的項才會被顯示出來 right join 右表顯示全部,左表中的數據必須和右表條件互相匹配的項才會被顯示出來 全外連接 left join union right join 子查詢 select * from 表 where 字段 = (select 字段 from 表 where 條件) select * from 表 where 字段 > (select 字段 from 表 where 條件) select * from 表 where 字段 in (select 字段 from 表 where 條件)
所謂連表
總是在連接的時候創建一張大表,里面存放的是兩張表的笛卡爾積
再根據條件進行篩選就可以了

內連接 inner join ... on ... select * from 表1,表2 where 條件;(了解) select * from 表1 inner join 表2 on 條件 select * from department inner join employee on department.id = employee.dep_id; select * from department as t1 inner join employee as t2 on t1.id = t2.dep_id;

左外連接 left join ... on ... select * from 表1 left join 表2 on 條件 select * from department as t1 left join employee as t2 on t1.id = t2.dep_id;
右外連接

右外連接 right join ... on ... select * from 表1 right join 表2 on 條件 select * from department as t1 right join employee as t2 on t1.id = t2.dep_id
全外連接

全外連接:在內連接的基礎上增加左邊有右邊沒有的和右邊有左邊沒有的結果 # 注意:mysql不支持全外連接 full JOIN # 強調:mysql可以下面的方式間接實現全外連接

全外連接 union select * from department as t1 left join employee as t2 on t1.id = t2.dep_id union select * from department as t1 right join employee as t2 on t1.id = t2.dep_id;
例子

# 1.找到技術部的所有人的姓名 # select * from department d inner join employee e on e.dep_id = d.id; # select e.name from department d inner join employee e on e.dep_id = d.id where d.name='技術'; # 2.找到人力資源部的年齡大於40歲的人的姓名 # select * from department d inner join employee e on e.dep_id = d.id # select * from department d inner join employee e on e.dep_id = d.id where d.name='人力資源' and age>40; # 3.找出年齡大於25歲的員工以及員工所在的部門 # select * from department d inner join employee e on e.dep_id = d.id; # select e.name,d.name from department d inner join employee e on e.dep_id = d.id where age>25; # 4.以內連接的方式查詢employee和department表,並且以age字段的升序方式顯示 # select * from department d inner join employee e on e.dep_id = d.id order by age; # 5.求每一個部門有多少人 # select d.name,count(e.id) from department d left join employee e on e.dep_id = d.id group by d.name; # 且按照人數從高到低排序 # select d.name,count(e.id) c from department d left join employee e on e.dep_id = d.id group by d.name order by c desc; # 所謂連表就是把兩張表連接在一起之后 就變成一張大表 從from開始一直到on條件結束就看做一張表 # 之后 where 條件 group by 分組 order by limit 都正常的使用就可以了
1:子查詢是將一個查詢語句嵌套在另一個查詢語句中。 2:內層查詢語句的查詢結果,可以為外層查詢語句提供查詢條件。 3:子查詢中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等關鍵字 4:還可以包含比較運算符:= 、 !=、> 、<等

# 查詢平均年齡在25歲以上的部門名 # select name from department where id in ( # select dep_id from employee group by dep_id having avg(age)>25); # 查看技術部員工姓名 # 先查詢技術部的部門id # select id from department where name = '技術'; # 再根據這個部門id找到對應的員工名 # select name from employee where dep_id =(select id from department where name = '技術'); # select name from employee where dep_id in (select id from department where name = '技術'); # 查看不足1人的部門名 # 先把所有人的部門id查出來 # select distinct dep_id from employee; # 然后查詢部門表,把不在所有人部門id這個范圍的dep_id找出來 # select name from department where id not in (select distinct dep_id from employee); # 查詢大於所有人平均年齡的員工名與年齡 # 求平均年齡 # select avg(age) from employee; # select * from employee where age >28; # select name,age from employee where age >(select avg(age) from employee); # 查詢大於部門內平均年齡的員工名、年齡 # select dep_id,avg(age) from employee group by dep_id; # select name,age from employee as t1 inner join (select dep_id,avg(age) avg_age from employee group by dep_id) as t2 # on t1.dep_id = t2.dep_id where age>avg_age;

mysql> select * from employee -> where exists -> (select id from department where id=204); Empty set (0.00 sec)
小結
如果一個問題既可以使用連表查詢解決,也可使用子表查詢
推薦使用連表查詢,因為效率高.
open('file') as f for line in f: pass 10個字節 一塊內容也很快就會被用到 每一次讀取硬盤的單位不是你要多少就讀多少 每一次讀取的數據塊的大小都是固定的 4096個字節 - block塊
索引的創建與刪除 創建主鍵 primary key 聚集索引 + 非空 + 唯一 創建唯一約束 unique 輔助索引 + 唯一 添加一個普通索引 添加: create index 索引名 on 表(字段); 刪除: drop index 索引名 on 表;

# root 根節點 # branch 分支節點 # leaf 葉子節點 # 父子節點 b+樹 b是balance 平衡的意思 為了保證每一個數據查找經歷的IO次數都相同 只在葉子節點存儲數據 為了降低樹的高度 葉子節點之前加入了雙向連接 為了查找范圍的時候比較快
兩種索引的差別 聚集索引 聚簇索引 Innodb 必有且僅有一個 :主鍵 innodb存儲引擎中的 主鍵默認就會創建一個聚集索引 全表數據都存儲在葉子節點上 -- Innodb存儲引擎中的主鍵 非聚集(簇)索引 輔助索引 innodb myisam 葉子節點不存放具體的整行數據,而是存儲的這一行的主鍵的值
建表的角度上 1.合理安排表關系 2.盡量把固定長度的字段放在前面 3.盡量使用char代替varchar 4.分表: 水平分,垂直分
使用sql語句的時候 1.盡量用where來約束數據范圍到一個比較小的程度,比如說分頁的時候 2.盡量使用連表查詢而不是子查詢 3.刪除數據或者修改數據的時候盡量要用主鍵作為條件 4.合理的創建和使用索引

1.查詢的條件字段不是索引字段 對哪一個字段創建了索引,就用這個字段做條件查詢 2.在創建索引的時候應該對區分度比較大的列進行創建 1/10以下的重復率比較適合創建索引 3.范圍 范圍越大越慢 范圍越小越快 like 'a%' 快 like '%a' 慢 4.條件列參與計算/使用函數 5.and和or id name select * from s1 where id = 1800000 and name = 'eva'; select count(*) from s1 where id = 1800000 or name = 'eva'; 多個條件的組合,如果使用and連接 其中一列含有索引,都可以加快查找速度 如果使用or連接 必須所有的列都含有索引,才能加快查找速度 6.聯合索引 : 最左前綴原則(必須帶着最左邊的列做條件,從出現范圍開始整條索引失效) (id,name,email) select * from s1 where id = 1800000 and name = 'eva' and email = 'eva1800000@oldboy'; select * from s1 where id = 1800000 and name = 'eva'; select * from s1 where id = 1800000 and email = 'eva1800000@oldboy'; select * from s1 where id = 1800000; select * from s1 where name = 'eva' and email = 'eva1800000@oldboy'; (email,id,name) select * from s1 where id >10000 and email = 'eva1800000@oldboy'; 7.條件中寫出來的數據類型必須和定義的數據類型一致 select * from biao where name = 666 # 不一致 8.select的字段應該包含order by的字段 select name,age from 表 order by age; # 比較好 select name from 表 order by age; # 比較差
使用索引的時候分頁不要用limit 使用where 300萬條數據 分頁 page = 1 num_per = 10 tmp = (page-1)*num_per = 1-1=0*10 = 0 select * from 表 where id between tmp and tmp+num_per page +=1 = 2 tmp = (page-1)*num_per = 10 select * from 表 where id between 10 and 20 select * from 表 limit 10,10 select * from 表 limit 20,10 select * from 表 limit 2999990,10

索引合並 :分開創建在查詢過程中臨時合並成一條 Using union(ind_id,ind_email) 創建索引的時候 create index ind_id on s1(id) create index ind_email on s1(email) select * from s1 where id=100 or email = 'eva100@oldboy' 臨時把兩個索引ind_id和ind_email合並成一個索引

覆蓋索引:在查詢過程中不需要回表 Using index 對id字段創建了索引 select id from s1 where id =100 覆蓋索引:在查找一條數據的時候,命中索引,不需要再回表 select count(id) from s1 where id =100 覆蓋索引:在查找一條數據的時候,命中索引,不需要再回表 select max(id) from s1 where id =100 覆蓋索引:在查找一條數據的時候,命中索引,不需要再回表 select name from s1 where id =100 相對慢
什么是mysql的執行計划?用過explain么? 在執行sql語句之前,mysql進行的一個優化sql語句執行效率的分析(計划),可以看到有哪些索引,實際用到了那個索引,執行的type等級 id name email select * from s1 where id = 1000000 and name=eva and email = 'eva1000000@oldboy'; 有沒有索引 有幾個 用哪一個索引比較效率高 explain select * from s1 where id = 1000000 and name=eva and email = 'eva1000000@oldboy';

慢查詢優化 :
首先從sql的角度優化
把每一句話單獨執行,找到效率低的表,優化這句sql
了解業務場景,適當創建索引,幫助查詢
盡量用連表代替子查詢
確認命中索引的情況
考慮修改表結構
拆表
把固定的字段往前調整
使用執行計划,觀察sql的type通過以上調整是否提高

mysql的慢日志 # 在mysql的配置中開啟並設置一下 # 在超過設定時間之后,這條sql總是會被記錄下來, # 這個時候我們可以對這些被記錄的sql進行定期優化
SQL SERVER 索引名前綴代表的意思
PK-主鍵
IX-非唯一索引
AK-唯一索引(AX應該是AK(備用鍵))
CK-檢查約束
DF-默認約束
FK-外鍵

import pymysql db = pymysql.connect("數據庫ip","用戶","密碼","數據庫" ) # 打開數據庫連接 cursor.execute("SELECT VERSION()") # 使用 execute() 方法執行 SQL 查詢 data = cursor.fetchone() # 使用 fetchone() 方法獲取單條數據 print ("Database version : %s " % data) db.close() # 關閉數據庫連接

conn = pymysql.connect(host='127.0.0.1', user='root', password="123", database='homework') cur = conn.cursor(cursor=pymysql.cursors.DictCursor) # 查詢返回字典 cur = conn.cursor() # cursor游標 cur.execute('select * from student;') print(cur.rowcount) # 獲取查出多少行,便於使用fetchone取所有結果 # for i in range(cur.rowcount): # ret = cur.fetchone() # 獲取一條結果 # print(ret) try: cur.execute('select * from student;') ret = cur.fetchone() # 獲取一條結果 print(ret) ret2 = cur.fetchmany(10) # 獲取多條結果 print(ret2) ret3 = cur.fetchall() # 獲取全部結果 print(ret3) except pymysql.err.ProgrammingError as e: print(e) cur.close() conn.close()

# 增加 刪除 修改 conn = pymysql.connect(host='127.0.0.1', user='root', password="123", database='homework') cur = conn.cursor() # cursor游標 try: cur.execute('insert into student values(18,"男",3,"大壯")') # 增 cur.execute('update student set gender = "女" where sid = 17') # 改 cur.execute('delete from student where sid = 17') # 刪 conn.commit() except Exception as e: print(e) conn.rollback() # 可以試一下 myisam cur.close() # 關閉游標 conn.close() # 關閉庫

結合數據庫 和python 寫一個登錄 user = input('username :') pwd = input('password :') conn = pymysql.connect(host='127.0.0.1', user='root', password="123", database='day42') sql = 'select * from userinfo where user = %s and password = %s' cur = conn.cursor() cur.execute(sql,(user,pwd)) print(cur.fetchone()) sql注入 傳參數,注意sql注入的問題,傳參數通過execute方法來傳 execute('select * from 表 where name = %s',('alex',)) # select * from userinfo where user = "1869" or 1=1;-- " and password = "3714"; 注入;-- 注釋掉后面的加--
事務就是指邏輯上的一組SQL語句操作,組成這組操作的各個SQL語句,執行時要么全成功要么全失敗
事務的四大特性:
1.原子性(Atomicity) 事務是一個不可分割的單位,事務中的所有SQL等操作要么都發生,要么都不發生。 2.一致性(Consistency) 事務發生前和發生后,數據的完整性必須保持一致。 3.隔離性(Isolation) 當並發訪問數據庫時,一個正在執行的事務在執行完畢前,對於其他的會話是不可見的,多個並發事務之間的數據是相互隔離的。也就是其他人的操作在這個事務的執行過程中是看不到這個事務的執行結果的,也就是他們拿到的是這個事務執行之前的內容,等這個事務執行完才能拿到新的數據。 4.持久性(Durability) 一個事務一旦被提交,它對數據庫中的數據改變就是永久性的。如果出了錯誤,事務也不允撤銷,只能通過'補償性事務'。
事務的開啟:
數據庫默認事務是自動提交的,也就是發一條sql他就執行一條。如果想多條sql放在一個事務中執行,則需要使用事務進行處理。當我們開啟一個事務,並且沒有提交,mysql會自動回滾事務。或者我們使用rollback命令手動回滾事務。

begin; # 開啟事務 select * from emp where id = 1 for update; # 查詢id值,for update添加行鎖; update emp set salary=10000 where id = 1; # 完成更新 commit; # 提交事務

#語法: # mysqldump -h 服務器 -u用戶名 -p密碼 數據庫名 > 備份文件.sql #示例: #單庫備份 mysqldump -uroot -p123 db1 > db1.sql mysqldump -uroot -p123 db1 table1 table2 > db1-table1-table2.sql #多庫備份 mysqldump -uroot -p123 --databases db1 db2 mysql db3 > db1_db2_mysql_db3.sql #備份所有庫 mysqldump -uroot -p123 --all-databases > all.sql

#方法一: [root@egon backup]# mysql -uroot -p123 < /backup/all.sql #方法二: mysql> use db1; mysql> SET SQL_LOG_BIN=0; #關閉二進制日志,只對當前session生效 mysql> source /root/db1.sql

D:\python_22\day42\tmp.sql 表和數據的備份 備份數據 在cmd命令行直接執行 mysqldump -uroot -p123 -h127.0.0.1 homework > D:\python_22\day42\tmp.sql 恢復數據 在mysql中執行命令 切換到一個要備份的數據庫中 source D:\python_22\day42\tmp.sql 備份庫 備份 mysqldump -uroot -p123 --databases homework > D:\python_22\day42\tmp2.sql 恢復 source D:\python_22\day42\tmp2.sql