一 定义列属性列约束
所谓列约束,就是保证表的结构和数据的正确性和稳定性。
总的来说有五种: 唯一性和主键约束、外键约束、检查约束、空值约束、默认值约束,
有五大关键词, UNIQUE和Primary Key, Foreign Key, CHECK, NOT NULL, DEFAULT
总的来说有五种: 唯一性和主键约束、外键约束、检查约束、空值约束、默认值约束,
有五大关键词, 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。
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;如果不可以,则不设置默认值。
默认值必须为一个 常数, 不能为一个函数或一个表达式
可以不存在default,但是mysql会判断: 如果该列可以为空,则默认值为null;如果不可以,则不设置默认值。
有些列是不能有默认值的:
Blob,text。
时间戳类型,可以设置一个特殊的默认值 CURRENT_TIMESTAMP。在当列不存在或者传递的值为null时,使用当前的时间戳。
时间戳类型,可以设置一个特殊的默认值 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)
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)
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)
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