概述
上篇,我们简单的学习了一下,数据库及数据表的简单操作,今天,我们接着上篇的内容来学习。
学习
空值与非空
字段 | 作用 |
---|---|
NULL | 字段值可以为空 |
NOT NULL | 字段值禁止为空 |
如:
mysql> create table tab2(
-> username varchar(20) not null,
-> age tinyint unsigned not null,
-> salary float(8,2) unsigned not null
-> );
Query OK, 0 rows affected (0.11 sec)
查看表结构:
mysql> show columns from tab2;
+----------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------------------+------+-----+---------+-------+
| username | varchar(20) | NO | | NULL | |
| age | tinyint(3) unsigned | NO | | NULL | |
| salary | float(8,2) unsigned | NO | | NULL | |
+----------+---------------------+------+-----+---------+-------+
3 rows in set (0.05 sec)
自动编号
- 特点
- 自动编号,且必须与主键组合使用
- 默认情况下,起始值为1,每次的增量为1
这里,提到了一个新的名词-主键,我们来学习下:
主键 PRIMARY KEY
主键全称为主键约束,有以下特点:
- 特点
- 每张数据表只能存在一个主键
- 主键保证记录的唯一性
- 主键自动为NOT NULL
结合自动编号,我们的demo可以改为这样:
mysql> create table tab3(
-> _id tinyint unsigned auto_increment primary key,
-> username varchar(20) not null,
-> age tinyint unsigned not null,
-> salary float(8,2) unsigned not null
-> );
Query OK, 0 rows affected (0.11 sec)
再查看表结构:
mysql> show columns from tab3;
+----------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------------------+------+-----+---------+----------------+
| _id | tinyint(3) unsigned | NO | PRI | NULL | auto_increment |
| username | varchar(20) | NO | | NULL | |
| age | tinyint(3) unsigned | NO | | NULL | |
| salary | float(8,2) unsigned | NO | | NULL | |
+----------+---------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
这个时候,我们插入数据试试。
mysql> insert into tab3 values(null,'Jack',23,3200.00);
Query OK, 1 row affected (0.08 sec)
mysql> insert into tab3 values(null,'Lucy',21,32000.00);
Query OK, 1 row affected (0.00 sec)
mysql> insert into tab3 values(null,'Tom',25,32500.00);
Query OK, 1 row affected (0.00 sec)
mysql> select * from tab3;
+-----+----------+-----+----------+
| _id | username | age | salary |
+-----+----------+-----+----------+
| 1 | Jack | 23 | 3200.00 |
| 2 | Lucy | 21 | 32000.00 |
| 3 | Tom | 25 | 32500.00 |
+-----+----------+-----+----------+
3 rows in set (0.00 sec)
可以看到,已经自动给我们的id编号了。
唯一约束 UNIQUE KEY
- 特点
- 唯一约束可以保证记录的唯一性
- 唯一约束的字段可以为空值(NULL)
- 每张数据表可以存在多个唯一约束
如:
mysql> create table tab4(
-> _id tinyint unsigned auto_increment primary key,
-> username varchar(20) not null unique key,
-> age tinyint unsigned not null,
-> salary float(8,2) unsigned not null
-> );
Query OK, 0 rows affected (0.01 sec)
我们接着看一下表结构:
mysql> show columns from tab4;
+----------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------------------+------+-----+---------+----------------+
| _id | tinyint(3) unsigned | NO | PRI | NULL | auto_increment |
| username | varchar(20) | NO | UNI | NULL | |
| age | tinyint(3) unsigned | NO | | NULL | |
| salary | float(8,2) unsigned | NO | | NULL | |
+----------+---------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
这个时候,我们插入数据试试。
mysql> insert into tab4 values(null,'Jack',23,3200.00);
Query OK, 1 row affected (0.00 sec)
mysql> insert into tab4 values(null,'Jack',23,3200.00);
ERROR 1062 (23000): Duplicate entry 'Jack' for key 'username'
mysql> insert into tab4 values(null,'Tom',23,3200.00);
Query OK, 1 row affected (0.00 sec)
mysql> insert into tab4 values(null,'Lucy',23,32000.00);
Query OK, 1 row affected (0.00 sec)
可以看到,插入username重复值时会报错。
默认值 DEFAULT
- 特点
- 可以设置默认值
- 当插入记录时,如果没有明确为字段赋值,则自动赋予默认值
- 每张数据表可以存在多个默认值
如:
mysql> create table tab5(
-> _id tinyint unsigned auto_increment primary key,
-> username varchar(20) not null unique key,
-> age tinyint unsigned not null default 20,
-> salary float(8,2) unsigned not null
-> );
Query OK, 0 rows affected (0.01 sec)
查看表结构:
mysql> show columns from tab5;
+----------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------------------+------+-----+---------+----------------+
| _id | tinyint(3) unsigned | NO | PRI | NULL | auto_increment |
| username | varchar(20) | NO | UNI | NULL | |
| age | tinyint(3) unsigned | NO | | 20 | |
| salary | float(8,2) unsigned | NO | | NULL | |
+----------+---------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
插入数据试试:
mysql> insert into tab5(username,salary) value('Lucy',32000.00);
Query OK, 1 row affected (0.00 sec)
mysql> select * from tab5;
+-----+----------+-----+----------+
| _id | username | age | salary |
+-----+----------+-----+----------+
| 1 | Lucy | 20 | 32000.00 |
+-----+----------+-----+----------+
1 row in set (0.02 sec)
其实,我们刚才学习了这么多条件,他们统称为约束。
- 约束的作用
- 约束保证数据的完整性和一致性
- 约束分为表级约束和列级约束
- 约束类型
- NOT NULL (非空约束)
- PRIMARY KEY (主键约束)
- UNIQUE KEY (唯一约束)
- DEFAULT (默认约束)
- FOREIGN KEY (外键约束)
其中,提到了外键约束,顾名思义,是外部的约束,这就涉及到两张表之间的关系了(子表和父表)。
外键约束
特点
- 保证数据一致性、完整性
- 实现了一对一或者一对多的关系
要求
- 父表和子表必须使用相同的存储引擎,而且禁止使用临时表
- 数据表的存储引擎只能是InnoDB
- 外键列和参照列必须具有相似的数据类型,其中数字的长度或是否有符号位必须相同;而字符的长度则可以不同
- 外键列和参照列必须具有创建索引,如果外键列不存在索引的话,mysql将自动创建索引。
如,我们新建两张表:
mysql> create table provinces(
-> _id int unsigned primary key auto_increment,
-> pname varchar(25) not null
-> );
Query OK, 0 rows affected (0.00 sec)
mysql> create table userinfor(
-> _id int unsigned primary key auto_increment,
-> username varchar(20) not null,
-> age int unsigned not null default 20,
-> pid int unsigned,
-> foreign key(pid) references provinces(_id)
-> );
Query OK, 0 rows affected (0.02 sec)
接着查看下userinfor表的结构:
mysql> show create table userinfor \G;
*************************** 1. row ***************************
Table: userinfor
Create Table: CREATE TABLE `userinfor` (
`_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(20) NOT NULL,
`age` int(10) unsigned NOT NULL DEFAULT '20',
`pid` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`_id`),
KEY `pid` (`pid`),
CONSTRAINT `userinfor_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `provinces` (`_id
`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
那么,它到底是干啥的咧?
我们可以这么理解,当我们在一个用户表中有省份这个字段时,而省份表单独存在,我们要保证加入的省份属于省份表中的,这个时候,如果不使用外键的话,每次添加的时候就很麻烦了。我们添加几个数据试试。
当省份表没有数据时
mysql> insert into userinfor(username,pid) value('Jack',1);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint f
ails (`myschool`.`userinfor`, CONSTRAINT `userinfor_ibfk_1` FOREIGN KEY (`pid`)
REFERENCES `provinces` (`_id`))
可以看到,无法添加成功
为省份添加几个数据,再添加用户信息
mysql> insert into provinces values(null,'湖北');
Query OK, 1 row affected (0.00 sec)
mysql> insert into provinces values(null,'湖南');
Query OK, 1 row affected (0.00 sec)
mysql> insert into provinces values(null,'天津');
Query OK, 1 row affected (0.00 sec)
mysql> select * from provinces;
+-----+-------+
| _id | pname |
+-----+-------+
| 1 | 湖北 |
| 2 | 湖南 |
| 3 | 天津 |
+-----+-------+
3 rows in set (0.00 sec)
mysql> insert into userinfor(username,pid) value('Jack',1);
Query OK, 1 row affected (0.00 sec)
可以看到,这次添加成功了,这是因为这个时候省份表中,有id=1这个字段了,我们再去添加个pid = 4的数据试试
mysql> insert into userinfor(username,pid) value('Lucy',4);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint f
ails (`myschool`.`userinfor`, CONSTRAINT `userinfor_ibfk_1` FOREIGN KEY (`pid`)
REFERENCES `provinces` (`_id`))
可以看到,无法添加成功,但是,这里又有一个问题出现了,就是,如果我们去删除父表(provinces)中的字段
mysql> delete from provinces where _id = 1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constrai
nt fails (`myschool`.`userinfor`, CONSTRAINT `userinfor_ibfk_1` FOREIGN KEY (`pi
d`) REFERENCES `provinces` (`_id`))
删除不了,这是因为在子表中还有与它关联的数据,这里就有了外键约束的参照操作。
字段 | 作用 |
---|---|
CASCADE | 从父表删除或更新且自动删除或更新子表中匹配的行 |
SET NULL | 从父表删除或更新行并设置子表中的外键为NULL(如果使用该选项,必须保证子表列表没有指定NOT NULL) |
RESTRICT | 拒绝对父表的删除或更新操作 |
NO ACTION | 标准SQL的关键字,在MYSQL中与RESTRICT相同 |
我们再去新建一张表,然将上一张表删除
mysql> create table userinfor1(
-> _id int unsigned primary key auto_increment,
-> username varchar(20) not null,
-> pid int unsigned,
-> foreign key(pid) references provinces(_id) on delete cascade
-> );
Query OK, 0 rows affected (0.01 sec)
mysql> drop table userinfor;
Query OK, 0 rows affected (0.01 sec)
添加用户数据
mysql> insert into userinfor1(username,pid) value('Jack',1);
Query OK, 1 row affected (0.00 sec)
mysql> insert into userinfor1(username,pid) value('Lucy',2);
Query OK, 1 row affected (0.00 sec)
mysql> select * from userinfor1;
+-----+----------+------+
| _id | username | pid |
+-----+----------+------+
| 1 | Jack | 1 |
| 2 | Lucy | 2 |
+-----+----------+------+
2 rows in set (0.00 sec)
我们再次尝试删除省份表中的数据
mysql> delete from provinces where _id = 1;
Query OK, 1 row affected (0.00 sec)
mysql> select * from userinfor1;
+-----+----------+------+
| _id | username | pid |
+-----+----------+------+
| 2 | Lucy | 2 |
+-----+----------+------+
1 row in set (0.00 sec)
可以看到,我们删除了省份表中的数据时,用户信息表也对应删除了。其他的大家可以自己试试。
基础二到此,转到基础三