第三十五章
數據庫初識
數據庫管理系統-DBMS
網絡應用服務端
咱們要使用服務端的數據 - 須要有一個客戶端
客戶端能夠本身寫 : 將來寫代碼的時候
也能夠用別人寫好的 : 第三方的工具 數據庫管理軟件的公司出版的官方客戶端
數據庫管理系統本質上也是管理一堆文件
只不過人家的管理方式比咱們更高效 更安全
數據庫管理員-DBA
搭建數據庫服務環境
用戶的建立 權限的管理
性能\語句的優化
數據庫的二次開發 : 讓數據庫具備公司的特質
軟件
mysql : 小公司 互聯網企業
甲骨文 oracle : 事業單位 金融企業
微軟 sql server
sqllite
名詞
DB 數據庫 - 文件夾
table 表 - 文件
data 一條數據-每一行數據
數據庫的分類
關係型數據庫 mysql oracle sqlserver sqllite
非關係型數據庫 redis mongodb memcache hbase
第三十六章
# 你啓動的mysql.exe是客戶端 S 你安裝的服務是server
# 在客戶端須要指定 要登陸的數據庫所在的ip 以及用戶名和密碼
# mysql -uroot -p123 -h192.168.12.45
# mysql> set password = password('123'); 設置密碼
# 須要注意要在sql的結尾輸入;表示整個sql語句的結束
# 若是忘記了能夠在換行以後補上。
# \c表示放棄當前行要執行的sql語句
# exit 表示退出客戶端
# 用戶
# create user '用戶名'@'容許的網段' identified by '密碼'
# grant usage on 數據庫.表 to 'eva'@'%';
# grant select on 數據庫.* to 'eva'@'%';
# grant update on *.* to 'eva'@'%';
# grant insert on *.* to 'eva'@'%';
# grant delete on *.* to 'eva'@'%';
# grant all on ftp.* to 'eva'@'%';
# show databases; 查看當前的全部庫
# create database ftp;
# mysql -ueva -h192.168.12.22 -p123
# mysql> select user();
基礎操做
# 你啓動的mysql.exe是客戶端 S 你安裝好的服務是server
# 在客戶端須要指定 要登陸的數據庫所在的ip 以及用戶名和密碼
# mysql -uroot -p123 -h192.168.12.45
# mysql> set password = password('123'); 設置密碼
# 須要注意要在sql的結尾輸入;表示整個sql語句的結束
# 若是忘記了能夠在換行以後補上。
# \c表示放棄當前行要執行的sql語句
# exit 表示退出客戶端
# 用戶
# create user '用戶名'@'容許的網段' identified by '密碼'
# grant usage on 數據庫.表 to 'eva'@'%';
# grant select on 數據庫.* to 'eva'@'%';
# grant update on *.* to 'eva'@'%';
# grant insert on *.* to 'eva'@'%';
# grant delete on *.* to 'eva'@'%';
# grant all on ftp.* to 'eva'@'%';
# show databases; 查看當前的全部庫
# create database ftp;
# mysql -ueva -h192.168.12.22 -p123
# mysql> select user();
建立表
# 數據類型
# 數字類型
# 整數 tinyint int
# 小數 float double
# 字符串
# 定長、節省時間、浪費空間 char(255)
# 變長、節省空間、浪費時間 varchar(65535)
# 時間類型
# now()函數表示當前時間
# datetime 年月日時分秒 0000-9999
# date 年月日
# time 時分秒
# year 年
# timestamp 年月日時分秒 1970-2038
# enum和set
# enum 單選
# set 多選
數值類型和字符串
# 整數
# create table t1(i1 tinyint,i2 int);
# 默認建立的全部數據都是有符號的
# create table t2(i1 tinyint unsigned,i2 int unsigned);
# unsigned表示無符號
# 小數
# create table t3(f1 float,f2 double)
# create table t4(f1 float(7,2))
# 字符串
# char(25)
# 'abc ' 浪費空間、節省時間
# varchar(25)
# '3abc' 節省空間、浪費時間
# create table t5(c1 char(5),c2 varchar(5));
時間類型和枚舉集合
# create table t6(dt datetime,d date,t time,y year,ts timestamp);
# insert into t6 values(now(),now(),now(),now(),now());
# insert into t6(dt) values('2018-8-8 8:8:8');
# insert into t6(dt) values(20180808080808);
# insert into t6(d) values(20180808);
# insert into t6(t) values('8:8:8');
# create table t7(dt datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,y year);
# create table t8(username char(12),gender enum('male','female'));
# create table t9(username char(12),hobby set('抽菸','喝酒','燙頭','洗腳'));
第三十七章
select
# select * from 表;
# 指定列查詢
# select emp_name,salary from employee;
# 在列中使用四則運算
# select emp_name,salary*12 from employee;
# 重命名
# select emp_name,salary*12 as annul_salary from employee;
# select emp_name,salary*12 annul_salary from employee;
# 去重
# select distinct post from employee;
# select distinct sex,post from employee;
# 函數 concat() 拼接
# select concat('姓名 :',emp_name),concat('年薪:',salary*12) from employee;
# select concat_ws('|','a','b','c')
# case when語句 == if條件判斷句
where語句 根據條件篩選行
# 比較運算 = > < >= <= !=/<>
# select * from employee where age>18;
# select * from employee where salary<10000;
# select * from employee where salary=20000;
# between a and b #[a,b]
# select * from employee where salary between 10000 and 20000;
# in
# select * from employee where salary in (17000,19000);
# like 模糊查詢
# _ 通配符 表示一個字符長度的任意內容
# select * from employee where emp_name like 'jin___'
# % 通配符 表示任意字符長度的任意內容
# select * from employee where emp_name like 'jin%'
# select * from employee where emp_name like '%g'
# select * from employee where emp_name like '%n%'
# regexp 正則匹配
# select * from employee where emp_name regexp '^jin'
邏輯運算
# and
# select * from employee where age>18 and post='teacher';
# or
# select * from employee where salary<10000 or salary>30000;
# not
# select * from employee where salary not in (10000,17000,18000);
關於null
# 查看崗位描述爲NULL的員工信息
# select * from employee where post_comment is null;
# 查看崗位描述不爲NULL的員工信息
# select * from employee where post_comment is not null;
5個聚合函數
# count
# max
# min
# avg
# sum
分組聚合 group by
# 查詢崗位名以及崗位包含的全部員工名字
# select post,group_concat(emp_name) from employee group by post;
# 查詢各部門年齡在20歲以上的人的平均薪資
# select post,avg(salary) from employee where age>20 group by post;
# select * from 表 where 條件 group by 分組
過濾 having (group by + 聚合函數)
# 查詢平均薪資大於1w的部門
# select avg(salary) from employee group by post having avg(salary) > 10000
# 1. 查詢各崗位內包含的員工個數小於2的崗位名、崗位內包含員工名字、個數
# select post,emp_name,count(id) from employee group by post having count(id)<2
# 2. 查詢各崗位平均薪資大於10000的崗位名、平均工資
# select post,avg(salary) from employee group by post having avg(salary) > 10000
# 3. 查詢各崗位平均薪資大於10000且小於20000的崗位名、平均工資
# select post,avg(salary) from employee group by post having avg(salary) between 10000 and 20000;
order by 排序
# 升序
# select * from employee order by salary;
# select * from employee order by salary asc;
# 降序
# select * from employee order by salary desc;
# select * from employee order by age,salary;
# select * from employee order by age,salary desc;
# select * from employee order by age desc,salary;
limit 取行
# select * from 表 order by 列 limit n; 取前n條
# select * from 表 order by 列 limit m,n; 從m+1開始,取n條
# select * from 表 order by 列 limit n offset m; 從m+1開始,取n條
順序:
select * from 表 where 條件 group by 分組 having 過濾 order by 排序 limit n;
第三十八章
pymysql模塊
import pymysql
# conn = pymysql.connect(host='localhost', user='root', password="123",
# database='day38')
# cur = conn.cursor(pymysql.cursors.DictCursor) # cur遊標 cur數據庫操做符
# 對數據的增刪改查
# ret = cur.execute('select * from books')
# ret 影響行數 在這裏表示查到7行數據
# for i in range(ret):
# row1 = cur.fetchone() # 每次取一條數據
# print(row1)
# row2 = cur.fetchmany(3) # 按照指定參數取n條
# print(row2)
# row3 = cur.fetchall() # 取全部,過於浪費內存
# print(row3)
# insert update delete conn.commit()
# cur = conn.cursor() # cur遊標 cur數據庫操做符
# cur.execute('insert into books values("學python從開始到放棄","alex","人民大學出版社",50,"2018-7-1")')
# conn.commit()
# cur = conn.cursor()
# sql = 'insert into books values(%s,%s,%s,%s,%s)'
# # 操做文件
# with open('file',encoding='utf-8') as f:
# for line in f:
# try:
# lst = line.strip().split('|')
# cur.execute(sql,lst)
# conn.commit()
# except:
# conn.rollback()
# cur.close()
# conn.close()
# sql注入
# 登錄註冊 + 數據庫
# 表 userinfo
# cur = conn.cursor()
# name = input('user:')
# passwd = input('password:')
# sql = "select * from userinfo where username = %s and password = %s;"
# print(sql)
# ret = cur.execute(sql,(name,passwd))
# if ret:
# print('登錄成功')
# else:
# print('登錄失敗')
# sql注入
# select * from userinfo where username = 'xxx' or 1=1 ; -- ' and password =
多表查詢
# 怎麼讓兩張表之間產生關係?
# 連表
# 內鏈接(全部不在條件匹配內的數據,都會被剔出連表)
# 方式一 :select * from employee,department where dep_id = department.id;
# 方式二 :select * from employee inner join department on dep_id = department.id;
# 外鏈接
# 左外鏈接 left join
# select * from employee left join department on dep_id = department.id;
# 右外鏈接 right join
# select * from employee right join department on dep_id = department.id;
# 全外鏈接 full join
# select * from employee left join department on dep_id = department.id
# union
# select * from employee right join department on dep_id = department.id
#示例1:之內鏈接的方式查詢employee和department表,而且employee表中的age字段值必須大於25,即找出年齡大於25歲的員工以及員工所在的部門
# select employee.name,department.name from employee inner join department on dep_id = department.id where age>25;
# select e.name ename,d.name dname from employee e inner join department d on dep_id = d.id where age>25;
# select e.name,d.name from employee e inner join department d on dep_id = d.id where age>25;
#示例2:之內鏈接的方式查詢employee和department表,而且以age字段的升序方式顯示。
# select * from employee inner join department on dep_id = department.id order by age;
# 子查詢
# 查詢平均年齡在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查詢employee表 找到技術部id對應的人名
# select * from employee where dep_id = 200;
# 結果
# select name from employee where dep_id = (select id from department where name = '技術');
# 查看不足1人的部門名(子查詢獲得的是有人的部門id)
# 先從employee中查有多少個部門有人
# select distinct dep_id from employee;
# 從department表中把不在上述部門中的那些項找出來
# select * from department where id not in (200,201,202,204);
# 結果
# select * from department where id not in (select distinct dep_id from employee);
# 查詢大於全部人平均年齡的員工名與年齡
# 全部人的平均年齡
# select avg(age) from employee; # 28
# 查大於上述平均年齡的人
# select name,age 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 * from employee where dep_id = 200 and age>18
# select * from employee where dep_id = 201 and age>43
# select * from employee where dep_id = 202 and age>28
# select * from employee where dep_id = 204 and age>18
# 結果
# select * from employee inner join (select dep_id,avg(age) as avg_age from employee group by dep_id) as t
# on employee.dep_id = t.dep_id;
#
# select * from employee inner join (select dep_id,avg(age) as avg_age from employee group by dep_id) as t
# on employee.dep_id = t.dep_id where age>avg_age;
第三十九章
存儲引擎
# show create table books;
# show engines;
# 什麼是存儲方式、存儲機制(存儲引擎)
# 表結構 存在一個文件中 : 硬盤上
# 表數據 存在另外一個文件中、內存中
# 索引(目錄) 爲了方便查找設計的一個機制 :
# 存儲引擎的種類
# innodb : 索引+數據 表結構 數據的持久化存儲
# 事務 :一致性 n條語句的執行狀態是一致的
# begin; # 開啓事務
# select id from innot where id =1 for update;
# update innot set id = 2 where id = 1;
# commit; # 提交事務 解鎖被鎖住的數據,讓他們可以被修改
# 行級鎖 :只對涉及到修改的行加鎖,利於併發的修改,可是對於一次性大量修改效率低下
# 表級鎖 :一次性加一把鎖就鎖住了整張表,不利於併發的修改,可是加鎖速度比行鎖的效率要高
# 外鍵約束 :被約束表中的數據不能隨意的修改/刪除 約束字段據要根據被約束表來使用數據
# myisam : 索引 數據 表結構 數據的持久化存儲
# 表級鎖
# memory : 表結構
# 數據斷電消失
# create table innot(id int) engine = innodb;
# create table myist(id int) engine = myisam;
# create table memot(id int) engine = memory;
約束
# not null 非空約束
# create table t1(id int not null,name char(12));
# 默認插入0,嚴格模式報錯
# create table t2(id int,name char(12) not null);
# 默認插入空字符串,嚴格模式報錯
# default 默認值 default
# create table t3(id int,name char(12),sex enum('male','female') default 'male');
# 非空約束 和 默認值
# create table t3(id int not null,name char(12) not null,sex enum('male','female') not null default 'male');
# unique惟一約束 (不能重複)
# create table t4(id int unique,name char(12));
# 聯合惟一約束
# create table t5(family char(12),name char(12),unique(family,name));
# create table t5(family char(12) not null,name char(12) not null,unique(family,name)); # 約束各自不能爲空 且聯合惟一
# 惟一+非空 id name
# create table t6(id int not null unique`11111111111111111111111, name char(12) not null unique);
# pri 是怎麼產生的? 第一個被設置了非空+惟一約束會被定義成主鍵 primary key
# 主鍵在整張表中只能有一個
# 主鍵(非空+惟一)
# create table t6(id int primary key, name char(12) not null unique);
# create table t5(family char(12) ,name char(12),primary key(family,name)); # 約束各自不能爲空 且聯合惟一 還佔用了整張表的主鍵
# 對某一列設置自增 auto_increment(自動增長,not null約束)
# create table t6(id int auto_increment, name char(12)); # 報錯
# create table t7(id int unique auto_increment, name char(12) primary key) ;
# create table t8(id int primary key auto_increment, name char(12)) ;
# create table t9(id int unique auto_increment, name char(12)) auto_increment=100000;
# delete from t7; 清空表數據但不能重置auto_increment
# truncate table t7; # 清空表而且重置auto_increment
# 全部的操做都沒法改變auto_increment的自動計數。可是咱們也沒有必要去改變它。
# 1.至少要看到自增的效果
# 2.至少寫3條數據 4,5,6
# 3.刪掉第5條,再看結果
# 4.再insert一條數據
# 5.刪掉第5條,再看結果
# 6.再insert一條數據
# 7.清空整張表
# 8.再insert一條數據,再看結果
# 修改auto_increment
# alter table 表名 auto_increment = n; 修改表的auto_increment
# alter table t7 auto_increment = 1000; 修改表的auto_increment
# 外鍵
# 沒有創建外鍵:
# create table stu(id int,name char(12),class_id int);
# create table class(cid int,cname char(12));
# insert into stu values (1,'日魔',1),(2,'炮手',1)
# insert into class values(1,'py27');
# insert into class values(2,'py28');
# select * from stu,class where class_id = cid;
# delete from stu where id = 1;
# delete from class where cid = 1;
# stu2 class2
# create table class2(cid int unique,cname char(12));
# create table stu2(id int,name char(12),class_id int,foreign key(class_id) references class2(cid));
# insert into class2 values(1,'py27');
# insert into stu2 values (1,'日魔',1),(2,'炮手',1)
# delete from class2 where cid = 1;
# insert into class2 values(2,'py28');
# update class2 set cid = 1 where cid = 2; 不能修改
# stu3 class3 級聯更新
# create table class3(cid int primary key,cname char(12));
# create table stu3(id int,name char(12),class_id int,foreign key(class_id) references class3(cid) on update cascade);
# insert into class3 values(1,'py27');
# insert into stu3 values (1,'日魔',1),(2,'炮手',1)
# update class3 set cid = 2; 修改了class3中的cid,stu3中相關的數據也會跟着變化,是on update cascade設置致使的
第四十章
表的修改
# create table
# drop table
# desc 表名;
# alter table
# alter table 表名 rename 表名;
# alter table 表名 charset 編碼;
# alter table 表名 auto_increment 自增的位置;
# alter table 表名 add 字段名 類型(長度) 約束;
# alter table 表名 drop 字段名;
# alter table 表名 change 字段名 新名字 類型(長度) 約束;
# alter table 表名 modify 字段名 新類型(新長度) 約束;
# name id age
# alter table 表名 change id id 類型(長度) 約束 first;
# alter table 表名 change id id 類型(長度) 約束 after age;
# alter table 表名 add 字段名 類型(長度) 約束 first;
# alter table 表名 add 字段名 類型(長度) 約束 after name;
表與表之間的關係
# 一對多 foreign key
# create table class(id int primary key,cname char(12));
# create table student(id int primary key,sname char(16),cid int,
# foreign key(cid) references class(id));
# 多對多
# create table class(id int primary key,cname char(12));
# create table teacher(id int primary key,tname char(12));
# create table teach_cls(id int,cid int,tid int,
# foreign key(cid) references class(id)),
# foreign key(tid) references teacher(id))
# );
# 一對一
# create table guest(id int primary key,name char(12));
# create table student(id int primary key,sname char(12),gid int unique,
# foreign key(gid) referances guest(id));
索引原理
# 磁盤預讀性原理
# 1個block塊 4096個字節/9ms
# 樹
# 樹 根節點 分支節點 葉子節點
# 平衡樹 balance tree - B樹
# 彙集索引/聚簇索引 : 葉子節點會存儲整行數據 —— innodb的主鍵
# 輔助索引/非彙集索引 :除了主鍵以外的普通索引都是輔助索引,一個索引沒辦法查到整行數據,須要回彙集索引再查一次(回表)
# b+樹 是爲了更好的處理範圍問題在b樹的基礎上有所優化
# mysql中innodb存儲引擎的全部的索引樹都是b+樹
索引優缺點:
優勢:加快查詢速度
缺點:下降寫的速度,佔用更多的磁盤空間
第四十一章
索引
# 索引 : index / unique / primary key
# 操做索引 :建立和刪除
# 建立 :create index 索引名 on 表名(字段名);
# create index ind_id on s1(id);
# create index ind_id2 on s1(id);
# 刪除 :drop index 索引名 on 表名;
# drop index ind_id2 on 表名;
# 正確的使用索引(******)
# 1.只有對建立了索引的列進行條件篩選的時候效率才能提升
# 2.索引對應的列作條件不能參與運算、不能使用函數
# 3.當某一列的區分度很是小(重複率高),不適合建立索引
# 4.當範圍做爲條件的時候,查詢結果的範圍越大越慢,越小越快
# 5.like關鍵字 : 若是使用%/_開頭都沒法命中索引
# 6.多個條件 : 若是隻有一部分建立了索引,條件用and相連,那麼能夠提升查詢效率
# 若是用or相連,不能提升查詢效率
# and
# select count(*) from s1 where id=1000000 and email = 'eva1000000@oldboy';
# or
# select count(*) from s1 where id=1000000 or email = 'eva1000000@oldboy';
# 7.聯合索引
# creat index ind_mix on s1(id,name,email);
# select count(*) from s1 where id=1000000 and email = 'eva1000000@oldboy'; 快
# select count(*) from s1 where id=1000000 or email = 'eva1000000@oldboy'; 慢 條件不能用or
# select count(*) from s1 where id=1000000; 快
# select count(*) from s1 where email = 'eva1000000@oldboy'; 慢 要服從最左前綴原則
# select count(*) from s1 where id>1000000 and email = 'eva1000000@oldboy'; 慢 從使用了範圍的條件開始以後的索引都失效
# 基礎概念(介紹)
# explain 執行計劃
# explain select count(*) from s1 where id=1000000 and email = 'eva1000000@oldboy';
# 覆蓋索引
# 在查詢的過程當中不須要回表 -- 覆蓋索引 using index
# explain select count(*) from s1 where id < 1000;
# 索引合併
# explain select count(*) from s1 where id=1000000 or email = 'eva1000000@oldboy';