首页 > 数据库 >MySQL 常见约束

MySQL 常见约束

时间:2023-02-09 11:36:39浏览次数:46  
标签:insert name no 常见 约束 area user MySQL 主键


MySQL 常见约束

  • ​​前言​​
  • ​​非空约束(not null)​​
  • ​​唯一约束(unique)​​
  • ​​1、设置编号是唯一的(列级约束:该约束只应用于相关的一列上):​​
  • ​​2、给两个列或者多个列添加 unique(表级约束:可以应用在一个表中的多列上)​​
  • ​​主键约束( primary key )​​
  • ​​1、单一主键​​
  • ​​2、复合主键​​
  • ​​3、自然主键和业务主键​​
  • ​​4、MySQL 提供主键值自增(auto_increment)​​
  • ​​外键约束(foreign key)​​
  • ​​父表和子表的操作顺序​​

前言

在创建表的时候,可以给表的字段添加相应的约束,添加约束的目的是为了保证表中数据的合法性、有效性、完整性。

常见的约束

名称

说明

非空约束(not null)

约束的字段不能为NULL

唯一约束(unique)

约束的字段不能重复

主键约束(primary key)

约束的字段既不能为NULL,也不能重复(简称PK)

外键约束(foreign key)

用于限制两个表的关系,用于保证该字段的值必须来自于主表的关联列的值(简称FK)

检查约束(check)

注意Oracle数据库有check约束,但是mysql没有,目前mysql不支持该约束

非空约束(not null)

not null 修饰的字段,在给表插入数据的时候,不能为空。

create table t_user (
no bigint,
name varchar(255) not null
);
执行以下语句(name字段为空):
insert into t_user(no) values(1);

报错:
[SQL]insert into t_user(no) values(1);
[Err] 1364 - Field 'name' doesn't have a default value

也可以给not null字段添加默认值,这样就不会报以上错误:

create table t_user (
no bigint,
name varchar(255) default 'xxx' not null
);

注意:​not null​ 约束只有列级约束。没有表级约束。

唯一约束(unique)

unique 约束的字段不能重复。

1、设置编号是唯一的(列级约束:该约束只应用于相关的一列上):

create table t_user (
no bigint unique,
name varchar(255)
);
插入相同的编号:

insert into t_user(no,name) values (1,'小明');
insert into t_user(no,name) values (1,'小龙');

报错:
Error Code: 1062. Duplicate entry '1' for key 't_user.no'

2、给两个列或者多个列添加 unique(表级约束:可以应用在一个表中的多列上)

创建表,设置unique(no,name)

create table t_user(
no bigint,
name varchar(255),
password varchar(15),
unique(no,name)
);
执行以下代码:
insert into t_user(no,name) values (1,'小明');
insert into t_user(no,name) values (1,'小龙');
select * from t_user;

运行是没有错误的,上面建表语句结果unique(no,name)只有在no和name同时相同时才会报错:

但如下分别设置no和name为unique则并不是表级约束,只是两个列级约束,是会报错的:

drop table if exists t_user;
create table t_user(
no bigint unique,
name varchar(255) unique,
password varchar(15)
);
insert into t_user(no,name) values (1,'小明');
insert into t_user(no,name) values (1,'小龙');

主键约束( primary key )

主键约束:
添加了主键约束,主键字段中的数据不能为NULL,也不能重复。

主键约束、主键字段、主键值:
表中某个字段添加主键约束后,该字段被称为主键字段,主键字段中出现的每一个数据都被称为主键值;

(1) 添加主键 ​​primary key​​​ 的字段即不能重复也不能为空,效果不 ​​“not null nuique”​​​ 相同,但本质是不同的,添加主键约束后,主键不仅会有 ​​“not null unique”​​ 作用,而主键字段还会自劢添加“索引 — index”

(2)一张表应该有主键,若没有,表示这张表是无效的(第一范式要求任何一张表都应该有主键),“主键值”是当前行数据的唯一标识,“主键值”是当前行数据的身份证号;(即使表中两行数据完全相同,但是由于主键不同,也认为这是两行完全不同的数据)

一张表的主键约束只能有1个。

1、单一主键

单一主键:一张表中的一个字段作为主键。

建表,把编号设置为主键:

create table t_user(
no bigint primary key,
name varchar(255) unique
);
分别运行下面两段sql,都会报错:

insert into t_user(no,name) values (1,'小明');
insert into t_user(no,name) values (1,'小龙');

insert into t_user(name) values ('小龙');
测试得出:no是主键,因为添加了主键约束,主键字段中的数据不能为NULL,也不能重复。

使用表级约束方式定义主键:
create table t_user(
no bigint,
name varchar(255) unique,
primary key(no)
);

2、复合主键

drop table if exists t_user;
create table t_user(
no bigint,
name varchar(255),
primary key(no,name)
);
不是复合主键中的所有值都重复,就不算重复
这样是允许的:

insert into t_user(no,name) values (1,'小明');
insert into t_user(no,name) values (1,'小龙');
select * from t_user;

MySQL 常见约束_字段

3、自然主键和业务主键

自然主键:
主键值最好就是一个和业务没有任何关系的自然数。(这种方式是推荐的)

业务主键:
主键值和系统的业务挂钩,例如:拿着银行卡的卡号做主键,拿着身份证号码作为主键。(不推荐用)

最好不要拿和业务挂钩的字段作为主键。因为以后的业务一旦发生改变的时候,主键值可能也需要随着发生变化,但有的时候没有办法变化,因为变化可能会导致主键值重复。

4、MySQL 提供主键值自增(auto_increment)

建表,no字段从1开始,以1递增:

