【MySQL】(3)约束

news2025/1/18 17:03:59

文章目录

  • 表的约束
    • 空属性
    • 默认值
    • 列描述
    • zerofill
    • 主键
      • 概念
      • 使用 alter 添加和删除主键
      • 联合主键
      • 如何设计主键
    • 自增长
    • 唯一键
    • 外键

表的约束

所谓约束,就是不让你做某事,约束的存在,有助于程序员和用户合法合理地使用数据库。

数据类型其实就是对字段的一种约束,但是数据类型约束很单一,需要有一些额外的约束,从而更好地保证数据的合法性。

表的约束有很多,这里主要介绍如下几个:null/not null default comment zerofill primary key auto_increment unique key

空属性

  • null 该列可以为空
  • not null 该列不可以为空
  • 数据库字段默认都是可以为空的,但是实际开发时,会约束某些字段不能为空,以保证这些字段能够参与运算。

例如,以下 SQL 语句可以创建一个名为 students 的表,其中包含三列,分别是 idnameage

CREATE TABLE students (
  id INT NOT NULL,
  name VARCHAR(50) NOT NULL,
  age INT NOT NULL
);

每列都有一个 NOT NULL 约束,因此在插入新行时,这些列必须都包含一个非空值。

img

默认值

某一种数据会经常性的出现某个具体的值,可以在一开始就指定好一个默认值

DEFAULT 关键字,用于指定一个列的默认值。

默认值可以是任何合法的表达式,包括字面量(如字符串或数字),函数调用或子查询等。

CREATE TABLE orders (
  id INT NOT NULL,
  item VARCHAR(50) NOT NULL,
  quantity INT NOT NULL DEFAULT 1
);

在这个例子中,如果在插入新行时未提供 quantity 列的值,则该列将自动设置为 1

img

列描述

comment ,用于为表、列或索引添加注释或描述。注释可以用于提供更多的文档或说明,以帮助理解表、列或索引的目的或用途。

COMMENT 关键字可以在创建表或列时使用,也可以在修改表或列时使用。

  1. 在创建表时添加注释:

    CREATE TABLE users (
      id INT NOT NULL COMMENT '用户ID',
      name VARCHAR(50) NOT NULL COMMENT '用户名',
      email VARCHAR(255) NOT NULL COMMENT '电子邮件',
      PRIMARY KEY (id)
    ) COMMENT '用户表';
    

    在这个例子中,COMMENT 关键字被用于为整个 users 表添加注释,以及为 idnameemail 列添加注释。

  2. 在修改表时添加注释:

    ALTER TABLE users COMMENT '这是用户表';
    

使用 SHOW CREATE TABLE 命令(desc 不行)可以查看表的详细信息,包括注释信息。例如:

img

zerofill

ZEROFILL 是一个列属性,用于在显示整数时填充前导零。

当列定义为 ZEROFILL 时,如果列中的值不足指定的位数,则在数字前面添加零以填充空白。这可以使数字在输出中对齐,以便更容易地读取和比较。

CREATE TABLE users (
  id INT(5) ZEROFILL NOT NULL,
  name VARCHAR(50) NOT NULL,
  PRIMARY KEY (id)
);

在这个例子中,id 列被定义为 INT(5) ZEROFILL,意味着它是一个整数列,最多有 5 个数字,并且在数字前填充前导零。例如,如果插入 id=1 的行,则在输出时会显示为 00001。同样,如果插入 id=123 的行,则在输出时会显示为 00123

注意,使用 ZEROFILL 属性只会在输出时填充前导零,而不会影响存储在列中的实际值。因此,在插入或更新行时,必须确保提供正确的整数值,而不是包含前导零的字符串值。

int 后的 () 里的数字就是专门为 zerofill 服务的,如果没有 zerofill,那么 () 里的数字是没有意义的。

主键

概念

在关系型数据库中,主键(Primary Key)是一种用于唯一标识表中每行记录的特殊列或集合。主键的值必须在表中是唯一的,并且不能为空。

也就是说,一张表最多只能有一个主键,而一个主键可以有多个列,这种主键也叫联合主键(Composite Primary Key),也就是将多个列作为一个主键来唯一标识一张表中的每个记录。

CREATE TABLE users (
  id INT NOT NULL AUTO_INCREMENT,
  name VARCHAR(50) NOT NULL,
  email VARCHAR(255) NOT NULL,
  PRIMARY KEY (id) -- 写法1:PRIMARY KRY(列名)
);
CREATE TABLE users (
  id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, -- 写法2:直接写在约束列表
  name VARCHAR(50) NOT NULL,
  email VARCHAR(255) NOT NULL,
);

