先看一个表结构。
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(11) | YES | | NULL | |
| password | varchar(11) | YES | | NULL | |
+---------+-------------+------+-----+---------+-------+
该表中的id、name、password字段都允许为空值。
插入一个数据
insert into aaaa values (3,"猫爷");
+------+--------+---------+
| id | mingzi | pssword |
+------+--------+---------+
| 1 | 猫爷 | 123456 |
| 2 | 狗哥 | 654321 |
| 3 | 猫爷 | NULL |
+------+--------+---------+
其中,第三行猫爷的password字段为空。
在创建表的时候,我们可以设置字段不为空。在使用表的时候,如果有业务要求可以为空,我们就可以不设置空值,之外我们最好都设置字段不能为空。
数据库是用来管理数据的,他对数据的管理很苛刻,其中是否为空就是数据库对数据的一种约束,只要对数据约束的够好,出现的错误就越少,在使用的时候也更加轻松。
create table bbbb(
id int not null,
name varchar(11) not null
);
desc bbbb;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | | NULL | |
| name | varchar(11) | NO | | NULL | |
+-------+-------------+------+-----+---------+-------+
这时候如果漏了一个字段不填数据,就会报错,数据库不允许不守规则的数据进入。
看表结构
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(11) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
表中默认值为空。默认值也是一种约束,插入一条记录时,某字段没有数据插入,该字段就会插入默认值。
创建一个新表cccc
create table cccc(
id int not null,
name varchar(11) default "三毛",
age enum('男','女') default '男'
)charset=utf8;
desc cccc;
+-------+-------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------------+------+-----+---------+-------+
| id | int(11) | NO | | NULL | |
| name | varchar(11) | YES | | 三毛 | |
| age | enum('男','女') | YES | | 男 | |
+-------+-------------------+------+-----+---------+-------+
插入几条记录
insert into cccc (id,name) values (1,"陈平安");
insert into cccc (id) values (2);
insert into cccc (id,age) values (3,'女');
+----+-----------+------+
| id | name | age |
+----+-----------+------+
| 1 | 陈平安 | 男 |
| 2 | 三毛 | 男 |
| 3 | 三毛 | 女 |
+----+-----------+------+
主键是用来唯一标识数据库的一个字段的数据,不能重复
,不能为空
。
如何设置主键:
create table dddd(
id int primary key comment '唯一标识',
name varchar(11) default '三毛'
)charset=utf8;
复合主键
有一些业务需求,一个单独的字段无法标识一段数据。
比如我们标识一个进程,是用ip地址和端口号来共同标识的。
create table eeee(
ip varchar(33) primary key comment 'IP地址',
port int primary key comment '端口号'
);
insert into eeee values ('127.0.0.1',8000);
插入成功
insert into eeee values ('127.0.0.1',8001);
插入成功
insert into eeee values ('192.0.0.3',8001);
插入成功
insert into eeee values ('127.0.0.1',8000);
插入失败
auto_increment:当对应的字段,不给值,会自动的被系统触发,系统会从当前字段中已经有的最大值+1操作,得到一个新的不同的值。通常和主键搭配使用,作为逻辑主键。
一搬设置主键的时候会给一个自增属性
mysql> create table tt21(
-> id int unsigned primary key auto_increment,
-> name varchar(10) not null default ''
-> );
mysql> desc aa;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(10) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
mysql>
insert into tt21(name) values('a');
mysql> insert into tt21(name) values('b');
mysql> select * from tt21;
+----+------+
| id | name |
+----+------+
| 1 | a |
| 2 | b |
+----+------+
自增长的特点:
唯一键和主键有一点类似,都是不许字段中的数据重复。
一张表中,主键的选取一般情况下是都是与业务无关的字段,但表中的字段也有一些具有唯一属性,我们也不能把他设置成主键,故可以把这些字段设置成唯一键。
create table students(
id int primary key comment "表的主键",
name varchar(11) not null comment "学生名字",
phone varchar(11) unique comment "学生的电话号码",
identity varchar(18) unique comment "身份证号"
);
关于唯一键和主键的区别:
我们可以简单理解成,主键更多的是标识唯一性的。而唯一键更多的是保证在业务上,不要和别的信息出现重复
mysql> desc students;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(13) | NO | | NULL | |
| phone | varchar(11) | YES | UNI | NULL | |
| dentity | varchar(18) | YES | UNI | NULL | |
+---------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
创建成功。。。。。。。。
insert into students values (1,"王二","12345678","111111111111111111");
插入成功
insert into students values (2,"王二","123456789","111111111111111111");
插入失败,dentity字段的内容在表中已经存在,不能重复
insert into students values (2,"王二","123456789","");
插入成功
insert into students values (3,"王二","1111","1111");
插入成功
select * from students;
+----+--------+-----------+--------------------+
| id | name | phone | dentity |
+----+--------+-----------+--------------------+
| 1 | 王二 | 12345678 | 111111111111111111 |
| 2 | 王二 | 123456789 | |
| 3 | 王二 | 1111 | 1111 |
+----+--------+-----------+--------------------+
3 rows in set (0.00 sec)
小知识:如果表已经创建成功,但是想要修改表中的字符集
alter table students convert to character set utf8
外键就需要涉及多张表了。
比如:
表一,班级表
create table classes(
id int primary key comment "班级号",
name varchar(11 not null comment "班级名称"
);
表二,学生表
create table students(
id int primary key comment "学号",
name varchar(11 not null comment "名字",
class_id int comment "所处班级"
);
这两张表中,其中班级表 name字段就是外键。
学生表关联班级表,班级表是被关联者,班级表属于主表,学生表属于从表。
但是上面两张表并没有构成外键约束。
看例子:
mysql> select * from students;
+-----+--------+--------+
| id | name | class_id |
+-----+--------+--------+
| 2 | 小彭 | 101 |
| 3 | 小波 | 102 |
| 4 | 小烧 | 400 |
| 1 | 小陈 | 100 |
+-----+--------+--------+
我是能插入班级等于400的数据的,可实际上班级表中并没有400这个班级,这就是并没有设置外键约束
mysql> select * from classes;
+-----+-----------+
| id | name |
+-----+-----------+
| 100 | 尖子班 |
| 101 | 普通班 |
| 103 | 文艺班 |
+-----+-----------+
正确做法,在创建班级表的时候加外键约束
表一,班级表
create table classes(
id int primary key comment "班级号",
name varchar(11 not null comment "班级名称",
foreign key (class_id) references myclass(id)
);
语法:foreign key (字段名) references 主表(列)
可能有人会说,我们不是可以用一张表吗?在学生表后面再加一个班级字段就行了啊,为什么还要多弄处一张表出来?
一张表会造成数据冗余
首先我们承认,这个世界是数据很多都是相关性的。
理论上,上面的例子,我们不创建外键约束,就正常建立学生表,以及班级表,该有的字段我们都有。
因为此时两张表在业务上是有相关性的,但是在业务上没有建立约束关系,那么就可能出现问题。
解决方案就是通过外键完成的。建立外键的本质其实就是把相关性交给mysql去审核了,提前告诉mysql表之间的约束关系,那么当用户插入不符合业务逻辑的数据的时候,mysql不允许你插入。