1.數(shù)據(jù)完整性
在查詢的時候可以沒有外鍵約束棋恼,就算沒有外鍵約束也可以進行查詢崇棠,但是在添加诫惭,更新的時候必須要有乓梨。
保證用戶輸入的數(shù)據(jù)保存到數(shù)據(jù)庫當中是正確的(保存到數(shù)據(jù)庫當中的數(shù)據(jù)是正確的)护昧。具體做法是在建表的時候給約束衫仑,完整性可以分為一下三類
實體完整性
域完整性
引用完整性
(一)實體完整性
表當中的一行就代表一個實體砰逻,實體完整性的作用是約束每一行的數(shù)據(jù)不能重復,完整性約束主要可以分為一下三類
主鍵約束(primary key)
唯一約束(unique)
自動增長列(auto_increment)
1.主鍵約束
特點:每個表當中要有一個主鍵旋恼,并且數(shù)據(jù)唯一乘陪,不能為null
添加方式:
**********************建表的同時創(chuàng)建主鍵*****************
create table 表名(字段1 數(shù)據(jù)類型 primary key,字段2 數(shù)據(jù)類型.....字段n 數(shù)據(jù)類型);
create table 表名(字段1 數(shù)據(jù)類型,字段2 數(shù)據(jù)類型....primary key(要設置主鍵的字段));
create table 表名(字段1 數(shù)據(jù)類型,字段2 數(shù)據(jù)類型....primary key(主鍵1,主鍵2...));
*********************先建表统台,在創(chuàng)建主鍵********************************
1.建表
2.修改表,添加主鍵
alter table 表名 add constraint primary key (id);
create table person(
id bigint primary key,
name varchar(10)
);
**********************************************
create table person(
id bigint,
name varchar(10),
age int,
primary key (id)
);
******************************************************
-- 聯(lián)合主鍵啡邑,兩個主鍵合起來作為一個聯(lián)合主鍵贱勃,
-- 兩個主鍵都不能為null,不能有2個重復,可以有1個重復
create table student(
id bigint,
snum bigint,
sname varchar(10),
primary key(id,snum)
);
*********************************************
alter table students add constraint primary key(id);
2.唯一性約束
特點:指定列的數(shù)據(jù)不能重復,可以為null(可以有多個)
格式:
create table 表名(字段1 數(shù)據(jù)類型 unique,字段二 數(shù)據(jù)類型......);
注意主鍵約束可以有多個null
create table student(
id bigint primary key,
name varchar(50) unique,
age int
);
3.字段增長列
特點:指定列的數(shù)據(jù)自動增長贵扰,即使數(shù)據(jù)刪除了族展,還是村刪除的序號往下繼續(xù)增長。
格式:
create table 表名(字段1 數(shù)據(jù)類型 primary key auto_increment,字段2 數(shù)據(jù)類型....);
create table student(
id bigint primary key auto_increment,
name varchar(20) unique,
age int
);
(二)域完整性
使用:限制此單元格的數(shù)據(jù)正確拔鹰,不與此列的其他單元格進行比較仪缸,域代表當前當單元格。
域完整性約束主要分為一下三個方面:
數(shù)據(jù)類型:數(shù)值類型列肢,日期類型恰画,字符串類型
非空約束(not null)
默認值約束(default)
1.非空約束,默認值約束
create table 表名(字段1 數(shù)據(jù)類型 not null,字段2 數(shù)據(jù)類型....);
create table 表名(字段1 數(shù)據(jù)類型 default '男',字段2 數(shù)據(jù)類型....);
create table student(
id bigint primary key auto_increment,
name varchar(50) unique not null,
gender char(2) default '男'
);
(三)參照完整性
什么是參照完整性:是指表于表之間的一種對應關(guān)系,通常情況下可以通過設置2張表之間的主鍵瓷马,外鍵關(guān)系拴还,或者編寫2張表的觸發(fā)器來實現(xiàn),有對應參照完整性的2張表欧聘,對他們的數(shù)據(jù)進行插入刪除更新操作的時候片林,系統(tǒng)都會將被修改表格與另一張對應的表格進行對照,從而阻止一些不正確的數(shù)據(jù)的操作怀骤。
數(shù)據(jù)庫的主鍵和外鍵類型必須要一致
2個表必須要是Innodb類型
設置參照完整性后费封,外鍵當中的內(nèi)值,必須是主鍵當中的內(nèi)容
一個表設置當中的字段為主鍵蒋伦,設置主鍵的為主表
創(chuàng)建表時弓摘,設置外鍵,設置外鍵的為子表
create table stu(
id int primary key,
name varchar(50),
age int
);
-- 設置score當中的sid為外鍵痕届,和stu當中的主鍵id關(guān)聯(lián)
create table score(
sid int,
score int,
constraint sc_st_fk foreign key (sid) references stu(id)
);
***************如果表以及建好了韧献,可以使用SQL語句添加外鍵***********
alter table score add constraint foreign key (sid) references stu(id);
2.多表關(guān)系的創(chuàng)建
創(chuàng)建多對多關(guān)系的方法:創(chuàng)建一個中間關(guān)系表來實現(xiàn)
-- 多對多,要創(chuàng)建中間表
create table teacher(
tid int primary key ,
name varchar(50)
);
create table student(
sid int primary key,
name varchar(50)
);
-- 注意此處的字段名不能亂寫研叫,必須要是前兩個表的主鍵锤窑,不然是無用的
create table tea_stu_rel(
tid int,
sid int
);
-- 添加中間表與其他表的聯(lián)系(設置外鍵),中間表當中的字段都要設置外鍵.
alter table tea_stu_rel add constraint foreign key (tid) references teacher(tid);
alter table tea_stu_rel add constraint foreign key (sid) references student(sid);
總結(jié):中間表約束創(chuàng)建完成之后嚷炉,添加到中間表當中的數(shù)據(jù)全部是表一表二當中的數(shù)據(jù)渊啰,加入其他的數(shù)據(jù)會報錯。
3.外什么要拆分表渤昌?
為了避免大量冗余數(shù)據(jù)的出現(xiàn)
4.多表查詢
多表查詢大致分為以下四個方面:
合并結(jié)果集
連接查詢
子查詢
自連接
(一)合并結(jié)果集
-- 合并結(jié)果集
create table A(
name varchar(50),
score int
);
create table B(
name varchar(20),
score int
);
insert into A values('a',80),('b',90);
insert into B values('a',80),('c',90),('b',100),('d',120)
select * from A union select * from B;
select * from A union all select * from B;
******************************************************
注意:在合并結(jié)果集的時候虽抄,要求2張表的列和列數(shù)據(jù)類型一致走搁,不然不能合并
(二)連接查詢
*********************多表查詢會出現(xiàn)笛卡爾積結(jié)果集***********************
select * from student,teacher
笛卡爾積的記錄書:A記錄數(shù)*B記錄數(shù)
1.如何保證數(shù)據(jù)的正確性独柑,避免笛卡爾積結(jié)果集?
select * from stu,score where stu.id=score.sid;
***************************************************
在查詢時保持主鍵和外鍵的一致性
主表當中的數(shù)據(jù)參照子表當中的數(shù)據(jù)
原理:逐行判斷私植,相等的留下忌栅,不相等的全部要。
2.連接查詢分類
注意查詢的時候可以沒有主外鍵約束
連接查詢主要可以分為以下三類:
內(nèi)連接
外連接
自然連接
(一)內(nèi)連接
內(nèi)連接可以分為如下的三種:
等值連接
多表連接
非等值連接
1.等值連接
**********************內(nèi)連接*********************************
-- 注意查詢的時候雖然沒有主外鍵約束,但是我們在心里面應該明白有主外鍵約束
-- 99寫法
select * from stu st,score sc where st.id=sc.id;
select * from stu st inner join score sc on st.id=sc.id;
select * from stu st join score sc on st.id=sc.id;
*******************************************************
select * from stu st join score sc on st.id=sc.id where score>80;
2.多表連接
表如下:
-- 查詢處學生的姓名,分數(shù)索绪,科目湖员,在此處是三表查詢
select st.name,sc.score ,cs.name from stu st,score sc ,course cs
where st.id=sc.id and sc.sid=cs.cid;
*******************************************************************
select st.name,cs.name,sc.score from stu st
inner join score sc on st.id=sc.id
inner join course cs on sc.sid=cs.cid;
總結(jié):在進行多表查詢的時候,具體的做法是一步一步瑞驱,兩表進行查詢娘摔。
3.非等值連接
非等值查詢:即查詢后面的條件不是等值的
-- 查詢所有員工的姓名,工資,所在部門名稱以及該工資的等級
select emp.ename,emp.salary ,dept.dname ,salgrade.grade from
emp,dept ,salgrade
where emp.deptno=dept.deptno
and emp.salary>=salgrade.lowSalary
and emp.salary<=salgrade.higghSalary;
***************************************************
select e.ename,e.salary,d.dname,s.grade from emp e
inner join dept d on e.deptno=d.deptno
inner join salgrade s on e.salary between s.lowSalary and s.higghsalary;
(二)外連接
外連接可以分為:
左外連接(左連接)
右外連接(右連接)
1.左連接
將2表滿足條件的數(shù)據(jù)查詢出來唤反,如果左邊表右不同的數(shù)據(jù)凳寺,被左邊表當中的數(shù)據(jù)查詢出來
select * from stu st left outer join score sc on st.id=sc.id;
2.右鏈接
select * from stu st right outer join score sc on st.id=sc.id;
(三)自然連接
-- 不加where條件的時候,求出的結(jié)果是笛卡爾積的結(jié)果
select * from stu,score;
select * from stu ,score where stu.id=score.id;
select * from stu inner join score on stu.id=score.id;
-- 自然連接,當有相同列名及數(shù)據(jù)類型的時候彤侍,會按照主外鍵查
-- 如果沒有對應的肠缨,會進行笛卡爾積查詢
select * from stu natural join score;
總結(jié):
4.子查詢
什么是子查詢:一個select語句當中包含另一個select語句,或者多個select語句盏阶。
子查詢出現(xiàn)的位置:
where后:把select查詢出來的結(jié)果當成另一個select的條件值晒奕。
from后:把查詢出來的結(jié)果當成一個新表。
(一)where后
查詢出和項羽同部門的員工名稱
-- 查詢與項羽同一部門的員工
-- 先查詢項羽所在的部門名斟,再查詢同部門人員
select emp.deptno from emp where emp.ename='項羽' ;
select ename ,empno from emp
where deptno=(select emp.deptno from emp where emp.ename='項羽');
(二)from后
查詢30號部門里面所有員工的薪資
-- 查詢30號部門所有薪資大于2000的員工
-- 先查詢30號部門的員工的工資脑慧,再查詢大于2000的
select ename,salary from emp where deptno=30;
select es.ename ,es.salary from (select ename,salary from emp where deptno=30) es
where es.salary>2000;
(三)練習
-- 查詢薪資高于程咬金的員工
第一步查詢出程咬金的薪水,第二部查詢出薪水大于他的員工
select e.salary from emp e where e.ename='程咬金';
select * from emp
where emp.salary>(select e.salary from emp e where e.ename='程咬金');
*****************************************************************
-- 查詢工資高于30號部門所有人的員工信息
-- 第一步查詢出30號部門的最高工資砰盐,第二部查處大于最高工資的所有人信息
select max(salary) from emp where deptno=30;
select * from emp
where emp.salary>(select max(salary) from emp where deptno=30);
******************************************************************************
-- 查詢工作和工資都與妲己完全相同的員工的信息
-- 第一步查詢妲己的工作和工資漾橙,第二部查詢相同的員工
select salary,job from emp where ename='妲己';
select * from emp
where job=(select job from emp where ename='妲己')
and salary=(select salary from emp where ename='妲己');
select * from emp
where (salary,job) in (select salary,job from emp where ename='妲己');
-- 利用99查詢查詢出共同的數(shù)據(jù)(salary,job相同)
select * from emp,(select salary,job from emp where ename='妲己') sj
where emp.salary=sj.salary
and emp.job=sj.job;
******************************************************************************
-- 查詢有2個以上直接下屬的員工信息
-- 對上級字段mgr進行統(tǒng)計楞卡,有2個相同說明霜运,該編號所對應的人有2個直接下級
select mgr,group_concat(mgr),count(mgr) from emp group by mgr having count(mgr)>2;
select * from emp
where empno in (select mgr from emp group by mgr having count(mgr)>2);
*************************************************************************
-- 查詢編號為7788的員工的名稱,員工工資蒋腮,部門名稱淘捡,部門地址
select e.ename,e.salary ,d.dname ,d.local from emp e ,dept d
where e.deptno=d.deptno
and e.empno=7788;
***********************切記不可寫成以下的形式*****************************
select e.ename,e.salary ,d.dname ,d.local from emp e ,dept d
where e.empno=7788;
總結(jié):這是錯誤的,因為在進行多表查詢的時候池摧,沒有寫連接字段焦除,肯定是錯誤的。
5.自連接
自己連接自己作彤,起別名
-- 求7902的員工編號膘魄,姓名,經(jīng)理編號竭讳,經(jīng)理姓名
select mgr from emp where empno=7369;
select ename from emp where empno=(select mgr from emp where empno=7369);
select e1.ename,e1.empno,e2.mgr,e2.ename from emp e1,emp e2
where e1.empno=e2.mgr
and e1.empno=7902;