Rumah >pangkalan data >tutorial mysql >MySQL中的约束与多表查询以及子查询的实例详解
一、约束之主键约束
约束:约束是添加在列上的,用来约束列的。
1、主键约束(唯一标识):非空、唯一、被引用
当表的某一列被指定为主键后,该类就不能为空,不能有重复值出现
创建表时指定主键的两种方式:
CREATE TABLE stu( sid CHAR(6) PRIMARY KEY, sname VARCHAR(20), age INT, sex VARCHEAR(10) ); CREATE TABLE stu( sid CHAR(6) , sname VARCHAR(20), age INT, sex VARCHEAR(10), PRIMARY KEY(sid) );
指定sid列为主键列,即为sid列添加主键约束
修改表时指定主键:
ALTER TABLE stu ADD PRIMARY KEY(sid);
删除主键:
ALTER TABLE stu DROP PRIMARY KEY;
2、主键自增长
因为主键列的特性是:必须唯一,不能为空,所以我们通常会指定主键为整型,然后设置其自动增长,这样可以保证在插入数据时主键列的唯一和非空特性。
创建表时指定主键自增长
CREATE TABLE stu( sid INT PRIMARY KEY AUTO_INCREMENT, sname VARCHAR(20), age INT, sex VARCHEAR(10) );
修改表时设置主键自增长:
ALTER TABLE stu CHANGE sid sid INT AUTO_INCREMENT;
修改表时删除主键自增长:
ALTER TABLE stu CHANGE sid sid INT ;
测试主键自增长:
INSERT INTO stu VALUES(NULL,'zhangsan',23,'man'); INSERT INTO stu(sname,age,sex) VALUES(NULL,'zhangsan',23,'man');
3、非空约束
因为某些列不能设置为null值,所以可以对添加非空约束。
例如:
CREATE TABLE stu ( sid INT PRIMARY KEY AUTO_INCREMENT, sname VARCHAR(20) NOT NULL, age INT, sex VARCHAR(10) );
对sname列设置了非空约束。
4、唯一约束
车库某些列不能设置重复的值,所以可以对列添加唯一约束。
例如:
CREATE TABLE stu ( sid INT PRIMARY KEY AUTO_INCREMENT, sname VARCHAR(20) NOT NULL UNIQUE, age INT, sex VARCHAR(10) );
二、概念模型
1、对象模型:在Java中是domain ,例如:User、Student .
2、关系模型:在数据库中表,1对多,1对1,多对多。
三、外键约束
外键必须是另一表的主键的值(外键要引用主键。)
外键可以重复
外键可以为空
1、创建时添加外键约束
CREATE TABLE dept ( deptno INT PRIMARY KEY AUTO_INCREMENT, dname VARCHAR(50) ); insert into dept values(10,'研发部'); insert into dept values(20,'人力部'); insert into dept values(30,'财务部'); CREATE TABLE emp ( empno INT PRIMARY KEY AUTO_INCREMENT, ename VARCHAR(50), deptno INT, CONSTRAINT fk_emp_dept FOREIGN KEY(dno) REFERENCES dept(deptno) ); CREATE TABLE dept ( deptno INT PRIMARY KEY AUTO_INCREMENT, dname VARCHAR(50) ); INSERT INTO dept VALUES(10,'研发部'); INSERT INTO dept VALUES(20,'人力部'); INSERT INTO dept VALUES(30,'财务部'); INSERT INTO emp(empno,ename) VALUES(null,'zhangsan'); INSERT INTO emp(empno,ename,deptno) VALUES(null,'lisi',10); INSERT INTO emp(empno,ename,deptno) VALUES(null,'zhangsan',80); /* Error Code: 1452. Cannot add or update a child row: a foreign key constraint fails (`mydb2`.`emp`, CONSTRAINT `fk_emp_dept` FOREIGN KEY (`deptno`) REFERENCES `dept` (`deptno`)) */
2、修改表时添加外键约束:
ALTER TABLE emp ADD CONSTRAINT fk_emp_dept FOREIGN KEY(dno) REFERNCES dept(deptno);
四、数据库关系模型
1、一对一关系
在表中建立一对一关系比较特殊,需要让其中一张表的主键,即是主键又是外键。
CREATE TABLE hasband ( hid INT PRIMARY KEY AUTO_INCREMENT, hname VARCHAR(50) ); CREATE TABLE wife ( wid INT PRIMARY KEY AUTO_INCREMENT, wname VARCHAR(50), CONSTRAINT fk_wife_hasband FOREIGN KEY (wid) REFERENCES hasband(hid) );
2、多对多关系
在表中建立多对多关系需要使用中间表,即需要三张表,在中间表中使用两个外键,分别引用其他两张表的主键。
CREATE TABLE student ( sid INT PRIMARY KEY , ...... ); CREATE TABLE teacher( tid INT PRIMARY KEY , ...... ); CREATE TABLE stu_tea ( sid INT, tid INT, ADD CONSTRAINT fk_stu_tea_sid FOREIGN KEY (sid) REFERENCES student(sid) , ADD CONSTRAINT fk_stu_tea_tid FOREIGN KEY (tid) REFERENCES teacher(tid) );
在中间表中建立关系,如:
INSERT INTO stu_tea VALUES(5,1); INSERT INTO stu_tea VALUES(2,2); INSERT INTO stu_tea VALUES(3,2);
五、多表查询
1、分类
合并结果集
连接查询
子查询
2、合并结果查询
要求被合并表中,结果集列的类型和列数相同
UNION,去除重复行
UNION ALL,不去除重复行
SELECT * FROM 表1名 UNION ALL SELECT * FROM 表2名;
3、连接查询
①分类
内连接
外连接
左外连接
右外连接
全外连接(mysql不支持)
自然连接(属于一种简化方式)
②内连接
方言:SELECT * FROM 表1 别名1,表2 别名2 WHERE 别名1.xx=别名2.xx;
SELECT * FROM emp,dept WHERE emp.deptno=dept.deptno; SELECT e.ename, e.sal, d.dname FROM emp e, dept d WHERE e.deptno=d.deptno;
以条件筛选去除笛卡尔积中无用的信息。
标准:SELECT * FROM 表1 别名1 INNER JOIN 表2 别名2 ON 别名1.xx=别名2.xx;
SELECT e.ename, e.sal , d.dname FROM emp e INNER JOIN dept d ON e.deptno=d.deptno;
自然:SELECT * FROM 表1 别名1 NATURAL JOIN 表2 别名2 ;
SELECT e.ename, e.sal , d.dname FROM emp e NATURAL JOIN dept d;
内连接查询出的所有记录都满足条件
③外连接
左外:SELECT * FROM 表1 别名1 LEFT OUTER JOIN 表2 别名2 ON 别名1.xx=别名2.xx;
左表记录无论是否满足条件都会查询出来,而右表只有满足条件才能出来。左表中不满足条件的记录,右表部分都为null。
SELECT e.ename, e.sal , IFNULL(d.dname,'无部门') AS dname FROM emp e LEFT OUTER JOIN dept d ON e.deptno=d.deptno;
左外自然:SELECT * FROM 表1 别名1 NATURAL LEFT OUTER JOIN 表2 别名2 ON 别名1.xx=别名2.xx;
右外:SELECT * FROM 表1 别名1 RIGHT OUTER JOIN 表2 别名2 ON 别名1.xx=别名2.xx;
右表记录无论是否满足条件都会查询出来,而左表只有满足条件才能出来。右表中不满足条件的记录,左表部分都为null。
右外自然:SELECT * FROM 表1 别名1 NATURAL RIGHT OUTER JOIN 表2 别名2 ON 别名1.xx=别名2.xx;
全链接:可以使用UNION来完成全连接。
SELECT e.ename, e.sal , d.dname FROM emp e LEFT OUTER JOIN dept d ON e.deptno=d.deptno UNION SELECT e.ename, e.sal , d.dname FROM emp e RIGHT OUTER JOIN dept d ON e.deptno=d.deptno;
4、子查询
查询中有查询(查看select关键字的个数)
①出现的位置
WHERE后作为条件存在
FROM后作为表存在(多行多列)
②条件
单行单列:SELECT * FROM 表1 别名1 WHERE 列1 [=、>、f539a70d3ea090bac4faa80192f58ccc=、<=、!=] (SELECT 列 FROM 表2 别名2 WHERE 条件) ;
SELECT * FROM emp WHERE sal=(SELECT MAX(sal) FROM emp);
多行单列:SELECT * FROM 表1 别名1 WHERE 列1 [IN,ALL,ANY] (SELECT 列 FROM 表2 别名2 WHERE 条件);
SELECT * FROM emp WHERE sal > ANY (SELECT sal FROM emp WHERE job='经理') ;
单行多列:SELECT * FROM 表1 别名1 WHERE (列1,列2)IN (SELECT 列1,列2 FROM 表2 别名2 WHERE 条件);
SELECT * FROM emp WHERE (job,deptno) IN (SELECT job,deptno from emp WHERE deptno=30) ;
多行多列:SELECT * FROM 表1 别名1,(SELECT......)表2 别名2 WHERE 条件;
Atas ialah kandungan terperinci MySQL中的约束与多表查询以及子查询的实例详解. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!