4.2 主键约束

一个表中可以有多个列,一个列中的数据有可能会重复。如学生信息表中,若有两个学生重名,那么姓名列的数据将出现重复现象。那么在为学生统计分数的时候,如何才能更精确地找出一个学生,而不是与他重名的学生呢?这就需要为学生信息表设置一个主键。

主键是不允许有重复数据的列,能够唯一地确认记录,与该记录的其他字段有没有重复无关。如学生信息表,即使重名的学生姓名、性别、年龄等信息都相同,只要不是一个人,就可以为他们定义不同的主键值来确定不同学生。

本节介绍主键的概述和使用,包括主键的创建、修改和删除等。

4.2.1 主键约束概述

主键是表的标识列,在MySQL中支持主键组的使用,即将多个字段作为一个主键来使用。这一组字段中的每个字段,作为主键的构成缺一不可。对主键的操作即对这一组字段的操作。

若表中具有实际意义的字段无法作为主键,那么可以为表添加一个字段作为主键。在日常应用中,主键往往是没有实际意义的列,这样能够有效避免字段因实际情况对数据产生影响。如有些网站为用户设置不同的用户名来作为主键,那么用户注册或修改用户名将变得很麻烦。此时只需要另外添加一个字段作为主键,由系统分配一个唯一的数据作为主键的值即可。

关系数据库依赖于主键,它是数据库物理模式的基石。主键在物理层面上只有两个用途,如下所示。

(1)唯一地标识一行记录。

(2)作为一个可以被外键引用的有效对象。

基于以上这两个用途,在设计物理层面的主键时需要遵循以下原则。

(1)MySQL主键通常是单列的,以便提高连接和筛选操作的效率。但MySQL支持复合主键的使用。

(2)主键通常不需要更换,能够唯一地标识一行数据。

(3)MySQL主键通常是对用户没有意义的。

(4)MySQL主键最好不要包含动态变化的数据,如时间戳、创建时间列、修改时间列等。

(5)MySQL主键通常由计算机自动生成,如对主键添加自增约束。

4.2.2 创建主键约束

主键是表中最重要的约束,一个表可以没有其他约束,但一定要有主键。在MySQL中,没有主键的表,将不允许在MySQL Workbench工具下对表中的数据进行添加、修改和删除,只能够查询到表中已有的数据。因为没有主键的表是违反了数据安全性管理的。本节介绍主键的创建,可以使用MySQL Workbench或使用SQL语句实现主键的创建。

1.MySQL Workbench创建主键

在MySQL Workbench工具下,创建表的时候可以直接创建主键,如图4-1所示。其操作可参考3.4.1节。

图4-1 创建约束

如图4-1所示,在新建表的时候,第一个列默认是主键约束列,被勾选了PK和NN两个复选框。选中该列时,界面下方将显示该列详细的属性。

图4-1中选中的是第一列,勾选了PK和NN两个复选框,下方的Primary和Not Null复选框也处于选中状态。PK复选框与Primary复选框是相对应的;NN与Not Null是一个意思。

所有约束的创建都是在如图4-1所示的界面中进行,对图中约束的复选框介绍如下。

(1)PK:与Primary一样,表示主键约束。

(2)NN:与Not Null一样,表示不能为空,是非空约束。

(3)UQ:与Unique一样,表示数据不重复,是唯一约束。

(4)BIN:与Binary一样,表示二进制存储。

(5)UN:与Unsigned一样,表示整数。

(6)ZF:与Zero Fill一样,表示数值中空白区域以0填补。

(7)AI:与Auto Increment一样,是自增约束。

(8)Default:默认值约束。

由于主键是列的唯一标识,因此主键不能为空,在设置主键时将默认添加主键约束和非空约束。另外,主键即使不添加唯一约束,也是不能有重复数据的。选中需要为列添加的约束,即可单击Apply按钮执行数据表创建;接着在弹出对话框中单击Apply按钮确认执行SQL语句;最后在弹出的对话框中单击Finish按钮完成数据表的创建。

2.SQL语句创建主键

使用SQL语句同样可以创建主键。主键分为单字段主键和复合主键,其用法如下所示。

(1)单字段主键只需在创建语句中,字段的数据类型后面添加PRIMARY KEY语句即可。

(2)复合主键需要在字段创建语句后,添加PRIMARY KEY(字段列表)语句,在KEY关键字后的括号中,写入需要设置为主键的字段列表,只用逗号隔开。

【范例1】

创建一个表,有主键id和字段name,代码如下。

CREATE TABLE 'shop'.'newtable' (
      'id' INT NOT NULL,
      'name' VARCHAR(45) NULL,
      PRIMARY KEY ('id'));

上述代码创建了单字段主键id。

【范例2】

创建一个表,有id、name和pas字段,其中id和name字段构成复合主键,代码如下。

CREATE TABLE 'shop'.'table' (
      'id' INT NOT NULL,
      'name' VARCHAR(45) NOT NULL,
      'pas' VARCHAR(45) NULL,
      PRIMARY KEY ('id', 'name'));

4.2.3 修改主键约束

修改主键包括两种,一种是在没有主键的表中设置主键,一种是有主键的表中将主键换到其他的字段。主键的修改可以在MySQL Workbench中进行,也可以使用SQL语句执行。

1.MySQL Workbench修改主键

在MySQL Workbench中修改主键与修改字段属性的方式一样,首先打开表修改界面,如图4-2所示。

图4-2 修改约束

如图4-2所示,该图虽然和图4-1很相似,但图4-1是创建表的界面,而图4-2是表修改的界面。在界面中可以设置、取消或修改主键,也可以修改其他的约束,在设置完成后单击Apply按钮执行约束的修改;接着在弹出对话框中单击Apply按钮确认执行SQL语句;最后在弹出的对话框中单击Finish按钮完成约束的修改。这里所说的修改包括约束的添加、删除和替换;而且可以是对任意约束进行的,不仅是主键约束的修改。

2.SQL语句修改主键

使用SQL语句修改主键没有MySQL Workbench工具那么轻松,需要区分两种方式:一种是在没有主键的表中设置主键,一种是有主键的表中将主键换到其他的字段。

表中没有主键,通过修改指定字段的类型来设置其主键,与修改字段的类型方式一样,如范例3所示。

【范例3】

为shop.newtable表的id列设置主键,代码如下。

ALTER TABLE 'shop'.'newtable'
    CHANGE COLUMN 'id' 'id' INT(11) NOT NULL ,
    ADD PRIMARY KEY ('id');

上述代码中,由于字段是在id列,因此只需要修改id列的数据类型,并使用ADD PRIMARY KEY()添加新的主键。

表中已经有主键的,在修改主键时分为两个步骤:删除原有主键;添加新的主键。因此在创建之前首先要删除原有主键,如范例4所示。

【范例4】

删除shop.newtable表的id列的主键,将主键转移到name列,代码如下。

ALTER TABLE 'shop'.'newtable'
    CHANGE COLUMN 'id' 'id' INT(11) NULL ,
    CHANGE COLUMN 'name' 'name' VARCHAR(45) NOT NULL ,
    DROP PRIMARY KEY,
    ADD PRIMARY KEY ('name');

由于将主键由id列转移到name列,涉及两个列的换行,因此需要修改这两个列的数据类型。同时使用DROP PRIMARY KEY语句删除主键;使用ADD PRIMARY KEY()添加新的主键。