id 列定义为一个自增的整数列,它是表 users 的主键。因此,每行记录都有一个唯一的 id 值,可以通过该值来标识该行。PRIMARY KEY 关键字用于指定 id 列作为主键。

AUTO_INCREMENT 是用于指定一个整数列为自增列的关键字。当在表中插入一条新记录时,MySQL 会自动为这个自增列分配一个唯一的值,该值会比上一条记录的值大 1。这样,每个新插入的记录都有一个唯一的标识符,防止出现重复值,通常用于表的主键列。

主键的作用是在表中唯一标识每行记录,使得每行记录都可以轻松地进行增、删、改、查操作。主键还可以用于定义表之间的关系,例如外键约束。另外,主键还可以用于提高查询性能,因为 MySQL 在查询主键时可以使用索引,从而更快地查找和检索数据。这些将在后面的内容中详细讲解。

使用 alter 添加和删除主键

-- 添加主键
ALTER TABLE 表名 ADD PRIMARY KEY (列名);

-- 删除主键
ALTER TABLE 表名 DROP PRIMARY KEY;

尽量在建表的时候就把表的主键设置好,而不是已经有数据了再使用 alter 添加或删除主键。

联合主键

当一个表中单个列都不能唯一地标识一条记录时,可以使用联合主键来指定多个列组合成一个主键,以确保记录的唯一性。下面是一个使用联合主键的例子。

假设我们有一个 orders 表,用于存储客户订单的数据。每个订单由多个商品组成,因此每个订单可能有多条记录,每条记录表示一个商品。为了保证记录的唯一性,我们可以将 order_idproduct_id 两列作为联合主键,这样每个订单中的商品组合就是唯一的。

CREATE TABLE orders (
  order_id INT NOT NULL,
  product_id INT NOT NULL,
  quantity INT NOT NULL,
  price DECIMAL(10,2) NOT NULL,
  PRIMARY KEY (order_id, product_id)
);

在上面的语句中,我们指定了 order_idproduct_id 两列组合成一个主键,这样每个订单中的商品组合就是唯一的。在插入数据时,我们需要同时指定这两列的值:

INSERT INTO orders (order_id, product_id, quantity, price)
VALUES (1001, 1, 2, 19.99);

INSERT INTO orders (order_id, product_id, quantity, price)
VALUES (1001, 2, 1, 29.99);

INSERT INTO orders (order_id, product_id, quantity, price)
VALUES (1002, 1, 3, 19.99);

INSERT INTO orders (order_id, product_id, quantity, price)
VALUES (1002, 3, 2, 49.99);

如何设计主键

  1. 结合业务,选择一个唯一的列属性作为主键
  2. 特定设计一个与业务无关列(如:id)

自增长

自增长(Auto-Increment)是一种用于生成唯一标识符的技术,常用于数据库中表的主键列。在 MySQL 中,可以使用 AUTO_INCREMENT 关键字来为整数列设置自增长属性。

当将 AUTO_INCREMENT 关键字应用于表的列时,该列的值会自动递增。当插入新行时,可以不指定该列的值,MySQL 会自动为该列生成唯一的值,以确保每个记录都具有唯一标识符。

自增长的特点:

  • 自增长的列必须是整数类型
  • 列必须是一个键(Key)或一部分键,通常是主键(Primary Key)或唯一键(Unique Key),以确保每个值都是唯一的。
  • 一张表最多只能有一个自增长

CREATE TABLE users (
  id INT NOT NULL AUTO_INCREMENT,
  name VARCHAR(50) NOT NULL,
  email VARCHAR(255) NOT NULL,
  PRIMARY KEY (id)
);

INSERT INTO users (name, email) VALUES
  ('Alice', 'alice@example.com'),
  ('Bob', 'bob@example.com'),
  ('Charlie', 'charlie@example.com'),
  ('David', 'david@example.com'),
  ('Eve', 'eve@example.com'),
  ('Frank', 'frank@example.com');
MariaDB [test_db]> select * from users;
+----+---------+---------------------+
| id | name    | email               |
+----+---------+---------------------+
|  1 | Alice   | alice@example.com   |
|  2 | Bob     | bob@example.com     |
|  3 | Charlie | charlie@example.com |
|  4 | David   | david@example.com   |
|  5 | Eve     | eve@example.com     |
|  6 | Frank   | frank@example.com   |
+----+---------+---------------------+
6 rows in set (0.00 sec)

注意

  1. 自增列的值是在当前表的最大值基础上加1,也就是说,如果你显式的插入一个1000是当前最大的值,下一个插入的值如果不指定,默认就是1001.
  2. 手动修改自增列的初始值
ALTER TABLE t1 AUTO_INCREMENT = 1000;

唯一键

唯一键(Unique Key)是一种用于保证表中某个列或列组的值唯一的约束条件。与主键类似,唯一键也可以用来标识表中的每个记录,但是它可以包含空值(NULL)。

与主键不同的是,一个表可以有多个唯一键,而每个唯一键可以包含多列。这意味着,唯一键可以由多个列组合而成,以确保这些列的组合值在表中是唯一的。

以下是一个创建带有唯一键的表的示例 SQL 语句:

CREATE TABLE users (
  id INT PRIMARY KEY,
  email VARCHAR(255) UNIQUE,
  name VARCHAR(50) NOT NULL
);

在上面的语句中,我们为 email 列设置了唯一键,以确保每个邮件地址在表中只出现一次。如果尝试插入一个已经存在的邮件地址,则会导致插入失败。

总的来说,主键和唯一键都用来保证数据行的唯一性,但主键是一种特殊的唯一键,用来唯一地标识一条数据记录

唯一键只是用于保证某些列的值唯一性的情况,如邮件地址、身份证号码等。

外键

在一个关系型数据库中,数据通常被分散到不同的表中,而这些表之间又有一些关联关系。例如,一个订单可能会包含多个产品,而每个产品的信息则存储在不同的表中。这时候就可以使用外键来约束这些表之间的关系。

外键(Foreign Key)是一种用于在关系型数据库中建立关系的机制。它用于定义主表和从表之间的关系,维护主表和从表间的约束。外键约束定义在从表上,主表必须有主键或唯一键。

通过将一个表中的列与另一个表中的主键或唯一键相对应,就可以在这两个表之间建立一个关系。当插入或更新一个表中的数据时,系统会自动检查关联的表中是否存在对应的数据,从而保持数据的一致性。如果关联表中的数据被删除,这时候会根据设置的规则,对关联表中的外键数据进行相应的操作,例如禁止删除或级联删除等等。

语法

FOREIGN KEY () REFERENCES 主表()

我们创建两个表,一个是 orders 表,包含订单的信息,另一个是 order_items 表,包含订单中每个商品的信息。这两个表的结构如下

CREATE TABLE orders (
  id INT PRIMARY KEY,
  customer_name VARCHAR(50),
  order_date DATE
);

CREATE TABLE order_items (
  id INT PRIMARY KEY,
  order_id INT,
  product_name VARCHAR(50),
  quantity INT,
  price DECIMAL(10, 2),
  FOREIGN KEY (order_id) REFERENCES orders(id)
);

在上述示例中,orders 表的主键是 id 列,order_items 表的主键是id列,同时还定义了一个外键 order_id,它与 orders 表中的 id 列相对应,用于建立 orders 表和 order_items 表之间的关系。

接下来,我们向这两个表中插入一些数据,如下所示:

INSERT INTO orders (id, customer_name, order_date)
VALUES (1, 'John Doe', '2023-01-01'),
       (2, 'Jane Smith', '2023-01-02');

INSERT INTO order_items (id, order_id, product_name, quantity, price)
VALUES (1, 1, 'Product A', 2, 10.00),
       (2, 1, 'Product B', 1, 20.00),
       (3, 2, 'Product C', 3, 30.00),
       (4, 2, 'Product D', 2, 40.00);

在上述示例中,我们向 orders 表中插入了两条数据,分别对应于编号为 1 和 2 的订单,同时向 order_items 表中插入了四条数据,分别对应于 orders 表中的两个订单中的商品。

下面演示外键约束对我们的作用

现在 orders 里面有 id 为 1、 2 的两个订单,如果我们向 order_items 里面插入一个属于 3 号订单的商品,MySQL 就会报错,因为 orders 里根本就没有 id 为 3 的订单:

