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