MySQL表约束和表设计

目录

1. 数据库约束 

1.1 什么是表约束

1.2 为什么需要表约束

1.3 常见约束

1.3.1 非空约束 not null

1.3.2 唯一约束 unique

1.3.3 主键约束  primary key

1.3.4 外键约束 foreign key 

 1.3.5 检查约束 check(了解)

1.3.6 自增约束 auto_increment

 1.3.7 默认约束 default

1.3.8 insert ... select

2.表设计

2.1 数据库设计三范式

2.1.1 第⼀范式(确保每列保持原子性) 

2.1.2 第⼆范式(确保表中的每列都和主键相关)

2.1.3 第三范式(确保每列都和主键列直接相关,而不是间接相关) 

2.2 表关系


1. 数据库约束 

1.1 什么是表约束

        表约束是在创建表的时候,设计⼀些表的约束条件,⽤来保证数据的合法性和数据的正确性。
        例如⼀个账号只能绑定⼀个⼿机号,那么⼿机号就不能重复,不能被多个账号绑定使⽤,所以它应该设置唯⼀约束。⽽主键是⽤来标识数据的,因此它不能为 NULL,也不能为空,所以他需要设置⾮空约束或(主键约束,主键约束也不能为 NULL)。

1.2 为什么需要表约束

就像法律是⽤来规范⼈们的正确⾏为的⼀样,表约束也是为了规范程序员正确使⽤表的,但表约束是预先设置的,设置之后就对所有插⼊和修改⽴即⽣效,⽐如⾮空约束设置好之后,如果添加和修改为NULL 值就会报错,这点是和法律有细微的不同。如果没有表约束,会导致数据不正确,从⽽导致程序或现实中的业务⽆法推进和执⾏。

1.3 常见约束

常⻅的表约束如下表:

约束 说明
NOT NULL ⾮空约束,指示某列不能存储 NULL 值
UNIQUE 唯⼀约束,保证某列的每⾏必须有唯⼀的值
PRIMARY KEY 主键约束,确保某列(或两个列多个列的结合)有唯⼀标识,有助于
更容易更快速地找到表中的⼀个特定的记录。
FOREIGN KEY 外键约束,保证⼀个表中的数据匹配另⼀个表中的值的参照完整性。
CHECK 检查约束, 保证列中的值符合指定的条件。对于MySQL数据库,对
CHECK⼦句进⾏分析,但是忽略CHECK⼦句。
AUTO_INCREMENT ⾃增约束,插⼊可忽略此字段,此字段会⾃⼰增加存储数值。默认是从 1
开始,每次递增 1。
DEFAULT 默认值约束, 规定没有给列赋值时的默认值。

1.3.1 非空约束 not null

语法:

create table table_name(字段名 数据类型 not null [,...]);

例如,给id和name加上非空约束 :

 

插入null值,会报错:

查看非空约束:

使用desc table_name 来查询,NO表示添加了非空约束,YES表示未添加非空约束。

 

1.3.2 唯一约束 unique

 语法:

create table table_name (字段名 数据类型 unique [,...]);

例如,给id加上唯一约束:

 添加两条id相同的数据:

此时就会发生错误,无法添加。

注意:

  • 一张表中可以有一个或多个唯一约束;
  • 唯一约束字段可以插入NULL值;
  • 唯一约束字段的NULL可以插入多个.

查看一张表的唯一约束:

1.3.3 主键约束  primary key

        主键是可以⽤来表示⼀张表中某条数据的代表凭证,例如对于“⼈”这张表来说,唯⼀的身份证就可以作为主键来代表这个⼈,“姓名”不⾏,因为姓名有可能会重复。

主键的特征:

  1. 主键可以由多个字段或单个字段组成。
  2. 主键不能为空且且唯⼀。
  3. ⼀个表中只能有⼀个主键。

语法1:独立主键

create table table_name (字段名 数据类型 primary key [,...]);

示例:

语法2:联合主键

create table table_name (
    字段1 数据类型,
    字段2 数据类型
    [,...],
    primary key(字段1,字段2[,...])
);
    

示例:

 主键约束 VS 唯⼀约束:

  • 主键约束⼀个表只能有⼀个,⽽唯⼀约束可以有多个;
  • 主键约束不能有 null 值,⽽唯⼀约束可以有 null(唯⼀索引可以有多个 null)。

1.3.4 外键约束 foreign key 

外键⽤于关联其他表的主键唯⼀键语法: 

foreign key (字段名) references 主表(列)

示例:创建班级表classes,id为主键:

创建班级表,有使用MySQL关键字作为字段时,需要使用``来标识

创建学生表student,一个学生对应一个班级,一个班级对应多个学生。使用id为主键,classes_id为外键,关联班级表id

 1.3.5 检查约束 check(了解)

