深入Mysql-03-MySQL 表的约束与数据库设计

news2024/11/14 19:01:44

文章目录

  • 数据库约束的概述
    • 约束种类
      • 主键约束
      • 唯一约束
      • 非空约束
      • 默认值
      • 外键约束
  • 表与表之间的关系
  • 数据库设计

数据库约束的概述

对表中的数据进行限制,保证数据的正确性、有效性和完整性。一个表如果添加了约束,不正确的数据将无法插入到表中。

约束种类

约束名约束关键字
主键primary key
唯一unique
非空not null
外键foreign key
检查约束check 注:mysql 不支持

主键约束

用来唯一标识数据库中的每一条记录

  • 主键是给数据库和程序使用的,不是给最终的客户使用的。所以主键有没有含义没有关系,只要不重复,非空就行。

创建主键:

  1. 在创建表的时候给字段添加主键
    字段名 字段类型 PRIMARY KEY
  2. 在已有表中添加主键
    ALTER TABLE 表名 ADD PRIMARY KEY(字段名);

代码示例:

create table stu (
	id int primary key,
	name varchar(20),
	age int
)

在这里插入图片描述
删除主键约束:
alter table stu drop primary key;
在这里插入图片描述
在这里插入图片描述
主键自增:
主键如果让我们自己添加很有可能重复,我们通常希望在每次插入新记录时,数据库自动生成主键字段的值
将stu表中的主键进行添加操作:
alter table stu add primary key(id)
在这里插入图片描述
添加主键自增操作:
ALTER TABLE stu MODIFY id INT AUTO_INCREMENT;
插入几条数据看看效果:

-- 插入数据
insert into stu (name,age) values ('小乔',18); 
insert into stu (name,age) values ('大乔',20);
-- 另一种写法
insert into stu values(null,'周瑜',35);

在这里插入图片描述
可以看到我们的主键id字段是逐渐递增的。

修改自增长的默认值起始值:

  • 创建表时指定起始值
CREATE TABLE 表名(
	列 名 int primary key AUTO_INCREMENT
) AUTO_INCREMENT=起始值;
-- 指定起始值为 1000 
create table stu1 (
  id int primary key auto_increment, 
  name varchar(20)
) auto_increment = 1000;

insert into stu1 values (null, '孔明');
select * from stu1;

在这里插入图片描述

  • 创建好以后修改起始值
ALTER TABLE 表名  AUTO_INCREMENT=起始值;
alter table stu1 auto_increment = 2000;
insert into stu1 values (null, '刘备');

在这里插入图片描述
注意: delete删除的记录对自增长没有影响,但是使用truncate删除记录时,自增长会重新开始。

唯一约束

表中某一列不能出现重复的值

字段名 字段类型 UNIQUE
  • 创建一个stu2表
create table stu2 (
	id int,
	name varchar(20) unique
)
  • 插入一条数据
insert into stu2 values (1, '张三');
  • 插入一条同样的数据
insert into stu2 values (1, '张三');

在这里插入图片描述
出现了错误: Duplicate entry '张三' for key 'name'

非空约束

某一列不能为 null

字段名 字段类型  NOT NULL
  • 创建一个stu3表
create table stu3(
	id int,
	name varchar(20) not null, gender char(1)
)
  • 添加一个数据
insert into stu3 values (1,'张三疯','男');
  • 添加一个name为null的数据
insert into stu3 values (2,null,'男');

出现了错误:Column 'name' cannot be null

默认值

字段名 字段类型  DEFAULT 默认值
  • 创建一个stu4表
create table stu4 ( 
	id int,
	name varchar(20),
	address varchar(20)	default '广州'
)
  • 添加一条默认地址数据
insert into stu4 values (1, '李四', default); 
  • 添加一个非默认地址的数据
insert into stu4 values (3, '李四光', '深圳');

在这里插入图片描述

外键约束

创建一个员工表emp

CREATE TABLE emp (
 id INT PRIMARY KEY AUTO_INCREMENT,
 NAME VARCHAR(30),
 age INT,
 dep_name VARCHAR(30),
 dep_location VARCHAR(30)
);

-- 添加数据
INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('张三', 20, '研发部', '广州');
INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('李四', 21, '研发部', '广州'); 
INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('王五', 20, '研发部', '广州');
INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('老王', 20, '销售部', '深圳'); 
INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('大王', 22, '销售部', '深圳'); 
INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('小王', 18, '销售部', '深圳');

在这里插入图片描述
出现了大量冗余数据,解决方案就是进行分表

  1. 创建一个部门表
create table department(
	id int primary key auto_increment,
	dep_name varchar(20),
	dep_location varchar(20)
);
  1. 创建一个员工表
-- 创建员工表(id,name,age,dep_id)
-- 多方,从表
create table employee(
	id int primary key auto_increment,
	name varchar(20),
	age int,
	dep_id int	-- 外键对应主表的主键
)
  1. 添加俩个部门
insert into department values(null, '研发部','广州'),(null, '销售部', '深圳'); 
  1. 添加一些员工
INSERT INTO employee (NAME, age, dep_id) VALUES ('张三', 20, 1);
INSERT	INTO	employee	(NAME,	age,	dep_id)	VALUES	('李四',	21,	1);
INSERT	INTO	employee	(NAME,	age,	dep_id)	VALUES	('王五',	20,	1);
INSERT	INTO	employee	(NAME,	age,	dep_id)	VALUES	('老王',	20,	2);
INSERT	INTO	employee	(NAME,	age,	dep_id)	VALUES	('大王',	22,	2);
INSERT	INTO	employee	(NAME,	age,	dep_id)	VALUES	('小王',	18,	2);
  1. 查询员工和部门
    在这里插入图片描述
    在这里插入图片描述
    这里我们可以看到部门id对应有部门信息,但是这里我们可以查润一条当前部门表不存在的id数据,这就要通过外键约束来解决了。
  • 创建表的时候添加外键: [CONSTRAINT] [外键约束名称] FOREIGN KEY(外键字段名) REFERENCES 主表名(主键字段名)
  • 已有表增加外键:ALTER TABLE 从表 ADD [CONSTRAINT] [外键约束名称] FOREIGN KEY (外键字段名) REFERENCES 主表(主键字段名);

这里我们已经创建了表,那么我们使用第二种方式来创建外键约束。

alter table employee add constraint emp_depid_fk foreign key (dep_id) references department(id)

在这里插入图片描述
这里可以看到当我们赋予外键约束的时候无法创建出部门表里面没有的id记录。

删除外键:

ALTER TABLE 从表  drop foreign key 外键名称;
-- 删除 employee 表的 emp_depid_fk 外键
alter table employee drop foreign key emp_depid_fk;

外键的级联:
重新添加外键约束:

alter table employee add constraint emp_depid_fk foreign key (dep_id) references department(id);

当我们想改以下部门表的id时,会出现如图问题。
在这里插入图片描述
因此我们需要进行级联操作(在修改和删除主表的主键时,同时更新或删除副表的外键值)。

级联操作语法描述
ON UPDATE CASCADE级联更新,只能是创建表的时候创建级联关系。更新主表中的主键,从表中的外键列也自动同步更新
ON DELETE CASCADE级联删除

示例:


drop table employee;

create table employee(
id int primary key auto_increment, name varchar(20),
age int,
dep_id int,	-- 外键对应主表的主键
-- 创建外键约束
constraint emp_depid_fk foreign key (dep_id) references department(id) on update cascade on delete cascade
)

INSERT INTO employee (NAME, age, dep_id) VALUES ('张三', 20, 1);
INSERT INTO employee (NAME, age, dep_id) VALUES ('李四', 21, 1); 
INSERT INTO employee (NAME, age, dep_id) VALUES ('王五', 20, 1);

INSERT INTO employee (NAME, age, dep_id) VALUES ('老王', 20, 2); 
INSERT INTO employee (NAME, age, dep_id) VALUES ('大王', 22, 2); 
INSERT INTO employee (NAME, age, dep_id) VALUES ('小王', 18, 2);

这时,我们对部门表进行删除操作。

drop table department;

在这里插入图片描述
出现了错误,无法删除或更新父行:外键约束失败。
我们对部门表进行更新操作来检测级联更新是否成功。

update department set id=10 where id=1; 

在这里插入图片描述
在这里插入图片描述
这里我们可以看到所有的id等于1的都被修改为10了。
最后我们删除部门号为10的来检测我们的级联删除是否成功。

delete from department where id=10;

在这里插入图片描述
可以看到我们的级联删除约束也是成功的。

表与表之间的关系

表与表之间的三种关系
一对多:最常用的关系 部门和员工(一个部门有多个员工)
多对多:学生选课表和学生表, 一门课程可以有多个学生选择,一个学生选择多门课程
一对一:相对使用比较少。员工表 简历表, 公民表 护照表

数据库设计

  1. 数据规范化
    建立科学的,规范的数据库就需要满足一些规则来优化数据的设计和存储,这些规则就称为范式。
  2. 三大范式
    目前关系数据库有六种范式: 第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。
  • 1NF: 第一范式每一列不可再拆分,称为原子性。
  • 2NF: 第二范式就是在第一范式的基础上所有列完全依赖于主键列。
  • 3NF: 任何非主列不得传递依赖于主键。

欢迎java热爱者了解文章,作者将会持续更新中,期待各位友友的关注和收藏,另外对编程感兴趣的友友们可以加以下群共同学习。群号:127871664

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1944747.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java实现OCR图片识别,RapidOcr开源免费

