數據庫

第三十五章

數據庫初識

數據庫管理系統-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';
相關文章
相關標籤/搜索