MariaDB [test_db]> insert into order_items values (5, 3, 'Product E', 1, 50.00);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test_db`.`order_items`, CONSTRAINT `order_items_ibfk_1` FOREIGN KEY (`order_id`) REFERENCES `orders` (`id`))

当我们尝试删除 ordersid 为 1 的订单,MySQL 也会向我们报错,因为在 order_items 中还有属于 1 号订单的商品。

MariaDB [test_db]> delete from orders where id=1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`test_db`.`order_items`, CONSTRAINT `order_items_ibfk_1` FOREIGN KEY (`order_id`) REFERENCES `orders` (`id`))

表之间的关系是根据业务逻辑天然存在的,而有了外键的约束,可以有效地防止程序员后续因为逻辑错误而对表进行错误操作。确保了数据的一致性和完整性。

外键所联系的两表之间究竟是一种什么关系?

外键所连接的两个表之间通常表示一种“父-子”(Parent-Child)的关系,也称为“从属”(Dependent)关系。

在这种关系中,其中一个表(通常是拥有主键的表)被视为“父表(主表)”,而另一个表(通常是拥有外键的表)则被视为“子表(从表)”。子表中的每一行都与父表中的某一行相关联,这种关联关系由外键来维护。

例如,在一个订单管理系统中,订单(orders)表是父表,而商品详情(order_items)表则是子表。每个订单可能会包含多个商品详情,因此,商品详情表中的每一行都与订单表中的某一行相关联。

需要注意的是,外键关系不仅仅限于“父-子”关系,也可以用于表示其他类型的关系,例如“一对一”(One-to-One)关系或“多对多”(Many-to-Many)关系,但通常情况下,外键关系是用于建立“父-子”关系的。

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

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

相关文章

【C++】位图的概念

文章目录位图的引入什么是位图位图的应用bitset的使用定义方式成员函数bitset的运算符重载>> 及 << 运算符赋值,关系,复合赋值,单目运算符[]重载位图的引入 无序的40亿个不重复的无符号整数,给一个无符号整数,如何判断一个数是否在这40亿个数中【腾讯面试题】 方法…

记一次浏览器下载错误处理-失败网络错误

背景 最近在自己电脑上Chrome浏览器正常使用&#xff0c;但只要是下载软件&#xff0c;就会在下载几十秒后&#xff0c;自动停止&#xff0c;报失败-网络错误&#xff0c;导致文件都下载不成功&#xff0c;如下图。 猜测是更改了哪块的配置&#xff0c;导致一直中断&#xff0…

28岁,终于从字节退休了...

大厂一直是每个程序员都向往职业目标&#xff0c;大厂意味着薪资高、福利好、倍有面儿&#xff0c;而且发展空间也大。甚至有人调侃不想进大厂的程序员不是好程序员。 而在网上&#xff0c;也有各个网友分享自己在大厂的经历&#xff0c;在某平台还有一个近2600万浏览的话题&a…

JavaEE——了解Spring,容器,Ioc,DI相关概念

目录 一、Spring 是什么 二、什么是容器 三、什么是loC 1. 什么是 IoC 2. 传统程序开发和控制反转式程序开发 (1). 传统程序开发 (2). 控制反转式程序开发 (3). 对比 3. Spring的功能 4. 将对象存放到容器中的好处 四、DI概念说明 IoC和DI的联系和区别&#xff1f;…

算法 贪心1 || 455.分发饼干 376. 摆动序列 53. 最大子数组和

基础知识 什么是贪心&#xff1a;贪心的本质是选择每一阶段的局部最优&#xff0c;从而达到全局最优。 但是贪心没有套路&#xff0c;做题的时候&#xff0c;只要想清楚 局部最优 是什么&#xff0c;如果推导出全局最优&#xff0c;其实就够了。 455.分发饼干 很容易想到&am…

Emlog底部显示当前在线人数

第一步&#xff1a;在模板文件里面创建“visitor.php”的文件吧下面代码入进去 code <?php//首先你要有读写文件的权限&#xff0c;首次访问肯不显示&#xff0c;正常情况刷新即可$online_log "slzxrs.dat"; //保存人数的文件到根目录,$timeout 30;//30秒内没…

计算机视觉__基本图像操作(显示、读取、保存)

计算机视觉__基本图像操作&#xff08;显示、读取、保存&#xff09; 本文目录&#xff1a; ✨ 一、前言 ✨ 二、图像显示&#xff08;使用OpenCV和Matplotlib显示图像&#xff09; &#xff08;1&#xff09;、使用OpenCV显示图像 &#xff08;2&#xff09;、使用Matplotl…

密集场景下的行人跟踪替代算法,头部跟踪算法 | CVPR 2021

一个不知名大学生&#xff0c;江湖人称菜狗 original author: Jacky LiEmail : 3435673055qq.com Time of completion&#xff1a;2023.4.8 Last edited: 2023.4.8 目录 摘要 主要内容 结果 这篇文章是CVPR 2021 的最新论文&#xff0c;文章的标题&#xff1a; 文章的主要内…

C#,数值计算的进化与发展——FORTRAN 77/80/95源程序 转C# 源程序的软件F2C#

1 F2C#FORTRAN 77/80/95源程序 转C# 源程序的软件 1.1 F2C#起源 全世界科学计算领域在超过40年的时间里累积了巨大数量的FORTRAN源程序&#xff08;尤其以FORTRAN77居多&#xff09;&#xff0c;实际上目前的许多大型科学软件还是以这些代码为基础的。众所周知的原因&#xf…

【youcans的深度学习 06】PyTorch入门教程:张量的基本操作

欢迎关注『youcans的深度学习』系列&#xff0c;持续更新中… 【youcans的深度学习 01】安装环境之 miniconda 【youcans的深度学习 02】PyTorch CPU版本安装与环境配置 【youcans的深度学习 03】PyTorch CPU版本安装与环境配置 【youcans的深度学习 04】PyTorch入门教程&#…

t-SNE进行分类可视化

0、引入 我们在论文中通常可以看到下图这样的可视化效果&#xff0c;这就是使用t-SNE降维方法进行的可视化&#xff0c;当然除了t-SNE还有其他的比如PCA等降维等方法&#xff0c;关于这些算法的原理有很多文章可以借阅&#xff0c;这里不展开阐释&#xff0c;重点讲讲如何进行…

window10 更新提示 0x80073712错误

解决方法&#xff1a; 1、可以尝试重新配置一下 Windows 更新服务状态&#xff1a; 2、Win S打开搜索&#xff0c;输入 CMD 找到 “命令提示符”&#xff0c; 3、右键以管理员身份打开&#xff0c;依次输入以下代码&#xff0c;并按回车执行。注&#xff1a;是一条一条的执行…

vue基础知识

1、特点 1.采用组件化模式&#xff0c;提高代码复用率、且让代码更好维护。 2.声明式编码&#xff0c;让编码人员无需直接操作DOM&#xff0c;提高开发效率 命令式编码 3.使用虚拟DOM优秀的Diff 算法&#xff0c;尽量复用DOM节点。 2、hello vue vue的引入 就是写在引入c…

关键词词库制作-搜索词分析工具

关键词词库制作 关键词词库是一种帮助SEO和SEM优化的工具&#xff0c;它可以帮助您确定关键词的流行程度、竞争程度、搜索意图和其他相关信息等等。以下是一些关键词词库制作的方法&#xff1a; 收集关键词&#xff1a;首先需要收集相关的关键词&#xff0c;这可能涉及到您的业…

一文讲透产品经理如何用好ChatGPT

作者&#xff1a;京东零售 何雨航 “4.0版本的ChatGPT可以有效提升产品经理工作效率&#xff0c;但并无法替代产品经理的角色。” 一、引言 3月15日&#xff0c;OpenAI发布了最新的基于GPT-4的ChatGPT&#xff0c;关于其智能性的讨论热度在互联网上空前高涨。 我之前体验过3…

基于POSIX的消息队列的发送、接收demo的设计(linux)

本文介绍POSIX的消息队列的linux应用&#xff0c;新建两个进程&#xff08;一个发送进程、一个接收进程&#xff09;实现消息形式的数据传输。POSIX消息队列与SystemV消息队列存在相似的消息传输单位&#xff0c;但较SystemV消息队列更适合linux系统的使用。本文在ubuntu20.4上…

面试篇-深入理解 Java 中的 HashMap 实现原理

一、HashMap实现原理 HashMap 的实现主要包括两个部分&#xff1a;哈希函数和解决哈希冲突的方法。 1.哈希函数 当使用 put() 方法将键值对存储在 HashMap 中时&#xff0c;首先需要计算键的哈希值。HashMap 使用 hashCode() 方法获取键的哈希值&#xff0c;并将其转换为桶&…

Docker的常见命令

前言:使用Docker得学会的几个常见命令 常见命令前置学习: docker --help这个命令必须得会因为,很多命令是记不住的,得使用他们的官方help下面是一些实例 docker load --help常见命令集合: 一: docker images #查看全部镜像 docker rmi #删除某个镜像(例如:docker rmi redis…

Vue3——组件间通信的五种常用方式

Vue3组件间通信的五种常用方式 写在前面 本文采用<script setup>语法糖的编写方式&#xff0c;比options API更自由。 <script setup>语法糖详细内容看查看文档&#xff1a;setup语法糖官方文档 然后我们会讲以下五种常用的组件通信方式 propsemitv-modelrefs…

高速数字信号VS射频信号,到底哪个更难设计?

一博高速先生成员&#xff1a;黄刚熟悉高速先生的小伙伴们会知道&#xff0c;我们是以研究高速数字信号为主的团队&#xff0c;从不到1G到目前在研究的112G&#xff0c;高速先生就这样一直研究过来的&#xff0c;分享的案例也大多是以高速数字信号为主的案例。最近受到我们粉丝…