先看一下识别效果(自我感觉很牛逼),比Tess4J Tesseract省事,这个还需要训练,安装软件、下载语言包什么的 很费事,关键识别率不高 RapidOcr不管文字的横竖,还是斜的都能识别(代码实现…

鸿蒙开发仓颉语言【在工程中使用Hyperion TCP框架】

3. 在工程中使用Hyperion TCP框架 3.1 导入Hyperion TCP框架的静态库 在工程的module.json中引入Hyperion TCP框架的静态库: "package_requires": {"package_option": {"hyperion_hyperion.buffer": "${path_to_hyperion_proj…

SpringBoot整合SSE技术详解

Hi 👋, Im shy SpringBoot整合SSE技术详解 1. 引言 在现代Web应用中,实时通信变得越来越重要。Server-Sent Events (SSE)是一种允许服务器向客户端推送数据的技术,为实现实时更新提供了一种简单而有效的方法。本文将详细介绍如何在SpringBoot中整合SSE,并探讨S…

java之回合制游戏以及如何优化

public class Role {private String name;private int blood;//空参public Role() {}//包含全部参数的构造public Role(String name, int blood) {this.name name;this.blood blood;}public String getName() {return name;}public void setName(String name) {this.name na…

单细胞生物都能学会的树莓派4B实现路由器

本文参考自CSDN用户羟基氟化宇的畅玩树莓派4B(二)树莓派搭建无线路由器(支持5GWIFI) 本文补充其中的细节及遇到的问题。 本文提及的代码,均需在树莓派终端中运行。 〇、硬件准备 树莓派4B一个、网线一根。 &#xff…

【NoSQL数据库】Redis学习笔记

一、缓存穿透 缓存穿透是先查Redis,发现缓存中没有数据,再查数据库。然而,如果查询的数据在数据库中也不存在,那么每次查询都会绕过缓存,直接落到数据库上。 解决方案一、缓存空数据 查询Redis缓存:首先查…

前后端分离项目部署,vue--nagix发布部署,.net--API发布部署。

目录 Nginx免安装部署文件包准备一、vue前端部署1、修改http.js2、npm run build 编译项目3、解压Nginx免安装,修改nginx.conf二、.net后端发布部署1、编辑appsetting.json,配置跨域请求2、配置WebApi,点击发布3、配置文件发布到那个文件夹4、配置发布相关选项5、点击保存,…

中电金信:AI数据服务

01 方案简介 AI数据服务解决方案为泛娱乐、电子商务、交通出行等行业提供数据处理、数据分析、AI模型训练等服务,通过自主研发的IDSC自动化数据服务平台与客户业务流程无缝衔接,实现超低延时的实时数据处理支持。 02 应用场景 智能医疗: 通…

Ribbon负载均衡与内核原理

什么是Ribbon? 目前主流的负载方案分为两种: 集中式负载均衡,在消费者和服务提供方中间使用独立的代理方式进行负载,有硬件的(比如F5),也有软件的(Nginx)客户端根据自己的请求做负…

transformers进行学习率调整lr_scheduler(warmup)

一、get_scheduler实现warmup 1、warmup基本思想 Warmup(预热)是深度学习训练中的一种技巧,旨在逐步增加学习率以稳定训练过程,特别是在训练的早期阶段。它主要用于防止在训练初期因学习率过大导致的模型参数剧烈波动或不稳定。…

力扣经典题目之->设计循环队列 的超详细讲解与实现

一:题目 二:思路讲解 前提: a:本文采取数组来实现队列去解决题目 b:开辟k1个空间,front指向队首,rear指向队尾的后一个,rear这样会更好的判空和判满 以下根据pop和push感受满和空…

python如何调用matlab python package库matlab转python安装包调用使用简单示例

说明(废话) 之前没有进行python调用过matlab,前面用matlab engine for python可以通过调用matlab的源码文件的形式可以调用工程,但是这又有一个问题,就是在运行的时候必须提供python和matlab的全部源码 该文章是通过matlab源码转python pack…

FPGA JTAG最小系统 EP2C5T144C8N

FPGA的文档没有相应的基础还真不容易看懂,下面是B站上对FPGA文档的解读(本文非对文档解读,只是为个人记录第三期:CycloneIV E最小系统板设计(一)从Datasheet上获取FPGA的基本参数_哔哩哔哩_bilibili 电源部份 核心电…

PlantUML 语法、图标和示例

基本语法 关键字 声明参与者的几个关键字 actor、boundary、control、entity、database、collections、participant 箭头样式 我们可以通过,修改箭头样式,来表达不一样的意思: 表示一条丢失的消息:末尾加 x让箭头只有上半部…

[UE 虚幻引擎] DTHmacSha 蓝图HMACSHA加密算法插件说明

本插件可以在虚幻引擎中使用蓝图对字符串和文件进行HMACSHA加密。 1.节点说明 HMACSHA一共有5种加密方式,分辨是 HMAC SHA-1, HMAC SHA-224,HMAC SHA-256,HMAC SHA-384,HMAC SHA-512。 本插件对每种加密方式提供3个节点…

C++初学者指南-6.函数对象--函数对象

C初学者指南-6.函数对象–函数对象 文章目录 C初学者指南-6.函数对象--函数对象函数对象示例:区间查询区间内的查找区间划分(分组) 指南标准库函数对象比较算术运算 函数对象 提供至少一个成员函数重载 operator() 的对象 class Multiplier {int m_; public:// cons…

MATLAB绘制方波、锯齿波、三角波、正弦波和余弦波、

一、引言 MATLAB是一种具有很强的数值计算和数据可视化软件,提供了许多内置函数来简化数学运算和图形的快速生成。在MATLAB中,你可以使用多种方法来快速绘制正弦波、方波和三角波。以下是一些基本的示例,展示了如何使用MATLAB的命令来实现正弦…

centos系统mysql主从复制(一主一从)

文章目录 mysql80主从复制(一主一从)一、环境二、服务器master1操作1.开启二进制日志2. 创建复制用户3. 服务器 slave1操作4. 在主数据库中添加数据 mysql80主从复制(一主一从) 一、环境 准备两台服务器,都进行以下操…

入门C语言Day15——关系条件逻辑操作符

今天来学习操作符中的一些内容,主要讲的是关系&条件&逻辑操作符 1.关系操作符 首先要来了解一下什么是关系操作符,关系操作符其实就是关系运算符,关系运算符又和关系表达式有关。 C语言中用于比较的表达式,就被称为 “关…

google、windows自带语音识别中英文等实时字幕使用

2、自带实时字幕 1)google浏览器自带 实时字幕 设置里可以设置: 有视频声音播放会弹出黑色文本框 下载其他语言包-比如中文: 测试 2)windows11 辅助功能 实时字幕 (直接快捷键打开:Win Ctrl L&#…