1. 程式人生 > >MySQL表操作(下篇)--完整性約束

MySQL表操作(下篇)--完整性約束

student 多列 地方 strong play 就是 custom def delet

一.介紹

約束條件與數據類型的寬度一樣,都是可選參數

作用:用於保證數據的完整性和一致性
主要分為: 

PRIMARY KEY (PK) 標識該字段為該表的主鍵,可以唯一的標識記錄
FOREIGN KEY (FK) 標識該字段為該表的外鍵
NOT NULL 標識該字段不能為空
UNIQUE KEY (UK) 標識該字段的值是唯一的
AUTO_INCREMENT 標識該字段的值自動增長(整數類型,而且為主鍵)
DEFAULT 為該字段設置默認值

UNSIGNED 無符號
ZEROFILL 使用0填充

說明:

1. 是否允許為空,默認NULL,可設置NOT NULL,字段不允許為空,必須賦值

2. 字段是否有默認值,缺少的默認值是NULL,如果插入記錄時不給字段賦值,此字段使用默認值
sex enum(‘male‘,‘female‘) not null default ‘male‘
age int unsigned NOT NULL default 20 必須為正值(無符號) 不允許為空 默認是20
3. 是否是key
主鍵 primary key
外鍵 foreign key
索引 (index,unique...)

二,PRIMARY KEY (PK)

primary key字段的值不為空且唯一

約束:not null unique
存儲引擎(innodb):對於innodb存儲引擎,一張表必須要有一個主鍵

============單列做主鍵===============
#方法一:not null+unique
create table department1(
id int not null unique, #主鍵
name varchar(20) not null unique,
comment varchar(100)
);

不指定主鍵MYSQL會尋找一個不為空且唯一的值為主鍵

