MySQL修炼手册8:约束与完整性:保证数据的一致性

目录

  • 写在开头
  • 1 主键与唯一键约束
    • 1.1 PRIMARY KEY约束的作用
    • 1.2 主键的复合使用
    • 1.3 主键的修改与删除
    • 1.4 UNIQUE约束的应用场景
    • 1.5 主键与唯一键约束的性能影响
    • 1.6 主键的自动增长
    • 1.7 主键的最佳实践
    • 1.8 独特性与业务需求
    • 1.9 避免过度使用唯一约束
    • 1.10 主键与唯一键的关系
  • 2 外键约束
    • 2.1 FOREIGN KEY约束的使用
    • 2.2 处理外键关联的数据更新和删除
    • 2.2.1 CASCADE
    • 2.2.2 SET NULL
    • 2.2.3 NO ACTION 和 RESTRICT
    • 2.2.4 SET DEFAULT
    • 2.3 多表级联操作
    • 2.4 综合实例
    • 2.5 外键约束的性能考虑
    • 2.6 动态添加与移除外键约束
    • 2.7 外键约束与索引
    • 2.8 外键约束的最佳实践
  • 3 CHECK约束
    • 3.1 CHECK约束的基本概念
    • 3.2 使用CHECK约束保障数据合法性
      • 3.2.1 确保数值范围
      • 3.2.2 确保字符串符合特定格式
      • 3.2.3 确保日期符合特定范围
      • 3.2.4 多条件组合
      • 3.2.5 使用逻辑运算符
      • 3.2.6 使用函数
      • 3.2.7 确保唯一组合
  • 写在最后

写在开头

在数据库设计和管理中,保证数据的完整性和一致性是至关重要的。MySQL通过不同类型的约束来实现这一目标。约束用于限制存储在表中的数据类型,保证数据的准确性和可靠性。本文将深入探讨MySQL中最常用的几种约束:主键(PRIMARY KEY)、唯一键(UNIQUE)、外键(FOREIGN KEY)和检查(CHECK)约束。了解这些约束的使用方法和应用场景,对于创建稳定和高效的数据库至关重要。

1 主键与唯一键约束

1.1 PRIMARY KEY约束的作用

主键约束是数据库表中的核心约束之一,用于唯一标识表中的每一行。在MySQL中,主键约束具有以下特点:

  • 唯一性:保证列中的每个值都是唯一的。
  • 非空性:主键列不能有NULL值。
  • 索引:MySQL会自动为主键列创建索引,优化查询性能。

例如,创建一个具有主键约束的学生表:

CREATE TABLE Students (StudentID int NOT NULL,StudentName varchar(255) NOT NULL,PRIMARY KEY (StudentID)
);

1.2 主键的复合使用

主键不仅可以是单个列,也可以是多个列的组合,称为复合主键。在复合主键中,每个列的组合必须是唯一的。

例如,如果一个课程注册表同时需要学生ID和课程ID来唯一确定一条记录:

CREATE TABLE CourseRegistrations (StudentID int NOT NULL,CourseID int NOT NULL,RegistrationDate date NOT NULL,PRIMARY KEY (StudentID, CourseID)
);

1.3 主键的修改与删除

  • 修改主键:在实际使用中,修改主键是一种需要谨慎进行的操作。你可以通过ALTER TABLE命令来修改主键。

    ALTER TABLE Students DROP PRIMARY KEY;
    ALTER TABLE Students ADD PRIMARY KEY (NewColumn);
    
  • 删除主键:有时可能需要删除主键约束。这可以通过ALTER TABLE命令实现。

    ALTER TABLE Students DROP PRIMARY KEY;
    

1.4 UNIQUE约束的应用场景

