python MySql


初識數據庫

參考: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解釋器

Mysql

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
View Code

默認用戶登陸

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

給當前用戶設置密碼

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

啟動客戶端連接server

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

創建用戶

# 創建一個其他用戶
mysql>create user 'guest'@'192.168.14.%' identified by '123';
創建  用戶   "guest"@"ip" identified 密碼
# server查看用戶
mysql>mysql -uguest -p123 -h192.16.14.200;
View Code

 

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個文件
    表結構
數據斷電消失

 

 

 

 

數據庫DDL 語句

操作數據庫
查看所有數據庫  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);
    指定字段名寫入,可以任意的選擇表中你需要寫入的字段進行
View Code

查看中的數據

查表中的數據
    select * from 表

查看表結構
    desc 表名;
        能夠查看到有多少個字段\類型\長度,看不到表編碼,引擎,具體的約束信息只能看到一部分
    show create table 表名;
        能查看字段\類型\長度\編碼\引擎\約束
View Code

數字類型

常用 int,float

定義無符號 unsigned

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
);
View Code

時間

常用 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);    # 在更新的時候使用當前時間更新字段
View Code

字符串

常用 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));
View Code

enum和set

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,'大壯','洗腳,洗腳,洗腳,按摩,打游戲'); #多選內容要在一個""里
View Code

約束

約束某一個字段
無符號的 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 外表(外表字段)
    外表字段必須至少是"唯一"
View Code

無符號

unsigned

create table t10(
  id int unsigned
);
View Code

不能為空

 not null

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

默認值

default

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

唯一約束(UNI)

unique

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

 

聯合唯一

unique

聯合唯一 unique
create table t14(
    id int,
    server_name char(12),
    ip char(15),
    port char(5),
    unique(ip,port)
);
View Code

 

非空 + 唯一約束+主鍵

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
);
View Code

聯合主鍵

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)
);
View Code

 

自增

auto_increment

約束字段為自動增長,被約束的字段必須同時被key約束

create table t20(
    id int primary key auto_increment,
    name char(12)
);
insert into t20(name) values('alex');
View Code

外鍵

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  # 級聯刪除 盡量不用
)
View Code

 

修改表結構

修改表名
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 舊名字 新名字 類型(長度) 約束;
View Code

表之間的關系

一對一
一對多
多對多

小結

存儲引擎
    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
View Code

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

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

 

單表數據查詢

select語句

最簡單的
select *from 表;
select 字段 from 表;
View Code
重命名
select 舊字段 as 新字段 from 表;
select 舊字段 新字段 from 表;
View Code
去重

distinct

select distinct 字段 from 表;
select distinct  age,sex from 表; #顯示表里的age,sex
View Code
連接字符串(分割)

concat() 函數用於連接字符串

concat() 函數用於連接字符串
select concat('姓名: ',字段,'  年薪: ', 字段)  AS 重命名 from 表; 
concat_ws 第一個參數為分隔符
select concat_ws(':',字段,字段)  AS 新表名 from 舊表名 
View Code
四則運算的
select 字段*數字 from 表; 乘法
select 字段*數字 as 重命名 from 表;
select 字段*數字 重命名 from 表;
View Code
使用判斷邏輯
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;       
       
View Code
查詢重命名
1.where條件中不能用select字段的重命名
2.order by 或者having可以使用select字段的重命名
    主要是因為order by 在select語句之后才執行
    having經過了mysql的特殊處理,使得它能夠感知到select語句中的重命名
View Code

 

拓展
在執行select語句的時候,實際上是通過where,group by,having這幾個語句鎖定對應的行
然后循環每一行執行select語句

 

where 篩選

篩選所有符合條件的行

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

 

多條件查詢
select 字段,字段 from 表名 where post="teacher" and salary>10000; #表名后面是判斷條件
View Code
between and(范圍)
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內
View Code
is判斷是否為空
關鍵字IS NULL(判斷某個字段是否為NULL不能用等號,需要用IS)
select 字段1,字段2 from 表 where 字段2 is null;       #判斷字段2為空的
select 字段1,字段2 from 表 where 字段2 is not null;   #判斷字段2不為空的
View Code
in集合查詢
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);
View Code
模糊匹配

like  regexp

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

 

邏輯運算

not\and\or

分組 group by

group by 根據誰分組,可以求這個組的總人數,最大值,最小值,平均值,求和 但是這個求出來的值只是和分組字段對應並不和其他任何字段對應,這個時候查出來的所有其他字段都不生效.

單獨使用GROUP BY關鍵字分組
select post from 表 group by post;
只能篩選行,不能篩選列

注意:我們按照post字段分組,那么select查詢的字段只能是post,想要獲取組內的其他相關信息,需要借助函數
group by與聚合函數一起使用
select sex,count(id) from 表 group by sex; 
View Code

聚合分組 (根據分組做計數)

count  求個數
max    求最大值   
min    求最小值   
sum    求和                  
avg    求平均       
View Code
舉例
沒有聚合函數
SELECT post,emp_name FROM employee GROUP BY post;
select 字段1,字段2 from 表 group by 字段1
View Code

having 過濾語句

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

order by 排序

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

limit限制查詢的記錄數

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一樣的意思
View Code

 

多表查詢

有兩種:
    連表查
        內連接  必須左表和右表中條件互相匹配的項才會被顯示出來
            表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;
View Code

外連接

左外連接 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;
View Code

右外連接

右外連接 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
View Code

全外連接

全外連接:在內連接的基礎上增加左邊有右邊沒有的和右邊有左邊沒有的結果
# 注意:mysql不支持全外連接 full JOIN
# 強調:mysql可以下面的方式間接實現全外連接
View Code
全外連接 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;
View Code

例子

# 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 都正常的使用就可以了
View Code

子查詢

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;
View Code

EXISTS關鍵字

EXISTS關字鍵字表示存在。在使用EXISTS關鍵字時,內層查詢語句不返回查詢的記錄。 而是返回一個真假值。True或False 當返回True時,外層查詢語句將進行查詢;當返回值為False時,外層查詢語句不進行查詢

mysql> select * from employee
    ->     where exists
    ->         (select id from department where id=204);
Empty set (0.00 sec)
View Code

小結

如果一個問題既可以使用連表查詢解決,也可使用子表查詢
推薦使用連表查詢,因為效率高.

數據准備

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次數都相同
    只在葉子節點存儲數據
        為了降低樹的高度
    葉子節點之前加入了雙向連接
        為了查找范圍的時候比較快
View Code

 

兩種索引的差距

兩種索引的差別
聚集索引 聚簇索引
    Innodb 必有且僅有一個 :主鍵
    innodb存儲引擎中的 主鍵默認就會創建一個聚集索引
    全表數據都存儲在葉子節點上 -- Innodb存儲引擎中的主鍵
非聚集(簇)索引 輔助索引
    innodb
    myisam
    葉子節點不存放具體的整行數據,而是存儲的這一行的主鍵的值

數據庫使用的時候注意事項

從搭建數據庫的角度上來描述問題

建表的角度上
    1.合理安排表關系
    2.盡量把固定長度的字段放在前面
    3.盡量使用char代替varchar
    4.分表: 水平分,垂直分

使用sql語句的時候

使用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;  # 比較差
View Code

 

分頁

使用索引的時候分頁不要用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合並成一個索引
View Code

覆蓋索引

覆蓋索引:在查詢過程中不需要回表   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   相對慢
View Code

執行計划

什么是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通過以上調整是否提高
View Code

 

mysql的慢日志

mysql的慢日志
    # 在mysql的配置中開啟並設置一下
    # 在超過設定時間之后,這條sql總是會被記錄下來,
    # 這個時候我們可以對這些被記錄的sql進行定期優化
View Code

 

SQL SERVER 索引名前綴代表的意思

PK-主鍵

IX-非唯一索引

AK-唯一索引(AX應該是AK(備用鍵))

CK-檢查約束

DF-默認約束

FK-外鍵

 

pymysql模塊

import pymysql

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

增 刪 改

# 增加 刪除 修改
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()            # 關閉庫
View Code

登陸pymysql

結合數據庫 和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";
注入;-- 
注釋掉后面的加--
View Code

 

 

 

事務和鎖

事務介紹

事務就是指邏輯上的一組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; # 提交事務
View Code

表和數據的備份

#語法:
# 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 
View Code

數據恢復

#方法一:
[root@egon backup]# mysql -uroot -p123 < /backup/all.sql

#方法二:
mysql> use db1;
mysql> SET SQL_LOG_BIN=0;   #關閉二進制日志,只對當前session生效
mysql> source /root/db1.sql
View Code
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
View Code


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM