數(shù)據(jù)庫(SQL)

數(shù)據(jù)庫 - 實(shí)現(xiàn)數(shù)據(jù)持久化以及數(shù)據(jù)管理

  • 持久化 將數(shù)據(jù)保存到(在掉電情況下)能夠長久保存數(shù)據(jù)的存儲(chǔ)介質(zhì)中

數(shù)據(jù)庫的分類

關(guān)系型數(shù)據(jù)庫(SQL) 、非關(guān)系型數(shù)據(jù)庫(NoSQL)

關(guān)系型數(shù)據(jù)庫概述

  • 關(guān)系型數(shù)據(jù)庫發(fā)展史: 網(wǎng)狀數(shù)據(jù)庫、層次數(shù)據(jù)庫、關(guān)系數(shù)據(jù)庫

1970年,IBM的研究員E.F.Codd在Communication of the ACM上發(fā)表了名為A Relational Model of Data for Large Shared Data Banks的論文,提出了關(guān)系模型的概念,奠定了關(guān)系模型的理論基礎(chǔ)。后來Codd又陸續(xù)發(fā)表多篇文章,論述了范式理論和衡量關(guān)系系統(tǒng)的12條標(biāo)準(zhǔn),用數(shù)學(xué)理論奠定了關(guān)系數(shù)據(jù)庫的基礎(chǔ)。

  • 理論基礎(chǔ):關(guān)系代數(shù)和集合論

  • 關(guān)系型數(shù)據(jù)庫產(chǎn)品:

    • Oracle (甲骨文公司) 目前世界上使用最為廣泛的數(shù)據(jù)庫管理系統(tǒng),作為一個(gè)通用的數(shù)據(jù)庫系統(tǒng),它具有完整的數(shù)據(jù)管理功能;作為一個(gè)關(guān)系數(shù)據(jù)庫,它是一個(gè)完備關(guān)系的產(chǎn)品;作為分布式數(shù)據(jù)庫,它實(shí)現(xiàn)了分布式處理的功能。在Oracle最新的12c版本中,還引入了多承租方架構(gòu),使用該架構(gòu)可輕松部署和管理數(shù)據(jù)庫云。
    • DB2 (IBM) 主要運(yùn)行于Unix(包括IBM自家的AIX)、Linux、以及Windows服務(wù)器版等系統(tǒng)的關(guān)系數(shù)據(jù)庫產(chǎn)品。DB2歷史悠久且被認(rèn)為是最早使用SQL的數(shù)據(jù)庫產(chǎn)品,它擁有較為強(qiáng)大的商業(yè)智能功能。
    • SQLServer (Microsoft)最初適用于中小企業(yè)的數(shù)據(jù)管理,但是近年來它的應(yīng)用范圍有所擴(kuò)展,部分大企業(yè)甚至是跨國公司也開始基于它來構(gòu)建自己的數(shù)據(jù)管理系統(tǒng)。
    • MySQL MySQL是開放源代碼的,任何人都可以在GPL(General Public License)的許可下下載并根據(jù)個(gè)性化的需要對其進(jìn)行修改。MySQL因?yàn)槠渌俣取⒖煽啃院瓦m應(yīng)性而備受關(guān)注。
    • Sybase
    • PostgreSQL 在BSD許可證下發(fā)行的開發(fā)源代碼的關(guān)系數(shù)據(jù)庫產(chǎn)品。
  • 具體表象:用二維表來保存數(shù)據(jù)

    • 行(記錄)
    • 列(字段)
    • 主鍵列:能夠唯一標(biāo)識(shí)一條記錄的列,例如:學(xué)生學(xué)號(hào)
  • 編程語言:SQL - 結(jié)構(gòu)化查詢語言

    • DDL 數(shù)據(jù)定義語言 create / drop / alter
    • DML 數(shù)據(jù)操作語言 insert / delete / update / select
    • DCL 數(shù)據(jù)控制語言 grant / revoke

ER圖(實(shí)體關(guān)系圖/概念模型圖)

矩形框:實(shí)體

橢圓框:實(shí)體的屬性

菱形框:實(shí)體之間的關(guān)系

關(guān)系的重?cái)?shù):一對一/一對多/多對多

畫圖工具:PowerDesigner

linux環(huán)境下啟動(dòng)Mariadb

啟動(dòng)和查看程序進(jìn)程
啟動(dòng) ——> 查看是否有進(jìn)程(4個(gè)方法)
方法4. systemctl status mariadb
image.png
  1. 查看數(shù)據(jù)庫版本
image.png

連接navicat可視化界面

image.png
  • ==第一步==:連接
    image.png
密碼是:該用戶登錄的密碼
點(diǎn)擊連接測試 ——> 成功后點(diǎn)擊連接
  • ==第二步==:授予root所有權(quán)限
    image.png

SQL結(jié)構(gòu)化查詢語言(Mysql)

注意:

  • 給數(shù)據(jù)庫和表命名時(shí)盡量使用小寫;
  • 作為篩選條件的字符串是否區(qū)分大小,看校對規(guī)則(collate utf8_general_ci ci——> case insensitive)
  • 數(shù)據(jù)庫中的對象通常會(huì)用前綴加以區(qū)分
數(shù)據(jù)庫增刪以及表格增刪改
-- 如果存在名為school的數(shù)據(jù)庫就刪除它
drop database if exists school;

-- 創(chuàng)建名為school的數(shù)據(jù)庫并設(shè)置默認(rèn)的字符集和排序方式
create database school default charset utf8 collate utf8_bin_ci;

-- 切換到school數(shù)據(jù)庫上下文環(huán)境
use school;

-- 創(chuàng)建學(xué)院表
create table tb_college
(
collid int not null auto_increment comment '編號(hào)',
collname varchar(50) not null comment '名稱',
collmaster varchar(20) not null comment '院長',
collweb varchar(511) default '' comment '網(wǎng)站',
primary key (collid)
);

-- 創(chuàng)建學(xué)生表
create table tb_student
(
stuid int not null comment '學(xué)號(hào)',
stuname varchar(20) not null comment '姓名',
stusex bit default 1 comment '性別',
stubirth date not null comment '出生日期',
stuaddr varchar(255) default '' comment '籍貫',
collid int not null comment '所屬學(xué)院',
primary key (stuid),
foreign key (collid) references tb_college (collid)
);

-- alter table tb_student add constraint fk_student_collid foreign key (collid) references tb_college (collid);

-- 創(chuàng)建教師表
create table tb_teacher
(
teaid int not null comment '工號(hào)',
teaname varchar(20) not null comment '姓名',
teatitle varchar(10) default '助教' comment '職稱',
collid int not null comment '所屬學(xué)院',
primary key (teaid),
foreign key (collid) references tb_college (collid)
);

-- 創(chuàng)建課程表
create table tb_course
(
couid int not null comment '編號(hào)',
couname varchar(50) not null comment '名稱',
coucredit int not null comment '學(xué)分',
teaid int not null comment '授課老師',
primary key (couid),
foreign key (teaid) references tb_teacher (teaid)
);

-- 創(chuàng)建選課記錄表
create table tb_score
(
scid int auto_increment comment '選課記錄編號(hào)',
stuid int not null comment '選課學(xué)生',
couid int not null comment '所選課程',
scdate datetime comment '選課時(shí)間日期',
scmark decimal(4,1) comment '考試成績',
primary key (scid),
foreign key (stuid) references tb_student (stuid),
foreign key (couid) references tb_course (couid)
);

-- 添加唯一性約束(一個(gè)學(xué)生選某個(gè)課程只能選一次)
alter table tb_score add constraint uni_score_stuid_couid unique (stuid, couid);

-- 插入學(xué)院數(shù)據(jù)
insert into tb_college (collname, collmaster, collweb) values 
('計(jì)算機(jī)學(xué)院', '左冷禪', 'http://www.abc.com'),
('外國語學(xué)院', '岳不群', 'http://www.xyz.com'),
('經(jīng)濟(jì)管理學(xué)院', '風(fēng)清揚(yáng)', 'http://www.foo.com');

-- 插入學(xué)生數(shù)據(jù)
insert into tb_student (stuid, stuname, stusex, stubirth, stuaddr, collid) values
(1001, '楊逍', 1, '1990-3-4', '四川成都', 1),
(1002, '任我行', 1, '1992-2-2', '湖南長沙', 1),
(1033, '王語嫣', 0, '1989-12-3', '四川成都', 1),
(1572, '岳不群', 1, '1993-7-19', '陜西咸陽', 1),
(1378, '紀(jì)嫣然', 0, '1995-8-12', '四川綿陽', 1),
(1954, '林平之', 1, '1994-9-20', '福建莆田', 1),
(2035, '東方不敗', 1, '1988-6-30', null, 2),
(3011, '林震南', 1, '1985-12-12', '福建莆田', 3),
(3755, '項(xiàng)少龍', 1, '1993-1-25', null, 3),
(3923, '楊不悔', 0, '1985-4-17', '四川成都', 3);