唯一约束确保指定列中的所有值都是不同的。与主键不同,唯一约束允许值为NULL。这在需要确保如电子邮件地址或用户名等属性的唯一性时特别有用。

  • 创建唯一约束

    CREATE TABLE Users (UserID int NOT NULL,Username varchar(255) NOT NULL,Email varchar(255),UNIQUE (Email)
    );
    
  • 添加唯一约束:已经存在的表可以添加唯一约束。

    ALTER TABLE Users ADD UNIQUE (Username);
    
  • 复合唯一键:与复合主键类似,可以定义多列组合的唯一约束,确保这些列的组合值唯一。

    CREATE TABLE Reservations (GuestID int NOT NULL,RoomID int NOT NULL,ReservationDate date NOT NULL,UNIQUE (GuestID, ReservationDate)
    );
    
  • 删除唯一约束:如果需要,可以从表中删除唯一约束。

    ALTER TABLE Users DROP INDEX Email;
    
  • 唯一约束与NULL值:唯一约束允许多个NULL值,因为在SQL中,NULL被认为与任何其他值(包括另一个NULL)都不相等。

1.5 主键与唯一键约束的性能影响

  • 性能优化:由于主键和唯一键自动创建索引,它们可以显著提高查询的速度。特别是在大型数据集中,合理设置主键和唯一键可以极大地优化数据检索的性能。

  • 考虑选择合适的主键:选择短且意义明确的字段作为主键可以提高性能。例如,整数类型的ID通常是一个好选择,因为它们比字符串类型占用更少的空间,并且在比较时更快。

1.6 主键的自动增长

  • AUTO_INCREMENT:在MySQL中,主键字段经常设置为自动增长(AUTO_INCREMENT)。这意味着当新行被插入表中时,主键字段会自动设置为一个唯一的数值。

    CREATE TABLE Orders (OrderID int NOT NULL AUTO_INCREMENT,OrderDate date NOT NULL,PRIMARY KEY (OrderID)
    );
    

    这在创建具有唯一标识符需求的表时非常有用,例如订单、票据等。

1.7 主键的最佳实践

  • 尽量使用简单的主键:复杂的或多列的主键可能会使数据关联和查询变得复杂,尤其是在涉及多个表的JOIN操作时。
  • 避免使用敏感数据:作为主键的数据将在多个地方引用,因此避免使用可能被视为敏感的数据(如社会安全号码)。

1.8 独特性与业务需求

  • 主键与业务逻辑:选择主键时,考虑是否反映了业务逻辑。例如,在员工数据库中,员工号可能是一个自然的选择。
  • 唯一键与数据规范:唯一键不仅是保证数据唯一性的工具,也是数据规范和完整性的重要部分。例如,防止同一电子邮件地址被多次注册。

通过这些细节的考虑,主键和唯一键约束不仅作为数据完整性的守护者,还能够优化数据库的性能和响应

时间。在数据库设计阶段,合理的规划主键和唯一键约束对于长期维护和扩展数据库系统至关重要。这要求数据库设计者不仅考虑当前的需求,还要预见未来可能的变化和扩展。

1.9 避免过度使用唯一约束

  • 性能考虑:虽然唯一约束有助于保持数据的准确性,但过度使用可能会影响性能。每个唯一约束都需要额外的存储空间和处理时间来维护索引。
  • 选择合适的字段:在为表设置唯一约束时,应该仔细考虑哪些字段确实需要这种级别的数据完整性保护。例如,用户的电子邮件地址可能需要唯一约束,但他们的姓名则不需要。

1.10 主键与唯一键的关系

  • 互补使用:虽然主键和唯一键有相似的作用,但它们通常用于不同的目的。主键用于唯一标识每条记录,而唯一键用于保证特定字段的独特性。
  • 业务和逻辑需求:根据业务和逻辑需求,可以灵活地组合使用主键和唯一键来达到既定的数据模型要求。

通过深入了解和正确应用主键和唯一键约束,数据库设计者和开发者可以创建出既高效又可靠的数据存储解决方案。这不仅有助于提高数据的质量和准确性,还可以保证数据的安全性和一致性,从而为用户提供更好的体验和服务。在实际应用中,恰当的使用这些约束是数据管理的基础,对于任何涉及数据存储和处理的项目来说都至关重要。

2 外键约束

外键约束(FOREIGN KEY)是数据库完整性的关键组成部分,用于在两个表之间建立链接,确保数据的一致性和准确性。以下是外键约束的一些重要用法和概念:

2.1 FOREIGN KEY约束的使用

当在一个表中定义了外键,它创建了一个指向另一个表主键或唯一键的引用。这种关系确保了引用表中的数据在被引用表中有相应的匹配记录。

例如,有两个表:StudentsOrdersStudents表有一个主键StudentID,而Orders表包含一个指向StudentsStudentID的外键:

CREATE TABLE Students (StudentID int NOT NULL,StudentName varchar(255),PRIMARY KEY (StudentID)
);CREATE TABLE Orders (OrderID int NOT NULL,StudentID int,OrderDetail varchar(255),PRIMARY KEY (OrderID),FOREIGN KEY (StudentID) REFERENCES Students(StudentID)
);

在此例中,Orders表中的StudentID必须在Students表中存在。

2.2 处理外键关联的数据更新和删除

在外键约束中,主要关注的是当被引用的数据发生变化时,如何处理引用该数据的表。以下是几种处理方式:

2.2.1 CASCADE

CASCADE操作会在父表(被引用表)上执行的更新或删除操作同步到子表(引用表)。这意味着如果一个父表的行被更新或删除,所有引用该行的子表行也会相应地更新或删除。

FOREIGN KEY (StudentID) REFERENCES Students(StudentID) ON DELETE CASCADE ON UPDATE CASCADE

2.2.2 SET NULL

SET NULL操作在父表中的记录被删除或更新时,会将子表中引用该记录的字段自动设置为NULL。这适用于非强制性的关系,其中子表可以继续存在,即使其引用的父表数据被移除。

FOREIGN KEY (StudentID) REFERENCES Students(StudentID) ON DELETE SET NULL ON UPDATE SET NULL

这个设置要求子表中的对应字段必须允许NULL值。

2.2.3 NO ACTION 和 RESTRICT

NO ACTIONRESTRICT实际上在行为上是相同的。当尝试删除或更新父表中的行,并且在子表中存在引用这些行的数据时,这两个选项都会拒绝删除或更新操作。它们确保子表中不会存在无效的引用。

FOREIGN KEY (StudentID) REFERENCES Students(StudentID) ON DELETE RESTRICT ON UPDATE NO ACTION

2.2.4 SET DEFAULT

SET DEFAULT操作在父表的记录被删除或更新时,会将子表中的外键字段设置为某个默认值。这需要在子表中的外键列定义时指定默认值。

FOREIGN KEY (StudentID) REFERENCES Students(StudentID) ON DELETE SET DEFAULT ON UPDATE SET DEFAULT

2.3 多表级联操作

外键约束也可以在多个表之间建立复杂的级联操作。例如,如果你有一个Students表、一个Orders表以及一个OrderDetails表,Orders表可以引用Students表,而OrderDetails表又可以引用Orders表。这种关系允许在任一级别上进行数据更新或删除,而相应的变更会传递到所有相关的表。

2.4 综合实例

创建一个具有外键约束和级联行为的复杂数据库结构,可以更全面地理解这些概念。例如,创建StudentsCoursesEnrollments表,其中Enrollments表连接StudentsCourses表,并具有相应的外键和级联规则。

CREATE TABLE Courses (CourseID int NOT NULL,CourseName varchar(255),PRIMARY KEY (CourseID)
);CREATE TABLE Enrollments (StudentID int,CourseID int,EnrollmentDate date,FOREIGN KEY (StudentID) REFERENCES Students(StudentID) ON DELETE CASCADE,FOREIGN KEY (CourseID) REFERENCES Courses(CourseID) ON DELETE CASCADE
);

通过掌握外键约束及其各种行为,可以在数据库设计中构建更加健壮和灵活的数据模型,同时确保数据的一致性和完整性。

2.5 外键约束的性能考虑

