MySQL創建表時加入的約束以及外鍵約束的的意義


1,創建表時加入的約束

a) 非空約束,not null

b) 唯一約束,unique

c) 主鍵約束,primary key

d) 外鍵約束,foreign key

1,非空約束,針對某個字段設置其值不為空,如:學生的姓名不能為空

drop table if exists t_student; 
create table t_student(
    student_id      int(10),
    student_name     varchar(20) not null,
    sex        char(2)  default  'm',
    birthday    date, 
    email        varchar(30),
    classes_id    int(3)    
)

反例,如果插入時 student_name為空違反了約束則報錯

insert into t_student(student_id, birthday, email, classes_id) 
values
(1002, '1988-01-01', 'qqq@163.com', 10)

2,唯一性約束,它可以使某個字段的值不能重復,如:email不能重復

drop table if exists t_student; 
create table t_student(
    student_id      int(10),
    student_name     varchar(20) not null,
    sex        char(2)  default  'm',
    birthday    date, 
    email        varchar(30)  unique,
    classes_id    int(3)    
)
drop table if exists t_student; 
create table t_student(
    student_id      int(10),
    student_name     varchar(20) not null,
    sex        char(2)  default  'm',
    birthday    date, 
    email        varchar(30)  ,
    classes_id    int(3)    ,
constraint email_unique unique(email)/*表級約束*/

3,主鍵約束

  每個表應該具有主鍵,主鍵可以標識記錄的唯一性,主鍵分為單一主鍵和復合(聯合)主鍵,單一主鍵是由一個字段構成的,復合(聯合)主鍵是由多個字段構成的。

drop table if exists t_student; 
create table t_student()
    student_id      int(10)  primary key,/*列級約束*/
    student_name     varchar(20) not null,
    sex        char(2)  default  'm',
    birthday    date, 
    email        varchar(30)  ,
    classes_id    int(3)    
)

或者

drop table if exists t_student; 
create table t_student(
    student_id      int(10),
    student_name     varchar(20) not null,
    sex        char(2)  default  'm',
    birthday    date, 
    email        varchar(30)  ,
    classes_id    int(3),
    CONSTRAINT p_id PRIMARY key (student_id)/*表級約束*/
)

4,外鍵約束

外鍵主要是維護表之間的關系的,主要是為了保證參照完整性,如果表中的某個字段為外鍵字段,那么該字段的值必須來源於參照的表的主鍵。

首先建立班級表t_classes

drop table if exists t_classes;
create table t_classes(
    classes_id int(3),
    classes_name varchar(40),
    constraint pk_classes_id primary key(classes_id)
)

在t_student中加入外鍵約束

drop table if exists t_student;
create table t_student(
    student_id       int(10),
    student_name     varchar(20),
    sex           char(2),
    birthday      date,
    email         varchar(30),
    classes_id    int(3),
    constraint    student_id_pk primary key(student_id),
   constraint    fk_classes_id foreign key(classes_id) references t_classes(classes_id)       
)

當我們向t_student中加入數據

insert into 
t_student(student_id, student_name, sex, birthday, email, classes_id)
values
(1001, 'zhangsan', 'm', '1988-01-01', 'qqq@163.com', 10)

出現錯誤,因為在班級表中不存在班級編號為10班級,外鍵約束起到了作用

存在外鍵的表就是子表,參照的表就是父表,所以存在一個父子關系,也就是主從關系,主表就是班級表從表就是學生表。

上面的例子中如果插入的時候把外鍵值設為null,可以插入成功。成功的插入了學生信息,但是classes_id沒有值,這樣會影響參照完整性,所以我們建議將外鍵字段設置為非空。

  當需要刪除班級數據,也會報錯,因為子表(t_student)存在一個外鍵classes_id,它參照了父表(t_classes)中的主鍵,所以先刪除子表中的引用記錄,再修改父表中的數據。

  因為子表(t_student)存在一個外鍵classes_id,它參照了父表(t_classes)中的主鍵,所以先刪除父表,那么將會影響子表的參照完整性,所以正確的做法是,先刪除子表中的數據,再刪除父表中的數據,采用drop table也不行,必須先drop子表,再drop父表

例如級聯更新

mysql對有些約束的修改比較麻煩,所以我們可以先刪除,再添加

alter table t_student drop foreign key fk_classes_id;

alter table t_student add constraint fk_classes_id_1 foreign key(classes_id) references t_classes(classes_id)  on update cascade;

級聯之后,我們只修改了父表中的數據,但是子表中的數據也會跟着變動。

2,需不需要外鍵

主鍵和索引是不可少的,不僅可以優化數據檢索速度,開發人員還省不其它的工作,

矛盾焦點:數據庫設計是否需要外鍵。這里有兩個問題:一個是如何保證數據庫數據的完整性和一致性;二是第一條對性能的影響。

 

正方觀點:
1,由數據庫自身保證數據一致性,完整性,更可靠,因為程序很難100%保證數據的完整性,而用外鍵即使在數據庫服務器當機或者出現其他問題的時候,也能夠最大限度的保證數據的一致性和完整性。
eg:數據庫和應用是一對多的關系,A應用會維護他那部分數據的完整性,系統一變大時,增加了B應用,A和B兩個應用也許是不同的開發團隊來做的。他們如何協調保證數據的完整性,而且一年以后如果又增加了C應用呢?
2,有主外鍵的數據庫設計可以增加ER圖的可讀性,這點在數據庫設計時非常重要。
3,外鍵在一定程度上說明的業務邏輯,會使設計周到具體全面。

反方觀點:
1,可以用觸發器或應用程序保證數據的完整性
2,過分強調或者說使用主鍵/外鍵會平添開發難度,導致表過多等問題
3,不用外鍵時數據管理簡單,操作方便,性能高(導入導出等操作,在insert,   update,   delete   數據的時候更快)
eg:在海量的數據庫中想都不要去想外鍵,試想,一個程序每天要insert數百萬條記錄,當存在外鍵約束的時候,每次要去掃描此記錄是否合格,一般還不 止一個字段有外鍵,這樣掃描的數量是成級數的增長!我的一個程序入庫在3個小時做完,如果加上外鍵,需要28個小時!  

 

結論:
1,在大型系統中(性能要求不高,安全要求高),使用外鍵;在大型系統中(性能要求高,安全自己控制),不用外鍵;小系統隨便,最好用外鍵。
2,用外鍵要適當,不能過分追求
3,不用外鍵而用程序控制數據一致性和完整性時,應該寫一層來保證,然后個個應用通過這個層來訪問數據庫。

需要注意的是:MySQL允許使用外鍵,但是為了完整性檢驗的目的,在除了InnoDB表類型之外的所有表類型中都忽略了這個功能。這可能有些怪異,實際上卻非常正常:對於數據庫的所有外鍵的每次插入、更新和刪除后,進行完整性檢查是一個耗費時間和資源的過程,它可能影響性能,特別是當處理復雜的或者是纏繞的連接樹時。因而,用戶可以在表的基礎上,選擇適合於特定需求的最好結合。所以,如果需要更好的性能,並且不需要完整性檢查,可以選擇使用MyISAM表類型,如果想要在MySQL中根據參照完整性來建立表並且希望在此基礎上保持良好的性能,最好選擇表結構為innoDB類型

 

轉自;https://www.cnblogs.com/fuland/p/4280434.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM