MySQL数据库:完整性约束
1. 完整性約束
完整性約束是為了表的數(shù)據(jù)的正確性!如果數(shù)據(jù)不正確,那么一開始就不能添加到表中。
2. 主鍵
當(dāng)某一列添加了主鍵約束后,那么這一列的數(shù)據(jù)就不能重復(fù)出現(xiàn)。這樣每行記錄中其主鍵列的值就是這一行的唯一標(biāo)識。例如學(xué)生的學(xué)號可以用來做唯一標(biāo)識,而學(xué)生的姓名是不能做唯一標(biāo)識的,因?yàn)樾彰锌赡芡?/p>
主鍵列的值不能為NULL,也不能重復(fù)!指定主鍵約束使用PRIMARY KEY關(guān)鍵字
- 創(chuàng)建表:定義列時指定主鍵:
- 創(chuàng)建表:定義列之后獨(dú)立指定主鍵:
- 修改表時指定主鍵:
- 刪除主鍵(只是刪除主鍵約束,而不會刪除主鍵列):
3. 主鍵自增長
MySQL提供了主鍵自動增長的功能!這樣用戶就不用再為是否有主鍵是否重復(fù)而煩惱了。當(dāng)主鍵設(shè)置為自動增長后,在沒有給出主鍵值時,主鍵的值會自動生成,而且是最大主鍵值+1,也就不會出現(xiàn)重復(fù)主鍵的可能了。
- 創(chuàng)建表時設(shè)置主鍵自增長(主鍵必須是整型才可以自增長):
- 修改表時設(shè)置主鍵自增長:
- 修改表時刪除主鍵自增長:
4. 非空
指定非空約束的列不能沒有值,也就是說在插入記錄時,對添加了非空約束的列一定要給值;在修改記錄時,不能把非空列的值設(shè)置為NULL。
- 指定非空約束:
當(dāng)為sname字段指定為非空后,在向stu表中插入記錄時,必須給sname字段指定值,否則會報(bào)錯:
INSERT INTO stu(sid) VALUES(1);插入的記錄中sname沒有指定值,所以會報(bào)錯!
5. 唯一
還可以為字段指定唯一約束!當(dāng)為字段指定唯一約束后,那么字段的值必須是唯一的。這一點(diǎn)與主鍵相似!例如給stu表的sname字段指定唯一約束:
CREATE TABLE tab_ab(sid INT PRIMARY KEY AUTO_INCREMENT,sname VARCHAR(10) UNIQUE );INSERT INTO sname(sid, sname) VALUES(1001, 'zs'); INSERT INTO sname(sid, sname) VALUES(1002, 'zs');當(dāng)兩次插入相同的名字時,MySQL會報(bào)錯!
6. 概念模型
對象模型:在java中是domain,例如:User、Student,可以雙向關(guān)聯(lián),而且引用的是對象,而不是一個主鍵
關(guān)系模型:在數(shù)據(jù)庫中的表,只能多方引用一方,而且引用的只是主鍵,而不是一整行記錄。
當(dāng)我們要完成一個軟件系統(tǒng)時,需要把系統(tǒng)中的實(shí)體抽取出來,形成概念模型。例如部門、員工都是系統(tǒng)中的實(shí)體。概念模型中的實(shí)體最終會成為Java中的類、數(shù)據(jù)庫中的表。
實(shí)體之間還存在著關(guān)系,關(guān)系有三種:
- 1對多:例如每個員工都從屬一個部門,而一個部門可以有多個員工,其中員工是多方,而部門是一方。
- 1對1:例如老公和老婆就是一對一的關(guān)系,一個老公只能有一個老婆,而一個老婆只能有一個老公。
- 多對多:老師與學(xué)生的關(guān)系就是多對多,一個老師可以有多個學(xué)生,一個學(xué)生可以有多個老師。
概念模型在Java中成為實(shí)體類(javaBean),類就使用成員變量來完成關(guān)系,一般都是雙向關(guān)聯(lián)!多對一雙向中關(guān)聯(lián),即員工關(guān)聯(lián)部門,部門也關(guān)聯(lián)員工
class Employee {//多方關(guān)聯(lián)一方...private Department department;}class Department {//一方關(guān)聯(lián)多方...private List<Employee> employees;}class Husband {...private Wife wife;}class Wife {...private Husband}class Student {...private List<Teacher> teachers}class Teacher {...private List<Student> students;}7. 外鍵
主外鍵是構(gòu)成表與表關(guān)聯(lián)的唯一途徑!
- 外鍵必須是另一表的主鍵的值(外鍵要引用主鍵!)
- 外鍵可以重復(fù)
- 外鍵可以為空
- 一張表中可以有多個外鍵!
外鍵是另一張表的主鍵!例如員工表與部門表之間就存在關(guān)聯(lián)關(guān)系,其中員工表中的部門編號字段就是外鍵,是相對部門表的外鍵。
我們再來看BBS系統(tǒng)中:用戶表(t_user)、分類表(t_section)、帖子表(t_topic)三者之間的關(guān)系。
例如在t_section表中sid為1的記錄說明有一個分類叫java,版主是t_user表中uid為1的用戶,即zs!
例如在t_topic表中tid為2的記錄是名字為“Java是咖啡”的帖子,它是java版塊的帖子,它的作者是ww。
外鍵就是用來約束這一列的值必須是另一張表的主鍵值!!!
創(chuàng)建t_user表,指定uid為主鍵列:
CREATE TABLE t_user(uid INT PRIMARY KEY AUTO_INCREMENT,uname VARCHAR(20) UNIQUE NOT NULL );創(chuàng)建t_section表,指定sid為主鍵列,u_id為相對t_user表的uid列的外鍵:
CREATE TABLE t_section(sid INT PRIMARY KEY AUTO_INCREMENT,sname VARCHAR(30),u_id INT,CONSTRAINT fk_t_user FOREIGN KEY(u_id) REFERENCES t_user(uid) );修改t_section表,指定u_id為相對t_user表的uid列的外鍵:
ALTER TABLE t_section ADD CONSTRAINT fk_t_user FOREIGN KEY(u_id) REFERENCES t_user(uid);修改t_section表,刪除u_id的外鍵約束:
ALTER TABLE t_section DROP FOREIGN KEY fk_t_user;8. 表與表之間的關(guān)系
8.1 一對一
例如t_person表和t_card表,即人和身份證。這種情況需要找出主從關(guān)系,即誰是主表,誰是從表。人可以沒有身份證,但身份證必須要有人才行,所以人是主表,而身份證是從表。設(shè)計(jì)從表可以有兩種方案:
- 在t_card表中添加外鍵列(相對t_user表),并且給外鍵添加唯一約束;
- 給t_card表的主鍵添加外鍵約束(相對t_user表),即t_card表的主鍵也是外鍵。
在表中建立一對一關(guān)系比較特殊,需要讓其中一張表的主鍵,即是主鍵又是外鍵。
create table husband(hid int PRIMARY KEY,...);create table wife(wid int PRIMARY KEY,...ADD CONSTRAINT fk_wife_wid FOREIGN KEY(wid) REFERENCES husband(hid));其中wife表的wid即是主鍵,又是相對husband表的外鍵!
husband.hid是主鍵,不能重復(fù)!
wife.wid是主鍵,不能重復(fù),又是外鍵,必須來自husband.hid。
所以如果在wife表中有一條記錄的wid為1,那么wife表中的其他記錄的wid就不能再是1了,因?yàn)樗侵麈I。
同時在husband.hid中必須存在1這個值,因?yàn)閣id是外鍵。這就完成了一對一關(guān)系。
8.2 一對多(多對一)
最為常見的就是一對多!一對多和多對一,這是從哪個角度去看得出來的。t_user和t_section的關(guān)系,從t_user來看就是一對多,而從t_section的角度來看就是多對一!這種情況都是在多方創(chuàng)建外鍵!
數(shù)據(jù)庫表中的多對一關(guān)系,只需要在多方使用一個獨(dú)立的列來引用1方的主鍵即可
/*員工表*/create talbe emp (empno int primary key,/*員工編號*/...deptno int/*所屬部門的編號*/);/*部門表*/create table dept (deptno int primary key,/*部門編號*/...);emp表中的deptno列的值表示當(dāng)前員工所從屬的部門編號。也就是說emp.deptno必須在dept表中是真實(shí)存在!但是我們必須要去對它進(jìn)行約束,不然可能會出現(xiàn)員工所屬的部門編號是不存在的。這種約束就是外鍵約束。
我們需要給emp.deptno添加外鍵約束,約束它的值必須在dept.deptno中存在。外鍵必須是另一個表的主鍵!
語法:CONSTRAINT 約束名稱 FOREIGN KEY(外鍵列名) REFERENCES 關(guān)聯(lián)表(關(guān)聯(lián)表的主鍵)
/*創(chuàng)建表時指定外鍵約束*/create talbe emp (empno int primary key,...deptno int,CONSTRAINT fk_emp FOREIGN KEY(mgr) REFERENCES emp(empno) );/*修改表時添加外鍵約束*/ALERT TABLE empADD CONSTRAINT fk_emp_deptno FOREIGN KEY(deptno) REFERENCES dept(deptno);/*修改表時刪除外鍵約束*/ALTER TABLE empDROP FOREIGN KEY fk_emp_deptno;/*約束名稱*/8.3 多對多
例如t_stu和t_teacher表,即一個學(xué)生可以有多個老師,而一個老師也可以有多個學(xué)生。這種情況通常需要創(chuàng)建中間表來處理多對多關(guān)系。例如再創(chuàng)建一張表t_stu_tea表,給出兩個外鍵,一個相對t_stu表的外鍵,另一個相對t_teacher表的外鍵。
在表中建立多對多關(guān)系需要使用中間表,即需要三張表,在中間表中使用兩個外鍵,分別引用其他兩個表的主鍵。
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));這時在stu_tea這個中間表中的每條記錄都是來說明student和teacher表的關(guān)系
例如在stu_tea表中的記錄:sid為1001,tid為2001,這說明編號為1001的學(xué)生有一個編號為2001的老師
sid tid 101 201 /*編號為101的學(xué)生有一個編號為201的老師*/ 101 202 /*編號為101的學(xué)生有一個編號為202的老師*/ 101 203 /*編號為101的學(xué)生有一個編號為203的老師*/ 102 201 /*編號為102的學(xué)生有一個編號為201的老師*/ 102 204 /*編號為102的學(xué)生有一個編號為204的老師*/總結(jié)
以上是生活随笔為你收集整理的MySQL数据库:完整性约束的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL数据库:SQL语句
- 下一篇: MySQL数据库:编码