使用外键约束时,还需要注意其对数据库性能的影响。外键检查可能会增加数据插入、更新和删除操作的成本。在高性能的系统中,有时可能选择在应用程序逻辑而非数据库级别来强制数据完整性,尤其是在处理大量交易的系统中。

2.6 动态添加与移除外键约束

在某些情况下,你可能需要在表已经创建之后添加或移除外键约束。这可以通过ALTER TABLE命令实现:

  • 添加外键约束:

    ALTER TABLE Orders ADD FOREIGN KEY (StudentID) REFERENCES Students(StudentID);
    
  • 移除外键约束:

    ALTER TABLE Orders DROP FOREIGN KEY Orders_ibfk_1;
    

在移除外键约束时,需要指定外键的名称,这可以通过查询表的创建信息或使用SHOW CREATE TABLE命令来获取。

2.7 外键约束与索引

在实施外键约束时,还需考虑索引的使用。为了提高性能,建议在作为外键的列上创建索引。当MySQL强制执行外键约束时,如果被引用的列(通常是主键或唯一键)和引用列都有索引,这将显著提高查询和更新操作的效率。

  • 自动索引创建:在某些情况下,当你为一个列添加外键约束时,MySQL会自动为该列创建索引。但这并不总是发生,取决于具体的数据库版本和设置。

  • 手动添加索引:如果自动索引创建未发生,或者你需要更精细地控制索引的类型和性能,可以手动添加索引。例如,为Orders表中的StudentID列添加索引:

    CREATE INDEX idx_student_id ON Orders (StudentID);
    

2.8 外键约束的最佳实践

在实际应用中,合理使用外键约束可以带来许多好处,但也要注意避免过度使用,因为它们可能会影响数据库的性能和灵活性:

  • 谨慎使用外键:对于核心业务逻辑至关重要的数据完整性保护,应使用外键。但在某些情况下,特别是对于大规模的、高频写入的数据库系统,应考虑通过应用逻辑来维护数据完整性。

  • 避免复杂的级联操作:虽然级联更新和删除操作可以简化某些数据库维护任务,但在复杂的数据库架构中,过度使用级联可能会导致不可预测的结果和性能瓶颈。

  • 定期审查外键约束:随着业务的发展,某些外键约束可能变得不再适用或不必要。定期审查并调整这些约束可以保证数据库架构与业务需求保持一致。

3 CHECK约束

3.1 CHECK约束的基本概念

CHECK约束是MySQL中用于确保表中特定列的数据符合特定条件的功能。它在数据插入或更新时自动执行,如果数据不符合定义的条件,操作将被拒绝。CHECK约束提高了数据的完整性和质量,避免了无效或不合适的数据进入数据库。

3.2 使用CHECK约束保障数据合法性

3.2.1 确保数值范围

例如,限制年龄字段必须在1到100之间:

CHECK (Age BETWEEN 1 AND 100)

3.2.2 确保字符串符合特定格式

如果需要确保某个字符串字段遵循特定格式,例如,一个国家代码必须是两个大写字母:

CHECK (CountryCode REGEXP '^[A-Z]{2}$')

3.2.3 确保日期符合特定范围

限制日期字段必须在特定日期之后:

CHECK (StartDate > '2024-01-01')

3.2.4 多条件组合

可以在一个CHECK约束中组合多个条件。例如,确保一个薪水字段既不是负数也不是过高的数值:

CHECK (Salary >= 0 AND Salary <= 100000)

3.2.5 使用逻辑运算符

使用AND、OR和NOT等逻辑运算符来创建更复杂的条件。例如,确保员工的状态是活动的或者,如果不活动,终止日期必须存在:

CHECK ((IsActive = 1) OR (IsActive = 0 AND TerminationDate IS NOT NULL))

3.2.6 使用函数

CHECK约束中使用函数来验证数据。例如,确保某个字符串字段是一个有效的电子邮件地址:

CHECK (Email LIKE '%_@__%.__%')

3.2.7 确保唯一组合

虽然UNIQUE约束通常用于这个目的,但在某些情况下,CHECK约束可以用来确保字段的组合是唯一的。例如:

