MySQL中的約束與多表查詢以及子查詢的實(shí)例詳解

一、約束之主鍵約束

約束:約束是添加在列上的,用來(lái)約束列的。

1、主鍵約束(唯一標(biāo)識(shí)):非空、唯一、被引用

當(dāng)表的某一列被指定為主鍵后,該類就不能為空,不能有重復(fù)值出現(xiàn)

創(chuàng)建表時(shí)指定主鍵的兩種方式:

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列添加主鍵約束

修改表時(shí)指定主鍵:

ALTER?TABLE?stu?ADD?PRIMARY?KEY(sid);

刪除主鍵:

ALTER?TABLE?stu?DROP?PRIMARY?KEY;

2、主鍵自增長(zhǎng)

因?yàn)橹麈I列的特性是:必須唯一,不能為空,所以我們通常會(huì)指定主鍵為整型,然后設(shè)置其自動(dòng)增長(zhǎng),這樣可以保證在插入數(shù)據(jù)時(shí)主鍵列的唯一和非空特性。

創(chuàng)建表時(shí)指定主鍵自增長(zhǎng)

CREATE?TABLE?stu(  ????sid??INT?PRIMARY?KEY?AUTO_INCREMENT,  ????sname??VARCHAR(20),  ????age??INT,  ????sex??VARCHEAR(10)  );

修改表時(shí)設(shè)置主鍵自增長(zhǎng):

ALTER?TABLE?stu?CHANGE?sid?sid?INT?AUTO_INCREMENT;

修改表時(shí)刪除主鍵自增長(zhǎng):

ALTER?TABLE?stu?CHANGE?sid?sid?INT?;

測(cè)試主鍵自增長(zhǎng):

INSERT?INTO?stu?VALUES(NULL,'zhangsan',23,'man');  INSERT?INTO?stu(sname,age,sex)?VALUES(NULL,'zhangsan',23,'man');

3、非空約束

因?yàn)槟承┝胁荒茉O(shè)置為null值,所以可以對(duì)添加非空約束。

例如:

CREATE?TABLE?stu?(    ?sid?INT?PRIMARY?KEY?AUTO_INCREMENT,    ?sname??VARCHAR(20)?NOT?NULL,    ?age???INT,    ?sex??VARCHAR(10)  );

對(duì)sname列設(shè)置了非空約束。

4、唯一約束

車庫(kù)某些列不能設(shè)置重復(fù)的值,所以可以對(duì)列添加唯一約束。

例如:

CREATE?TABLE?stu?(    ?sid?INT?PRIMARY?KEY?AUTO_INCREMENT,    ?sname??VARCHAR(20)?NOT?NULL?UNIQUE,    ?age???INT,    ?sex??VARCHAR(10)  );

二、概念模型

1、對(duì)象模型:在Java中是domain ,例如:User、Student?.

2、關(guān)系模型:在數(shù)據(jù)庫(kù)中表,1對(duì)多,1對(duì)1,多對(duì)多。

三、外鍵約束

外鍵必須是另一表的主鍵的值(外鍵要引用主鍵。)

外鍵可以重復(fù)

外鍵可以為空

1、創(chuàng)建時(shí)添加外鍵約束

CREATE?TABLE?dept?(  ????deptno?INT?PRIMARY?KEY?AUTO_INCREMENT,  ????dname?VARCHAR(50)  );  insert?into?dept?values(10,'研發(fā)部');  insert?into?dept?values(20,'人力部');  insert?into?dept?values(30,'財(cái)務(wù)部');    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,'研發(fā)部');  INSERT?INTO?dept?VALUES(20,'人力部');  INSERT?INTO?dept?VALUES(30,'財(cái)務(wù)部');    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、修改表時(shí)添加外鍵約束:

ALTER?TABLE?emp?ADD?CONSTRAINT?fk_emp_dept?FOREIGN?KEY(dno)?REFERNCES?dept(deptno);

四、數(shù)據(jù)庫(kù)關(guān)系模型

1、一對(duì)一關(guān)系

  在表中建立一對(duì)一關(guān)系比較特殊,需要讓其中一張表的主鍵,即是主鍵又是外鍵。

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、多對(duì)多關(guān)系

在表中建立多對(duì)多關(guān)系需要使用中間表,即需要三張表,在中間表中使用兩個(gè)外鍵,分別引用其他兩張表的主鍵。

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)?  );

在中間表中建立關(guān)系,如:

INSERT?INTO?stu_tea?VALUES(5,1);  INSERT?INTO?stu_tea?VALUES(2,2);  INSERT?INTO?stu_tea?VALUES(3,2);

五、多表查詢

1、分類

合并結(jié)果集

連接查詢

子查詢

2、合并結(jié)果查詢

要求被合并表中,結(jié)果集列的類型和列數(shù)相同

UNION,去除重復(fù)行

UNION ALL,不去除重復(fù)行

SELECT?*?FROM?表1名  UNION?ALL  SELECT?*?FROM?表2名;

3、連接查詢

①分類

內(nèi)連接

外連接

左外連接

右外連接

全外連接(mysql不支持)

自然連接(屬于一種簡(jiǎn)化方式)

②內(nèi)連接

方言: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;

??以條件篩選去除笛卡爾積中無(wú)用的信息。

標(biāo)準(zhǔn):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;

內(nèi)連接查詢出的所有記錄都滿足條件

③外連接

左外:SELECT * FROM 表1 別名1 LEFT OUTER JOIN 表2 別名2 ON 別名1.xx=別名2.xx;

左表記錄無(wú)論是否滿足條件都會(huì)查詢出來(lái),而右表只有滿足條件才能出來(lái)。左表中不滿足條件的記錄,右表部分都為null。

SELECT?e.ename,?e.sal?,?IFNULL(d.dname,'無(wú)部門')?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;

右表記錄無(wú)論是否滿足條件都會(huì)查詢出來(lái),而左表只有滿足條件才能出來(lái)。右表中不滿足條件的記錄,左表部分都為null。

右外自然:SELECT * FROM 表1 別名1?NATURAL RIGHT OUTER JOIN 表2 別名2 ON 別名1.xx=別名2.xx;

全鏈接:可以使用UNION來(lái)完成全連接。

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關(guān)鍵字的個(gè)數(shù))

①出現(xiàn)的位置

WHERE后作為條件存在

FROM后作為表存在(多行多列)

②條件

單行單列:SELECT * FROM 表1 別名1 WHERE 列1 [=、>、=、

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='經(jīng)理')?;

單行多列: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 條件;

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊11 分享