drop table if exists t_user;
create table t_user(
no bigint primary key auto_increment,
name varchar(255)
);
insert into t_user(name) values ('a');
insert into t_user(name) values ('b');
insert into t_user(name) values ('c');
insert into t_user(name) values ('d');
insert into t_user(name) values ('e');
select * from t_user;

外键约束(foreign key)

外键用来建立主表与从表的关联关系,为两个表的数据建立连接,约束两个表中数据的一致性和完整性。

外键约束、外键字段、外键值:给某个字段添加外键约束之后,该字段称为外键字段,外键字段中的数据称为外键值。

定义一个外键时,需要遵守下列规则:

父表必须已经存在于数据库中,或者是当前正在创建的表。如果是后一种情况,则父表与子表是同一个表,这样的表称为自参照表,这种结构称为自参照完整性。

必须为父表定义主键。

主键不能包含空值,但允许在外键中出现空值。也就是说,只要外键的每个非空值出现在指定的主键中,这个外键的内容就是正确的。

在父表的表名后面指定列名或列名的组合。这个列或列的组合必须是父表的主键或候选键。

外键中列的数目必须和父表的主键中列的数目相同。

外键中列的数据类型必须和父表主键中对应列的数据类型相同。

外键可以为NULL。

建立一个表,area_number 为1代表是中国地区,为0是海外地区:

drop table if exists t_user;
create table t_user(
no bigint primary key auto_increment,
name varchar(255),
area_number int(1),
area char(4)
);
insert into t_user(name,area,area_number) values('小明','中国地区',1);
insert into t_user(name,area,area_number) values('小龙','中国地区',1);
insert into t_user(name,area,area_number) values('Ana','海外地区',0);
insert into t_user(name,area,area_number) values('Jan','海外地区',0);
insert into t_user(name,area,area_number) values('Fak','海外地区',0);
insert into t_user(name,area,area_number) values('小法','中国地区',1);
select * from t_user;

MySQL 常见约束_mysql_02


可以很清楚地看出此表的缺点:数据太冗余!!

解决方法:我们可以借由两张表来维护这个用户信息。分别用用户表t_user和地区表t_area来存储数据。

drop table if exists t_user;
drop table if exists t_area;

create table t_area(
area_number int(1) primary key,
area char(4)
);
create table t_user(
no bigint primary key auto_increment,
name varchar(255),
a_number int(1),
foreign key(a_number) references t_area(area_number)
);

insert into t_area values (1,'中国地区'),(0,'海外地区');
insert into t_user(name,a_number) values ('小明',1), ('小龙',1),('Ana',0),('Jan',0),('Fak',0),('小法',1);

select * from t_area;
select * from t_user;

MySQL 常见约束_字段_03


通过两表操作,数据不再冗余。

找出用户的信息:

select u.*,a.* from t_user u join t_area a on u.a_number=a.area_number;

MySQL 常见约束_主键_04

此时t_area表叫做父表,t_user叫做子表。

父表和子表的操作顺序

删除数据的时候,先删除子表,再删除父表。
添加数据的时候,先添加父表,再添加子表。
创建表的时候,先创建父表,再创建子表。
删除表的时候,先删除子表,再删除父表。


标签:insert,name,no,常见,约束,area,user,MySQL,主键
From: https://blog.51cto.com/u_13571520/6046454

相关文章

  • MySQL 设计与开发规范
    阅读目录​​规范背景与目的​​​​设计规范​​​​数据库设计​​​​库名​​​​表结构​​​​列数据类型优化​​​​索引设计​​​​分库分表、分区表​​​​字符......
  • MySQL设置当前默认时间
    ​​CURRENT_TIMESTAMP​​......
  • MySQL查询一年、一周、三个月的数据
    阅读目录DATE_SUB()函数从日期减去指定的时间间隔DATE_SUB()函数从日期减去指定的时间间隔语法:DATE_SUB(date,INTERVALexprtype)date参数是合法的日期表达......
  • MySQL中 any,some,all 的用法
    阅读目录一、any,some,allall逻辑运算符any和some运算符一、any,some,allany,some,all是MySQL当中的逻辑运算符,作用是将子查询返回的单列值的集合与查询......
  • MySQL查询某天的数据
    阅读目录1、DATE_FORMAT()函数用于以不同的格式显示日期/时间数据2、DATEDIFF()函数返回两个日期之间的天数扩展知识1、DATE_FORMAT()函数用于以不同的格式......
  • MySQL给查询加序号
    阅读目录数据表MySQL给查询加序号解释说明相关知识点数据表DROPTABLEIFEXISTStb_score;CREATETABLEtb_score(idINT(11)NOTNULLauto_incr......
  • MySQL中 replace 替换字符
    阅读目录语法:replace(field,search,replace)说明:field-数据库表的列名search-需要替换的字符串replace-替换成的字符串语义:将列名:field中出现......
  • MySQL查看库中所有表的大小和记录数
    阅读目录说明说明TABLE_NAME:表名字;DATA_LENGTH:数据大小;INDEX_LENGTH:索引大小;TABLE_ROWS:记录数量;TABLE_SCHEMA:数据库名字;ENGINE:所使用的存储引擎;......
  • MySQL的数据结构
    阅读目录MySQL数据结构用b+tree做的为什么不用红黑树叉树呢?什么是B-Tree(B-树)?什么是B+Tree?B+Tree相对于B-Tree的几点不同MySQL数据结构用b+tree......
  • MySQL数据行怎么转为列
    阅读目录行转列1、使用case...when....then进行行转列2、使用IF()进行行转列3、利用SUM(IF())生成列+WITHROLLUP生成汇总行,并利用IFNULL将汇总行标......