CHECK (NOT EXISTS (SELECT * FROM table WHERE column1=value1 AND column2=value2))

写在最后

在数据库设计和数据维护过程中,合理使用各种约束至关重要。它们不仅帮助维护数据的一致性和完整性,还能在某种程度上提高数据库操作的效率。理解并正确应用这些约束,可以使你的数据库更加健壯和可靠。无论是设计一个新的数据库还是优化现有的数据库,掌握MySQL中的约束都是任何数据库管理员或开发者的基本技能。

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

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

相关文章

嵌入式培训机构四个月实训课程笔记(完整版)-Linux网络编程第三天-UDP编程练习题(物联技术666)

网盘链接:https://pan.baidu.com/s/1TKdHdeuDI8XPaakepvSLZQ?pwd=1688 提取码:1688 利用UDP实现双人不同机器聊天(服务器可以被多人连接,显示多人聊天记录) //-------------------------服务器 #include <string.h> #include <sys/types.h> #include <…

VCG 网格布尔运算

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 Mesh布尔操作是一种在三维计算机图形学中用于组合两个或多个网格(mesh)对象的方法。它可以将两个网格对象组合成一个新的对象,同时保留原始对象的拓扑结构和几何信息。Mesh布尔操作主要有以下三种类型: Union(…

爱这个世界,从爱自己开始

亲爱的月月&#xff1a; 早上十点叫你起床&#xff0c;你仍睡意朦胧&#xff0c;今天的网课看样又得加班加点到凌晨。昨晚你大半夜跑完步后&#xff0c;涮火锅、麻辣肚、吃冷饮后闹肚子不停&#xff0c;你妈心疼地照顾你时&#xff0c;你勇敢地微笑着对我们说“肉体不就是拿来…

android gradle编译问题记录

1、gradle下载太慢 有时候即便配置了国内镜像下载gradle也是慢的一批&#xff0c;可以手动下载gradle文件配置到项目中,比如我下载了一个新项目&#xff0c;它的gradle版本是gradle-4.1-all&#xff0c;进入项目时它会开始下载gradle&#xff0c;此时gradle目录中会创建gradle…

[NSSCTF Round#16 Basic] CPR

打着玩玩&#xff0c;比赛很简单。 Crypto pr 一个RSA题&#xff0c;n1p*q,n2q*r给了两个c和p,r而且flag经过pad用单因子无法解出。分别用p,r解完再取crt from Crypto.Util.number import * import randomflagplaintext NSSCTF{****************} charset abcdefghijklmn…

【DP】931. 下降路径最小和

题目 法1&#xff1a;标准DP class Solution {public int minFallingPathSum(int[][] matrix) {if (matrix.length 0 || matrix[0].length 0) {return 0;}int m matrix.length, n matrix[0].length;int[][] dp new int[m][n]; // 到达i,j的最小路径和int min Integer.M…

【Spring之ComponentScanAnnotationParser】

ComponentScanAnnotationParser 1. ComponentScanAnnotationParser属性解析2. 一个重要方法---parse 1. ComponentScanAnnotationParser属性解析 private final Environment environment;// 用于获取当前应用运行时的配置信息&#xff0c;包括但不限于系统属性、环境变量以及通…

MySQL基础学习: 使用EXPLAIN查看执行计划详解分析

一、EXPLAIN语句的作用 在客户端执行MySQL的操作语句&#xff0c;会依次经过MySQL客户端连接管理、语法解析与优化&#xff08;查询缓存、语法解析、查询优化&#xff09;、存储引擎层。其中查询优化器在基于成本和规则对查询语句进行优化&#xff0c;并且在优化后会生成一个执…

Redis学习指南(6)-Redis的数据类型简介

文章目录 引言1. 字符串 (String)2. 哈希 (Hash)3. 列表 (List)4. 集合 (Set)5. 有序集合 (ZSet)结语 引言 Redis是一种高性能的键值存储系统&#xff0c;被广泛应用于缓存、消息队列等场景。其中&#xff0c;Redis的数据类型是其强大功能的基础之一。本文将深入介绍Redis的主…

nacos配置中心只能获取部分配置的问题

检查配置中心&#xff0c;在配置中心里是可以看到监听的服务地址的&#xff0c;但是却获取不到配置 nacos配置中心主要是在这个NacosConfigService的这个类下面。该接口下面主要有一些获取配置&#xff0c;发布配置&#xff0c;增加监听器&#xff0c;删除配置&#xff0c;删…

一个简易的PHP论坛系统

一个简易的PHP论坛系统 php课程设计&#xff0c;毕业设计 预览 技术 bootstrap 4.x jquery css php mysql 5.7 目录结构 登录 管理员 admin/123456 测试用户 user1/123456 更多文章和源码获取查看

Windows平台RTMP推送|轻量级RTSP服务录像模块如何支持中文路径?

技术背景 我们在做Windows平台RTMP推送、轻量级RTSP服务录像模块的时候&#xff0c;部分开发者抱怨路径无法设置中文&#xff0c;只能设置为英文。 以C#的接口为例&#xff0c;早期的设计如下&#xff1a; /** 设置本地录像目录, 必须是英文目录&#xff0c;否则会失败*/[DllI…

Debezium发布历史66

原文地址&#xff1a; https://debezium.io/blog/2019/07/25/debezium-0-10-0-beta3-released/ 欢迎关注留言&#xff0c;我是收集整理小能手&#xff0c;工具翻译&#xff0c;仅供参考&#xff0c;笔芯笔芯. Debezium 0.10.0.Beta3 发布 七月 25, 2019 作者&#xff1a; Jir…

【PostgreSQL】数据查询-LIMIT AND OFFSET

PostgreSQL数据查询-LIMIT AND OFFSET PostgreSQL中LIMIT并允许您仅检索由查询的其余部分生成的部分行&#xff1a;OFFSET SELECT select_listFROM table_expression[ ORDER BY ... ][ LIMIT { number | ALL } ] [ OFFSET number ]如果给出了限制计数&#xff0c;则返回的行数…

【Java SE语法篇】8.面向对象三大特征——封装、继承和多态

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ 文章目录 1. 封装1.1 封装的概念1.2 为什么封装1.3 封装的实现…

Leetcode with Golang 滑动窗口 Part1

滑动窗口的定义&#xff1a; 滑动窗口这一个技巧主要运用于处理数组问题上&#xff0c;一般用于“子串”问题。精髓是&#xff0c;维护一个里面装着元素的“窗口”&#xff0c;在将新元素装进“窗口”的同时&#xff0c;根据题意&#xff0c;把不符合题意的元素踢出“窗口”。…

漏洞复现-nginxWebUI runCmd前台远程命令执行漏洞(附漏洞检测脚本)

免责声明 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…

Pandas实战100例 | 案例 33: 使用 `loc` 和 `iloc` 选择数据

案例 33: 使用 loc 和 iloc 选择数据 知识点讲解 在 Pandas 中&#xff0c;loc 和 iloc 是两种主要的数据选择方法。loc 是基于标签的选择方法&#xff0c;而 iloc 是基于整数位置的选择方法。 loc: 使用行标签和列名来选择数据。iloc: 使用行和列的整数位置&#xff08;从 …

1222. 密码脱落(dp划分)

题目&#xff1a; 1222. 密码脱落 - AcWing题库 思路&#xff1a; 代码&#xff1a; #include<cstdio> #include<cstring> using namespace std; const int N1010; int f[N][N];//表示以L和R为两端点的字符串的“最长”回文序列长度 char s[N];//存储输入的字符串…

buuctf-Misc 题目解答分解115-117

115.派大星的烦恼 解压下载文件时一个 bmp 文件&#xff0c;用notepad 打开有没有发现什么 &#xff0c;提示位图什么的 用Stegsolve.jar 打开 发现很多. 和- 第一时间想到了 电报码 但提示不是电报码&#xff0c;除了这个那就是很像二进制了 0,1 什么的&#xff0c;但这个感觉…