KEY:
primay key 主鍵,一個表中隻能有一個主鍵,主鍵的意思就是非空且唯一
unique 定義該字段的值唯一
【001】我們設定一個整形字段直接自增,會報錯:提示隻能有一個自增長的字段,要麼是unique key,要麼是primary key
mysql> create table t20(id int auto_increment,name char(10));
ERROR1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined asa key
create table t20(idint primary key auto_increment,name char(10));
create table t21(idint not null unique auto_increment,name char(10));
比較t20和t21這兩張表,我們發現primary key和notnullunique是等同的
【002】下面我們來驗證下,一張表中是否可以建立多個主鍵
create table t22(
idintprimary key,
namechar(10)
);
create table t23(
idint,
namechar(10),
constraint pri_id primary key(id) # 在字段定義完畢後,再來限制它為主鍵,這裡pri_id給限制起一個名字
);
上面的方式也可以像如下的方式這樣寫(實際中我們還是直接在定義字段的時候就指定主鍵)
create table t24(
idint,
namechar(10),
primary key(id)
);
下面我們示範直接加入unique key,下面兩種方式均可以
create table t25(
idint,
namechar(10),
constraint uni_id unique(id)
);
create table t26(
idint,
namechar(10),
unique(id)
);
#隻能有一個主建,但是可以有多個notnullunique
# 建立如下這張表時會報錯,因為一張表中隻能存在一個主鍵
create table t27(
idint,
namechar(10),
primary key(id),
primary key(name)
);
一張表中可以有多個notnullunique
create table t28(
idint not nullunique,
namechar(10) not nullunique
);
DESC t28;雖然可以存在多個notnullunique,但是最終隻有一個成為了主鍵,隻有ID成為了主鍵
即如果你在定義一個表時,沒有使用primary key定義主鍵,那麼預設就用第一個notnullunique修飾的字段作為主鍵
表中不一定需要存在主鍵
我們最後來看一個聯合唯一的主鍵
需求:現在我使用t29來存儲一個服務資訊,
為了保證每個服務是獨立的,我需要保證該服務所對應的IP位址和端口的組合不一樣
IP位址可以一樣,隻要端口不一樣即可,這就設計到聯合唯一的概念。我們可以将
ip和端口設定為一個聯合主鍵
#聯合唯一
create table t29(
idint,
ipchar(15), # 由于IP位址是固定的長度,是以我們推薦使用char類型
portint,
primary key(ip,port)
);
insert into t29 values
(1,'1.1.1.1',3306),
(2,'1.1.1.2',3306),
(3,'1.1.1.1',8080)
;
現在問題來了,這樣設定不合理,因為ID這個字段應該是自增的,用來辨別此時到了多少條記錄
既然是自增的,那麼就要将它設定為一個key,要麼是primary key,要麼是unique key;
通常ID字段設定為primary key,我們通常查詢表時,都是通過ID字段來作為查詢依據,這涉及到
MySQL的優化機制。像上面的那樣,如果設定将IP和port設定為primary key,以後查詢就很不友善。
而同時我們又要保證ip和port的組合不為空且唯一,是以隻能将其設定為unique。
這樣設定完畢後,就可以保證ip和port是聯合唯一的,但主鍵不是它們兩個
create table t30(
idintprimary key auto_increment,
ipchar(15) not null,
portint not null,
unique(ip,port)
);
desc t30;
此時我們可以得知ip和port就是聯合唯一的,下面我們插入值就可以使用如下的方式啦,非常友善:
insert into t30(ip,port) values
('1.1.1.1',3306),
('1.1.1.1',3307),
('1.1.1.2',3307)
;