MySQL快速入门05----列属性 & 列约束 & 主键

本文介绍了MySQL数据库中定义列属性和约束的重要性,详细讲解了NULL、default值的设置,并重点探讨了主键和唯一索引的概念及两种实现方法。此外,还阐述了自动增长(auto_increment)属性的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一 定义列属性列约束





所谓列约束,就是保证表的结构和数据的正确性和稳定性。

总的来说有五种: 唯一性和主键约束、外键约束、检查约束、空值约束、默认值约束
有五大关键词, UNIQUE和Primary Key, Foreign Key, CHECK, NOT NULL, DEFAULT


二 列属性NULL


Null( 占用一个字节,char[0]不占用字节),表示没有值。与任何数据不同。表示什么都没有。Mysql的每条记录,如果存在可以为null的字段,则需要使用 一个字节保存哪些字段是空。(如果不显示设置not null,则默认该列数据是可以存放null值的。)
Null | not null可以规定当前列,是否可以为null。
Null的操作:
插入值null。
判断null,需要使用 is null or is not null来判断,不能直接比较=null。

如果一个列不允许为空,但是在赋值时,没有为该字段赋值,则会出现问题。

创建一个score_1表:
mysql> create table if not exists `score_1`(
    -> `a` int not null,
    -> `b` int
    -> );
Query OK, 0 rows affected (0.06 sec)
上表中,变量a设置为not null属性,变量b没有设置该属性,那么当插入新值时的表现如下:

mysql> insert into score_1 (a, b) values(null, 456);
ERROR 1048 (23000): Column 'a' cannot be null
上述代码表明,当向a中插入null值时会报错!


mysql> insert into score_1 (b) values(123);
ERROR 1364 (HY000): Field 'a' doesn't have a default value
mysql> insert into score_1 (a) values(123);
Query OK, 1 row affected (0.03 sec)
由上述代码可以看出,当直接向变量b中插入数据时,发生了错误,因为变量a中不能为空,所以插入数据时必须要给a变量赋值,然而,直接给a变量插入新值的时候变量b并没有报错。当只向a中插入数据的时候,b会设置为null。

数据展示:
mysql> select * from score_1;
+-----+------+
| a   | b    |
+-----+------+
| 123 | NULL |
+-----+------+
1 row in set (0.00 sec)

结构展示:
mysql> desc score_1;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| a     | int(11) | NO   |     | NULL    |       |
| b     | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.01 sec)



三 列属性default


DEFAULT子句用于为列指定一个默认,当该字段不存在值时(也就是没有为该段设置值时),会被启用。
默认值必须为一个 常数不能为一个函数或一个表达式
可以不存在default,但是mysql会判断: 如果该列可以为空,则默认值为null;如果不可以,则不设置默认值。

有些列是不能有默认值的: Blob,text

时间戳类型,可以设置一个特殊的默认值 CURRENT_TIMESTAMP。在当列不存在或者传递的值为null时,使用当前的时间戳。

mysql> create table if not exists review_tb1(
    -> `NO` int not null default 100,
    -> `Name` varchar(20) not null default 'Apple Lin',
    -> `Time` timestamp default CURRENT_TIMESTAMP,
    -> `Number` int
    -> );
Query OK, 0 rows affected (0.06 sec)

mysql>
mysql> insert into review_tb1 (Number) values (23);
Query OK, 1 row affected (0.01 sec)

mysql> select * from review_tb1;
+-----+-----------+---------------------+--------+
| NO  | Name      | Time                | Number |
+-----+-----------+---------------------+--------+
| 100 | Apple Lin | 2016-08-20 10:26:53 |     23 |
+-----+-----------+---------------------+--------+
1 row in set (0.00 sec)
当没有明确指定被插入的变量的值的时候才会调用默认值!

mysql> create table if not exists review_tb1(
    -> `NO` int not null default 100,
    -> `Name` varchar(20) not null default 'Apple Lin',
    -> `Time` timestamp default CURRENT_TIMESTAMP,
    -> `Number` int
    -> );
Query OK, 0 rows affected (0.08 sec)

mysql>
mysql> insert into review_tb1  values (null, null, null, 23);
ERROR 1048 (23000): Column 'NO' cannot be null
此时插入的值不能为null,这是否说明了null的权限要比default要大呢?




创建表score_2,使之都为not null,都有默认值:
mysql> create table if not exists `score_2`(
    -> `a` int not null default 10,
    -> `b` int not null default 20
    -> );
Query OK, 0 rows affected (0.05 sec)

向score_2表中插入新的数据:
mysql> insert into score_2 (a) values(123);
Query OK, 1 row affected (0.03 sec)

