一、約束之主鍵約束 約束:約束是添加在列上的,用來約束列的。 1、主鍵約束(唯一標識):非空、唯一、被引用 當表的某一列被指定為主鍵後,該類就不能為空,不能有重覆值出現 創建表時指定主鍵的兩種方式: 指定sid列為主鍵列,即為sid列添加主鍵約束 修改表時指定主鍵: ALTER TABLE stu ...
一、約束之主鍵約束
約束:約束是添加在列上的,用來約束列的。
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 [=、>、<、>=、<=、!=] (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 條件;