-- 插入老師數(shù)據(jù)
insert into tb_teacher (teaid, teaname, teatitle, collid) values 
(1122, '張三豐', '教授', 1),
(1133, '宋遠(yuǎn)橋', '副教授', 1),
(1144, '楊逍', '副教授', 1),
(2255, '范遙', '副教授', 2),
(3366, '韋一笑', '講師', 3);

-- 插入課程數(shù)據(jù)
insert into tb_course (couid, couname, coucredit, teaid) values 
(1111, 'Python程序設(shè)計(jì)', 3, 1122),
(2222, 'Web前端開發(fā)', 2, 1122),
(3333, '操作系統(tǒng)', 4, 1122),
(4444, '計(jì)算機(jī)網(wǎng)絡(luò)', 2, 1133),
(5555, '編譯原理', 4, 1144),
(6666, '算法和數(shù)據(jù)結(jié)構(gòu)', 3, 1144),
(7777, '經(jīng)貿(mào)法語', 3, 2255),
(8888, '成本會(huì)計(jì)', 2, 3366),
(9999, '審計(jì)學(xué)', 3, 3366);

-- 插入選課數(shù)據(jù)
insert into tb_score (stuid, couid, scdate, scmark) values 
(1001, 1111, '2017-09-01', 95),
(1001, 2222, '2017-09-01', 87.5),
(1001, 3333, '2017-09-01', 100),
(1001, 4444, '2018-09-03', null),
(1001, 6666, '2017-09-02', 100),
(1002, 1111, '2017-09-03', 65),
(1002, 5555, '2017-09-01', 42),
(1033, 1111, '2017-09-03', 92.5),
(1033, 4444, '2017-09-01', 78),
(1033, 5555, '2017-09-01', 82.5),
(1572, 1111, '2017-09-02', 78),
(1378, 1111, '2017-09-05', 82),
(1378, 7777, '2017-09-02', 65.5),
(2035, 7777, '2018-09-03', 88),
(2035, 9999, curdate(), null),
(3755, 1111, date(now()), null),
(3755, 8888, date(now()), null),
(3755, 9999, '2017-09-01', 92);

-- 添加主鍵約束(如果創(chuàng)建表時(shí)沒有添加)
alter table tb_teacher add constraint pk_teacher_teaid primary key(tea_id);

-- 添加外鍵約束(如果創(chuàng)建表時(shí)沒有添加)
alter table tb_teacher add constraint fk_teacher_deptid foreign key(dept_id) references tb_department(dept_id);
如果外鍵編號(hào)不存在,會(huì)報(bào)錯(cuò)
image.png
表格查詢語句
  • 查詢所有學(xué)生信息
select * from tb_student;
  • 查詢所有課程名稱及學(xué)分(投影和別名)
select couname as 課程名稱, coucredit as 學(xué)分 from tb_course;

select stuname as 姓名, case stusex when 1 then '男' else '女' end as '性別'
from tb_student;

select stuname as 姓名, if(stusex, '男', '女') as 性別
from tb_student;                                       -- 僅適用于mysql
  • 查詢所有女學(xué)生的姓名和出生日期(篩選)
select stuname as 學(xué)生姓名 , stubirth as 出生日期 from tb_student
where stusex = 0;
  • 查詢所有80后學(xué)生的姓名、性別和出生日期(篩選)
select stuname, stusex, stubirth from tb_student
where stubirth between '1980-1-1' and '1989-12-31';

select stuname, stusex, stubirth from tb_student
where stubirth>'1980-1-1' and stubirth<'1989-12-31';
  • 查詢姓”楊“的學(xué)生姓名和性別(模糊)
select stuname, stusex from tb_student
where stuname like '林%'
  • 查詢姓”楊“名字兩個(gè)字的學(xué)生姓名和性別(模糊)
select stuname, stusex from tb_student
where stuname like '楊_'
  • 查詢姓”楊“名字三個(gè)字的學(xué)生姓名和性別(模糊)
select stuname,stusex from tb_student
where stuname like '楊__'
  • 查詢名字中有”不“字或“嫣”字的學(xué)生的姓名(模糊)