#方法二:在某一個字段後用primary key
create table department2(
id int primary key, #主鍵
name varchar(20),
comment varchar(100)
);
#方法三:在所有字段後單獨定義primary key
create table department3(
id int,
name varchar(20),
comment varchar(100),
constraint pk_name primary key(id); #創建主鍵並為其命名pk_name 

constraint 是約束的意思,單獨拿出來加約束條件

==================多列做主鍵================
create table service(
ip varchar(15),
port char(5),
service_name varchar(10) not null,
primary key(ip,port)
); 

也稱之為復合主鍵

三,FOREIGN KEY (FK)

標識該字段為該表的外鍵,理解為一個表關聯另外一張表。

1.如何找出兩張表的關系

分析步驟:
#1、先站在左表的角度去找
是否左表的多條記錄可以對應右表的一條記錄,如果是,則證明左表的一個字段foreign key 右表一個字段(通常是id)

#2、再站在右表的角度去找
是否右表的多條記錄可以對應左表的一條記錄,如果是,則證明右表的一個字段foreign key 左表一個字段(通常是id)

#3、總結:
#多對一:出版社 書
如果只有步驟1成立,則是左表多對一右表
如果只有步驟2成立,則是右表多對一左表

從兩張表中找多對一的關系,只要有一個符合就新加一個字段關聯到另一張表

#多對多
如果步驟1和2同時成立,則證明這兩張表時一個雙向的多對一,即多對多,需要定義一個這兩張表的關系表來專門存放二者的關系

#一對一:
如果1和2都不成立,而是左表的一條記錄唯一對應右表的一條記錄,反之亦然。這種情況很簡單,就是在左表foreign key右表的基礎上,將左表的外鍵字段設置成unique即可

2,建立表之間的關系

#多對一

技術分享圖片

#先建立被關聯的表,並且保證被關聯表唯一

create table dep(
id int primary key,
name char(16),
comment char(50)
);

#在建立關聯表
create table emp(
id int primary key,
name char(16),
sex enum("male","female"),
dep_id int,
foreign key(dep_id)references dep(id)
on delete cascade
on update cascade # 在實際操作中盡量不要同步更新,影響擴展性
);

#插入數據
#先往被關聯表插入記錄

insert into dep values
(1,"IT","技術有限部門"),
(2,"銷售","銷售能力不足部門"),
(3,"財務","花錢特別多部門");


insert into emp values
(1,"egon","male",1),
(2,"alex","male",1),
(3,"wupeiqi","female",2),
(4,"yuanhao","male",3),
(5,"jingxin","male",2)

未加同步更新和刪除
刪除先刪除關聯表
delete from emp where dep_id=1;=
後刪除被關聯表
delete from dep where id=1;


加了同步更新
update dep set id=202 where id=2;

#多對多

技術分享圖片

create table author(
    id int primary key auto_increment,
    name char(20)
    );

create table book(
    id int primary key auto_increment,
    name char(20)
    );
    
create table author2book(
    id int not null unique auto_increment,
    author_id int not null,
    book_id int not null,
    constraint fk_author foreign key(author_id) references author(id)
    on delete cascade
    on update cascade,
    constraint fk_book foreign key(book_id) references book(id)
    on delete cascade
    on update cascade,
    primary key(author_id,book_id)
    );
    
insert into author values
    (1,"egon"),
    (2,"alex"),
    (3,"wupeiqi"),
    (4,"yuanhao");

insert into book values
    (1,"python自動換開發"),
    (2,"liunx高級運維"),
    (3,"爬蟲技術");

insert into author2book(author_id,book_id) values
    (1,1),
    (1,2),
    (2,1),
    (2,3),
    (3,1),
    (4,2);
    

#一對一

技術分享圖片

create table customer(
    id int primary key auto_increment,
    name char(20) not null,
    qq char(20) not null,
    phone char(20) not null
    );
    
create table student(
    id int primary key auto_increment,
    class_name char(20) not null,
    customer_id int unique, #該字段一定要是唯一的
    constraint fk_customer foreign key(customer_id) references customer(id) # 外鍵的字段也一定要保證唯一
    on delete cascade
    on update cascade
    );

insert into customer values
(1,"egon",123456,123456),
(2,"alex",2345,2345),
(3,"wupeiqi",3456,3456),
(4,"yuanhao",4567,4567);

insert into student(class_name,customer_id) values
("脫產3期",2),
("周末2期",1),
("周末2期",3);

四,NOT NULL 和 DEFAULT

是否可空,null表示空,非字符串
not null - 不可空
null - 可空

DEFAULT默認值,創建列時可以指定默認值,當插入數據時如果未主動設置,則自動添加默認值

mysql> create table student(
    -> name varchar(20) not null,
    -> age int(3) unsigned not null default 18,
    -> sex enum(male,female) default male,
    -> hobby set(play,study,read,music) default play,music
    -> );

五,UNIQUE KEY (UK)

============設置唯一約束 UNIQUE===============

方法一:
create table department1(
id int,
name varchar(20) unique,
comment varchar(100)
);


方法二:
create table department2(
id int,
name varchar(20),
comment varchar(100),
constraint uk_name unique(name)
);

聯合唯一
create table service(
id int primary key auto_increment,
name varchar(20),
host varchar(15) not null,
port int not null,
unique(host,port) #聯合唯一
);

六,AUTO_INCREMENT

標識該字段的值自動增長(整數類型,而且為主鍵)

約束字段為自動增長,被約束的字段必須同時被key約束

#不指定id,則自動增長
create table student(
id int primary key auto_increment,
name varchar(20),
sex enum(male,female) default male
);

清空表

delete from t20; #對於自增的字段,在用delete刪除後,再插入值,該字段仍按照刪除前的位置繼續增長

delete from t20 where id = 3;
insert into t20(name) values
("wxx");


truncate t20; #應該用它來徹底的清空表,

#在創建完表後,修改自增字段的起始值
mysql> create table student(
    -> id int primary key auto_increment,
    -> name varchar(20),
    -> sex enum(male,female) default male
    -> );

mysql> alter table student auto_increment=3;

mysql> show create table student;
.......
ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8

mysql> insert into student(name) values(egon);
Query OK, 1 row affected (0.01 sec)

mysql> select * from student;
+----+------+------+
| id | name | sex  |
+----+------+------+
|  3 | egon | male |
+----+------+------+
row in set (0.00 sec)

mysql> show create table student;
.......
ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8


#也可以創建表時指定auto_increment的初始值,註意初始值的設置為表選項,應該放到括號外
create table student(
id int primary key auto_increment,
name varchar(20),
sex enum(male,female) default male
)auto_increment=3;

#了解補充
show variables like "auto_inc%"; #%指向任意字符

# 步長:
auto_increment_increment 默認為1
#起始偏移量
auto_increment_offset 默認為1

#設置步長
set session auto_increment_increment= 5; # 設置當前會話級別
set global auto_increment_increment=5; # 設置全局會話級別(對所有會話有效),必須退出重新加載一遍

# 設置起始偏移量
set global auto_increment_offset= 3
強調起始偏移量<=步長

mysql> show variables like ‘auto_incre%‘; #需要退出重新登錄
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| auto_increment_increment | 1     |
| auto_increment_offset    | 1     |
+--------------------------+-------+

今天就到這裏了,如果有什麽不對的地方,一定要指出來,小白在這裏謝謝了。

MySQL表操作(下篇)--完整性約束