mysql> insert into score_2 (b) values(456);
Query OK, 1 row affected (0.03 sec)
上述代码表明,在只向变量a或者变量b中插入新的数据的时候并没有报错,而是将另外一个没有设置的变量设置的默认值

数据展示:
mysql> select * from score_2;
+-----+-----+
| a   | b   |
+-----+-----+
| 123 |  20 |
|  10 | 456 |
+-----+-----+
2 rows in set (0.00 sec)

结构展示:
mysql> desc score_2;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| a     | int(11) | NO   |     | 10      |       |
| b     | int(11) | NO   |     | 20      |       |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.01 sec)


四 主键&唯一索引


主关键字(primary key)是表中的一个或多个字段,它的值用于 惟一地标识表中的某一条记录。
要求主键的值不能重复且只能有一个主键
如果还存在不重复的记录,可以定义成唯一索引,提高检索效率。

主键不能为空,不设置或者null都会变成not null

定义索引,
列属性primary key 指明当前字段是主键。
通过表操作,primary key(字段名列表),可以定义多列在一起组成一个索引(8号楼2018组合表示一个房间)。

可以通过修改表来删除主键 :
alter table tbl_name drop primary key;

主键字段原则上在插入后,应该不被修改,但是语法上可以修改,但是修改的值不能与已有值冲突。




主键是可以唯一标识某条记录的字段或者是字段的集合。

主键可以是真实实体的属性,但是常用的好的解决方案是:利用一个与实体信息不相关的属性,作为唯一标识。

主键与业务逻辑不发生关系,只是用来标识记录。

设置主键之后,查找的速度回变得很快


方法一:


字段上设置,主键字段在插入时不能为空,或者冲突:

创建带有主键的表pk_1:
mysql> create table if not exists pk_1(
    -> id int primary key,
    -> name varchar(20),
    -> sex enum('boy', 'girl')
    -> );
Query OK, 0 rows affected (0.08 sec)

向表pk_1中插入数据:
mysql> insert into pk_1 values(1, 'Apple', 1);
Query OK, 1 row affected (0.03 sec)

mysql> insert into pk_1 values(2, 'Lin', 2);
Query OK, 1 row affected (0.01 sec)

数据展示:
mysql> select * from pk_1;
+----+-------+------+
| id | name  | sex  |
+----+-------+------+
|  1 | Apple | boy  |
|  2 | Lin   | girl |
+----+-------+------+
2 rows in set (0.00 sec)

结构展示:
mysql> desc pk_1;
+-------+--------------------+------+-----+---------+-------+
| Field | Type               | Null | Key | Default | Extra |
+-------+--------------------+------+-----+---------+-------+
| id    | int(11)            | NO   | PRI | NULL    |       |
| name  | varchar(20)        | YES  |     | NULL    |       |
| sex   | enum('boy','girl') | YES  |     | NULL    |       |
+-------+--------------------+------+-----+---------+-------+
3 rows in set (0.01 sec)
上述代码表明主键不能为null。

方法二:

在定义字段之后,可以定义多列主键(组合主键)

组合主键的意义:一个主键可以包含多个字段,而不是多个字段都是主键。

只需要一个唯一标识接口,mysql规定只能存在一个主键。

要求:常见的设计,每个表都应该存在一个可以唯一标识的主键字段,最好与实体没有联系,不是实体属性字段。

用第二种方法创建表pk_2:
mysql> create table if not exists pk_2(
    -> id int,
    -> name varchar(20),
    -> sex enum('boy', 'girl'),
    -> primary key(id, name)
    -> );
Query OK, 0 rows affected (0.07 sec)

向pk_2中插入数据:
mysql> insert into pk_2 values(3, 'Qian', 1);
Query OK, 1 row affected (0.03 sec)

mysql> insert into pk_2 values(4, 'Qin', 2);
Query OK, 1 row affected (0.17 sec)

数据展示:
mysql> select * from pk_2;
+----+------+------+
| id | name | sex  |
+----+------+------+
|  3 | Qian | boy  |
|  4 | Qin  | girl |
+----+------+------+
2 rows in set (0.00 sec)

结构展示:
mysql> desc pk_2;
+-------+--------------------+------+-----+---------+-------+
| Field | Type               | Null | Key | Default | Extra |
+-------+--------------------+------+-----+---------+-------+
| id    | int(11)            | NO   | PRI | 0       |       |
| name  | varchar(20)        | NO   | PRI |         |       |
| sex   | enum('boy','girl') | YES  |     | NULL    |       |
+-------+--------------------+------+-----+---------+-------+
3 rows in set (0.01 sec)
上述代码可以看出,该表中有两个主键,且两个主键不能为null。


五 自动增长auto_increment




定义要求: 该列上必须有索引,not null,只能存在一个自动增长的列,通常定义在主索引(主键)字段上。

在处理该列值时, 通常传递null或者不写。注意自动增长是可以添加值的。如果定义了主索引或者唯一索引,则添加时不能重复

只要某个自动增长出现过,即使该记录被删除也会被计算在内。

通常自动增长是 从1开始递增(默认),但是可以通过修改表属性,更改初始值。

表属性 auto_increment=x;(如果比已存在的小,则会从已有的最大值新记录)

创建拥有主键值且自动增长的表auin_1:
mysql> create table if not exists auin_1(
    -> id int primary key auto_increment,
    -> name varchar(20),
    -> sex enum('boy', 'girl')
    -> );
Query OK, 0 rows affected (0.04 sec)

向表中插入数据:
mysql> insert into auin_1 values(null, 'Apple', 1);
Query OK, 1 row affected (0.02 sec)

mysql> insert into auin_1 values(null, 'Lin', 2);
Query OK, 1 row affected (0.03 sec)

mysql> insert into auin_1 values(10, 'Qian', 1);
Query OK, 1 row affected (0.04 sec)
mysql> insert into auin_1 values(null, 'qin', 1);
Query OK, 1 row affected (0.02 sec)

数据展示:
mysql> select * from auin_1;
+----+-------+------+
| id | name  | sex  |
+----+-------+------+
|  1 | Apple | boy  |
|  2 | Lin   | girl |
| 10 | Qian  | boy  |
| 11 | qin   | boy  |
+----+-------+------+
4 rows in set (0.00 sec)
由上方代码可以看出,当没有指明自动增长的主键值时(NULL),新插入的数据会在原来主键值的基础上加1,;
当然了,你也可以自主设定主键的值,如其中名为Qian的主键id值我们就显示的设置为10。


更改自动增长的初始值:
mysql> alter table auin_1 auto_increment 100;
Query OK, 4 rows affected (0.17 sec)
Records: 4  Duplicates: 0  Warnings: 0

当再插入一个新的数据的时候:
mysql> insert into auin_1 values(null, 'Ting', 1);
Query OK, 1 row affected (0.02 sec)
mysql> insert into auin_1 values(null, 'ming', 1);
Query OK, 1 row affected (0.02 sec)


数据展示:
mysql> select * from auin_1;
+-----+-------+------+
| id  | name  | sex  |
+-----+-------+------+
|   1 | Apple | boy  |
|   2 | Lin   | girl |
|  10 | Qian  | boy  |
|  11 | qin   | boy  |
| 100 | Ting  | boy  |
| 101 | ming  | boy  |
+-----+-------+------+
6 rows in set (0.00 sec)
由上方代码可以看出,新插入的数据的id值设置为100,再往后的新插入的数据增长幅度依然是1.

注意:当重新更改自动增量的初始值小于当前最大的键值的时候,依然可以插入新的数据( 不能重复),但是该数据的主键值大小为原来最大键值加1,也就是更改没有发生作用。

如当前最大键值为101,先更改键值增量初始值为15:
mysql> alter table auin_1 auto_increment 15;
Query OK, 6 rows affected (0.14 sec)
Records: 6  Duplicates: 0  Warnings: 0

插入新的数据:
mysql> insert into auin_1 values(null, 'hong', 2);
Query OK, 1 row affected (0.03 sec)

数据展示:
mysql> select * from auin_1;
+-----+-------+------+
| id  | name  | sex  |
+-----+-------+------+
|   1 | Apple | boy  |
|   2 | Lin   | girl |
|  10 | Qian  | boy  |
|  11 | qin   | boy  |
| 100 | Ting  | boy  |
| 101 | ming  | boy  |
| 102 | hong  | girl |
+-----+-------+------+
7 rows in set (0.00 sec)
由上方代码可以看出,新加入的数据是在原来最大键值的基础上进行加1的结果。


也可以手动插入拥有键值的数据,但是键值不能重复:
mysql> insert into auin_1 values(15, 'ming', 1);
Query OK, 1 row affected (0.02 sec)
键值不重复,插入成功!

mysql> insert into auin_1 values(2, 'hong', 2);
ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'
键值重复,插入不成功!

数据展示:
mysql> select * from auin_1;
+-----+-------+------+
| id  | name  | sex  |
+-----+-------+------+
|   1 | Apple | boy  |
|   2 | Lin   | girl |
|  10 | Qian  | boy  |
|  11 | qin   | boy  |
|  15 | ming  | boy  |
| 100 | Ting  | boy  |
| 101 | ming  | boy  |
| 102 | hong  | girl |
+-----+-------+------+
8 rows in set (0.00 sec)

可以更新拥有主键值的id,但是 主键值不能重复
mysql> update auin_1 set id = 5 where name = 'lin';
Query OK, 1 row affected (0.03 sec)
Rows matched: 1  Changed: 1  Warnings: 0
































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值