select stuname from tb_student
where stuname like '%不%' or '%嫣%';
  • 查詢沒有錄入家庭住址的學(xué)生姓名(空值)
select stuname from tb_student where stuaddr is null;
  • 查詢錄入了家庭住址的學(xué)生姓名(空值)
select stuname from tb_student where stuaddr is not null;
  • 查詢學(xué)生選課的所有日期(去重)
select distinct scdate from tb_score;
  • 查詢學(xué)生的家庭住址(去重)
select distinct stuaddr from tb_student;
  • 查詢男學(xué)生的姓名和生日按年齡從大到小排列(排序)
select stuname, stubirth from tb_student
where stusex = 1
order by stubirth asc;


select stuname, stubirth from tb_student
where stusex = 1
order by stubirth desc;

select stuname, year(now())-year(stubirth) as 年齡 from tb_student
where stusex = 1
order by 年齡 desc, stuid;
  • 查詢年齡最大的學(xué)生的出生日期(聚合函數(shù))
select min(stubirth) from tb_student;
  • 查詢年齡最小的學(xué)生的出生日期(聚合函數(shù))
select max(stubirth) from tb_student;
  • 查詢男女學(xué)生的人數(shù)(分組和聚合函數(shù))
select stusex,count(*) from tb_student
group by stusex;

select stusex, min(stubirth) from tb_student
group by stusex;
  • 查詢課程編號(hào)為1111的課程的平均成績(篩選和聚合函數(shù))
select avg(scmark) from tb_score
where couid = 1111;
  • 查詢學(xué)號(hào)為1001的學(xué)生所有課程的平均分(篩選和聚合函數(shù))
select avg(scmark) from tb_score
where stuid = 1001;
  • 查詢每個(gè)學(xué)生的學(xué)號(hào)和平均成績(分組和聚合函數(shù))
select stuid, avg(scmark) from tb_score
group by stuid;
  • 查詢平均成績大于等于90分的學(xué)生的學(xué)號(hào)和平均成績
select stuid, avg(scmark) as 平均分 from tb_score
group by stuid
having 平均分>90;
  • 查詢年齡最大的學(xué)生的姓名(子查詢)
select stuname, stubirth from tb_student;
select stuname, min(stubirth) from tb_student;


select stuname from tb_student
where stubirth = (select min(stubirth) from tb_student);
  • 查詢年齡最大的學(xué)生姓名和年齡(子查詢+運(yùn)算)
select stuname, year(now()) - year(stubirth) as 年齡 from tb_student
where stubirth = (select min(stubirth) from tb_student);
  • 查詢選了兩門以上的課程的學(xué)生姓名(子查詢/分組條件/集合運(yùn)算)
select stuname from tb_student
where stuid in (
    select stuid from tb_score
    group by stuid
    having count(stuid)>2 
);
  • 查詢學(xué)生姓名、課程名稱以及成績(連接查詢)
select stuname, couname, scmark 
from tb_student t1, tb_course t2, tb_score t3
where t1.stuid=t3.stuid and t2.couid=t3.couid;

select stuname, couname, scmark 
from tb_student t1 inner join tb_course t2 inner join tb_score t3
on t1.stuid=t3.stuid and t2.couid=t3.couid;
  • 查詢選課學(xué)生的姓名和平均成績(子查詢和連接查詢)
select stuname, 平均成績 from tb_student t1,(select stuid,avg(scmark) as 平均成績 from tb_score
group by stuid) t2
where t1.stuid = t2.stuid;

select stuname, 平均成績 from tb_student t1 inner join (select stuid,avg(scmark) as 平均成績 from tb_score
group by stuid) t2
on t1.stuid = t2.stuid;
  • 查詢每個(gè)學(xué)生的姓名和選課數(shù)量(左外連接和子查詢)
select stuname, 選課數(shù)量 
from tb_student t1 inner join (select stuid,count(couid) as 選課數(shù)量 from tb_score
group by stuid) t2
on t1.stuid=t2.stuid
order by 選課數(shù)量 desc
limit 5 offset 2;  -- 跳過2條查5條

select stuname, ifnull(選課數(shù)量,0) 
from tb_student t1 left outer join (select stuid,count(couid) as 選課數(shù)量 from tb_score
group by stuid) t2
on t1.stuid=t2.stuid
order by 選課數(shù)量 desc
limit 1,1;    -- 跳過第一查第二條
DCL 授予權(quán)限(grant to)和召回權(quán)限(revoke from)
create user 'hellokitty'@'%' identified by '123123'; -- '用戶名'@'IP地址'