语法:

check (<检查约束>)

示例: 

 特殊说明:检查约束在MySQL 8.0.16才可以使用,在MySQL 8.0.15以前不能使用。

1.3.6 自增约束 auto_increment

 语法:

create table table_name(
    id int primary key auto_increment,
    name varchar(250)
);

示例:

 插入两个name:

 使用 show create table 表名 可以查看当前的自增值:

 当给自增列插入null时,他的执行逻辑和不设置是一样的:

自增也可以手动指定值:

  

 ⾃增值可以在创建表的时候⼿动指定:

修改自增值:

 使⽤ alter table table_name auto_increment=n,可修改⾃增值为n

 注意:

  • 一个表中只能有一个自增列;
  • ⾃增列的字段类型只能为整数类型(TINYINT、SMALLINT、INT、BIGINT 等);
  • auto_increment 必须配合 key ⼀起使⽤,这个 key 可以是 primary key,foreign key,如果没有 key就会报错;
  •  唯⼀列可以为⾃增列:
  • auto_increment 的值只能设置⽐⽬前存储的最⼤值⼤,否则设置不会⽣效。

 delete 和 truncate 重置自增验证:

delete删除不会重置自增值:

 truncate删除重置自增值:

 1.3.7 默认约束 default

默认约束是给没有给列赋值时的默认值,语法如下:

字段 数据类型 default 默认值

示例:

1.3.8 insert ... select

2.表设计

2.1 数据库设计三范式

2.1.1 第⼀范式(确保每列保持原子性) 

        第⼀范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原⼦值,就说明该数据库表满⾜了第⼀范式。第⼀范式的合理遵循需要根据系统的实际需求来定。⽐如某些数据库系统中需要⽤到“地址”这个属性,本来直接将“地址”属性设计成⼀个数据库表的字段就⾏。但是如果系统经常会访问“地址”属性中的“城市”部分,那么就⾮要将“地址”这个属性重新拆分为省份、城市、详细地址等多个部分进⾏存储,这样在对地址中某⼀部分操作的时候将⾮常⽅便。这样设计才算满⾜了数据库的第⼀范式,如下表所示。

上表所示的⽤户信息遵循了第⼀范式的要求,这样在对⽤户使⽤城市进⾏分类的时候就⾮常⽅便,也提⾼了数据库的性能。

2.1.2 第⼆范式(确保表中的每列都和主键相关)

        第⼆范式在第⼀范式的基础之上更进⼀层。第⼆范式需要确保数据库表中的每⼀列都和主键相关,⽽不能只与主键的某⼀部分相关(主要针对联合主键⽽⾔)。也就是说在⼀个数据库表中,⼀个表中只能保存⼀种数据,不可以把多种数据保存在同⼀张数据库表中。
         ⽐如要设计⼀个订单信息表,因为订单中可能会有多种商品,所以要将订单编号和商品编号作为数据库表的联合主键,如下表所示。

         

        这样就产⽣⼀个问题:这个表中是以订单编号和商品编号作为联合主键。这样在该表中商品名称、单位、商品价格等信息不与该表的主键相关,⽽仅仅是与商品编号相关。所以在这⾥违反了第⼆范式的设计原则。⽽如果把这个订单信息表进⾏拆分,把商品信息分离到另⼀个表中,把订单数量表也分离到另⼀个表中,就⾮常完美了。如下所示。
 

这样设计,在很⼤程度上减⼩了数据库的冗余。如果要获取订单的商品信息,使⽤商品编号到商品信息表中查询即可。

2.1.3 第三范式(确保每列都和主键列直接相关,而不是间接相关) 

         第三范式需要确保数据表中的每⼀列数据都和主键直接相关,⽽不能间接相关。⽐如在设计⼀个订单数据表的时候,可以将客户编号作为⼀个外键和订单表建⽴相应的关系。⽽不可以在订单表中添加关于客户其它信息(⽐如姓名、所属公司等)的字段。
        如下⾯这两个表所示的设计就是⼀个满⾜第三范式的数据库表。不符合第三范式:

 正确的表结构:

         

这样在查询订单信息的时候,就可以使⽤客户编号来引⽤客户信息表中的记录,也不必在订单信息表中多次输⼊客户信息的内容,减⼩了数据冗余。

2.2 表关系

表和表之间的关系有三种:

  1. ⼀对⼀:⼀个学⽣对应⼀个学号;
  2. ⼀对多:⼀个班级包含多个学⽣(⽤两张表表示);
  3. 多对多:⼀张表中的⼀条数据可以对应到另⼀张表的多条数据,反之也是这样的,这样的关系叫做多对多,⼀般⽤三个表表示。

一对一:

一对多:

多对多:

猜你喜欢

转载自blog.csdn.net/m0_59140023/article/details/123227063