grant all privileges on hrs.* to 'hellokitty'@'%'; -- 把hrs數(shù)庫的所有權(quán)限給新建的用戶

-- 召回新用戶的添加、刪除、更新的權(quán)限
revoke insert, delete, update on hrs.* from 'hellokitty'@'%';

drop user 'hellokitty'@'%'; -- 刪掉新用戶

視圖
  • 查詢的快照(簡化查詢操作)
  • 通過視圖可以將用戶的訪問權(quán)限限制到某些指定的列上
-- 創(chuàng)建視圖
create view vw_emp_dept as 
select eno, ename, dname from tb_emp t1 inner join tb_dept t2 on t1.dno=t2.dno;
-- 使用視圖
select ename, dname from vw_emp_dept;
-- 刪除視圖
drop view vw_emp_dept;

索引(index)
  • 索引可以加速查詢所以應(yīng)該在經(jīng)常用于查詢篩選條件的列上建立索引
  • 索引會(huì)使用額外的存儲(chǔ)空間而且會(huì)讓增刪改變得更慢(因?yàn)橐滤饕?/li>
  • 所以不能夠?yàn)E用索引
-- 創(chuàng)建索引
create index idx_emp_ename on tb_emp (ename);
-- 刪除索引
drop index idx_emp_ename on tb_emp;

  • explain生成執(zhí)行計(jì)劃
explain select eno, ename from tb_emp where eno=7800;
explain select eno, ename from tb_emp where eno<>7900;
explain select eno, ename from tb_emp where ename='張三豐';
explain select eno, ename from tb_emp where ename like '張%';
explain select eno, ename from tb_emp where ename like '%張';
explain select eno, ename from tb_emp where ename<>'張三豐';
如果在執(zhí)行計(jì)劃中,type類型是all 表示查詢語句效率最差,range 次之,const 最好
image.png
觸發(fā)器(trigger)
  • 為什么不用觸發(fā)器:

在執(zhí)行增刪改操作時(shí)可以觸發(fā)其他的級(jí)聯(lián)操作,在數(shù)據(jù)量很大的情況下,會(huì)導(dǎo)致“鎖表”現(xiàn)象,但是有可能導(dǎo)致“鎖表”現(xiàn)象,實(shí)際開發(fā)中應(yīng)該盡量避免使用觸發(fā)器

-- update tb_dept set dno=11 where dno=10;
-- delete from tb_dept where dno=11;

delimiter $$

create trigger tr_dept_update 
after update on tb_dept for each row
begin
    update tb_emp set dno=new.dno where dno=old.dno;
end$$

delimiter ;

drop trigger tr_dept_update;

  • 替代方案:

在添加外鍵時(shí)設(shè)置級(jí)聯(lián)操作cascade
(cascade 表示級(jí)聯(lián)操作,就是說,如果主鍵表中被參考字段更新,外鍵表中也更新,主鍵表中的記錄被刪除,外鍵表中改行也相應(yīng)刪除)
默認(rèn)是 on delete restrict 即不能級(jí)聯(lián)操作

image.png
事務(wù)(transaction)

把多個(gè)增刪改的操作做成不可分割的原子性操作,要么全部都做,要么全都不做

begin; -- 開啟事務(wù)
delete from tb_emp;
commit; -- 提交(事務(wù)中的所有操作全都生效)
rollback; -- 回滾(事務(wù)中的所有操作全部撤銷)
(存儲(chǔ))過程/函數(shù)

把一系列的SQL可以封裝到一個(gè)過程中,而且可以加上分支和循環(huán),將來通過過程的名字直接調(diào)用過程即可,因?yàn)閯?chuàng)建過程時(shí)已經(jīng)提前編譯了SQL語句,所以比直接執(zhí)行SQL語句性能更好

-- 創(chuàng)建存儲(chǔ)過程
delimiter $$

create procedure sp_dept_avg_sal(deptno int, out avgsal float)
begin
    select avg(sal) into avgsal from tb_emp where dno=deptno;
end$$

delimiter ;

-- 調(diào)用存儲(chǔ)過程
call sp_dept_avg_sal(20, @a);

-- 查找存儲(chǔ)在@a變量里的數(shù)據(jù)
select @a; 
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。