当前位置: 首页 > news >正文

MVCC(多版本并发控制)

MVCC(多版本并发控制)是数据库实现高并发事务的核心技术之一,其核心是通过数据多版本解决读写冲突。以下从‌技术原理、实现细节、应用场景、优缺点‌四个方面深入解析。


一、技术原理

1. ‌核心思想
  • 数据多版本化‌:每次数据修改(增删改)时,生成一个新版本的数据,旧版本保留(通过指针或隐藏字段链接)。
  • 读操作基于快照‌:每个事务启动时获取一个“快照”(Snapshot),后续读操作仅基于该快照的数据版本,不阻塞写操作。
2. ‌关键组件
  • 事务ID(Transaction ID)‌:每个事务启动时分配唯一递增的ID,标记事务的时间顺序。
  • 版本链(Version Chain)‌:每条数据维护多个版本,通过指针链接历史版本(类似链表)。
  • Read View(读视图)‌:事务启动时生成,用于判断哪些版本的数据对该事务可见。
    • 包含活跃事务ID列表(未提交的事务)。
    • 记录当前最小事务ID(up_limit_id)和最大事务ID(low_limit_id)。

二、实现细节(以MySQL InnoDB为例)

1. ‌数据存储结构
  • 隐藏字段‌:
    • DB_TRX_ID:最近修改该数据的事务ID。
    • DB_ROLL_PTR:回滚指针,指向旧版本数据的undo log(版本链入口)。
    • 示例:某行数据的隐藏字段为 DB_TRX_ID=200DB_ROLL_PTR=0x1234,表示该版本由事务200修改,旧版本存储在undo log地址0x1234。
2. ‌版本链与undo log
  • undo log(回滚日志)‌:存储数据修改前的旧版本,构成版本链。
    • INSERT操作:undo log记录删除信息。
    • DELETE/UPDATE操作:undo log记录旧数据。
  • 版本链遍历‌:事务读取数据时,通过DB_ROLL_PTR依次回溯undo log,找到符合可见性条件的版本。
3. ‌Read View可见性规则

事务读取数据时,根据Read View判断版本可见性:

  • 如果数据版本的DB_TRX_ID < up_limit_id:该版本在事务启动前已提交,‌可见‌。
  • 如果数据版本的DB_TRX_ID >= low_limit_id:该版本在事务启动后生成,‌不可见‌。
  • 如果up_limit_id ≤ DB_TRX_ID < low_limit_id
    • DB_TRX_ID在活跃事务列表中:该版本由未提交事务生成,‌不可见‌。
    • 否则:事务已提交,‌可见‌。
4. ‌不同隔离级别的实现
  • 读已提交(Read Committed)‌:每次读操作生成新的Read View。
  • 可重复读(Repeatable Read)‌:事务首次读操作生成Read View,后续复用该视图。

三、应用场景

1. ‌高并发读写
  • 示例:电商系统库存扣减,大量用户并发查询库存(读)和下单(写),MVCC避免读写锁竞争。
2. ‌长事务与一致性快照
  • 示例:数据分析事务需要长时间运行,MVCC保证其读取的数据始终是启动时的快照版本。
3. ‌避免锁带来的死锁
  • MVCC通过版本控制减少行锁使用,降低死锁概率。

四、优缺点

优点
  1. 高并发‌:读写操作互不阻塞。
  2. 一致性快照‌:支持可重复读和读已提交隔离级别。
  3. 避免死锁‌:减少锁的依赖。
缺点
  1. 存储开销‌:需存储多版本数据和undo log。
  2. 版本回收‌:需要定期清理旧版本(如MySQL的Purge线程)。
  3. 写冲突处理‌:仍需锁机制处理写-写冲突(如悲观锁或乐观锁)。

五、对比其他并发控制机制

机制MVCC锁机制(2PL)
读写冲突处理读不阻塞写,写不阻塞读读阻塞写,写阻塞读
性能高并发场景性能更优高锁竞争时性能下降
一致性基于快照的隔离级别严格串行化(Serializable)
适用场景读多写少,长事务写密集型,强一致性要求

六、实际案例分析

MySQL的MVCC实现
  1. 插入操作‌:生成新数据版本,旧版本为空。
  2. 更新操作‌:
    • 原数据行的DB_TRX_ID标记为当前事务ID。
    • 旧数据存入undo log,DB_ROLL_PTR指向undo log地址。
  3. 删除操作‌:标记数据为删除状态,旧版本保留在undo log中。
  4. 查询操作‌:遍历版本链,找到符合Read View的最新可见版本。
PostgreSQL的MVCC实现差异
  • 通过事务ID(XID)和元组可见性规则实现。
  • 旧版本数据直接存储在表中,通过xminxmax字段标记事务范围。
  • 需要VACUUM进程清理旧版本数据。

七、总结

  • MVCC本质‌:用空间换时间,通过多版本数据降低锁竞争。
  • 核心价值‌:在高并发场景下,平衡一致性、隔离性和性能。
  • 适用性‌:适合读多写少、需要非阻塞读的场景(如OLTP系统)。

相关文章:

MVCC(多版本并发控制)

MVCC&#xff08;多版本并发控制&#xff09;是数据库实现高并发事务的核心技术之一&#xff0c;其核心是通过数据多版本解决读写冲突。以下从‌技术原理、实现细节、应用场景、优缺点‌四个方面深入解析。 ‌一、技术原理‌ 1. ‌核心思想‌ ‌数据多版本化‌&#xff1a;每…...

可以隐藏列的表格

今天积累一个可以隐藏列的表格的实现方法 需求&#xff1a; 表格中有一部分列可以隐藏&#xff0c;在列名右侧有一个复选框&#xff0c;点击勾选展示&#xff0c;否则隐藏另有一个小工具栏&#xff0c;其中有每一列对应的复选框&#xff0c;点击可以将隐藏的列再次展示 思路…...

学习MySQL的第十二天

夕阳西下 云霞满天 一、存储过程概述 1.1 理解 含义:存储过程的英文是 Stored Procedure。它的思想很简单,就是一组经过预先编译的SQL语句的封装。 执行过程:存储过程预先存储在MySQL服务器上,需要执行的时候,客户端只需要向服务器端发出调用存储过程的命令,服…...

用Python做有趣的AI项目4:AI 表情识别助手

本项目将使用 计算机视觉 CNN 模型来识别人脸表情&#xff0c;例如&#xff1a; 开心 &#x1f60a; | 生气 &#x1f620; | 悲伤 &#x1f622; | 惊讶 &#x1f632; | 厌恶 &#x1f612; | 害怕 &#x1f631; | 中性 &#x1f610; &#x1f9e0; 项目目标 实时摄像头…...

2005-2020年 各省-绿色信贷水平原始数据及测算

各省-绿色信贷水平原始数据及测算&#xff08;2005-2020年&#xff09;.ziphttps://download.csdn.net/download/2401_84585615/90259771 https://download.csdn.net/download/2401_84585615/90259771 绿色信贷是指金融机构向符合环保要求的企业或项目提供的贷款&#xff0c;旨…...

STM32F103_HAL库+寄存器学习笔记21 - CAN接收过滤器:CPU减负神器,提升系统效率的第一道防线

在STM32F103的CAN总线应用中&#xff0c;硬件过滤器&#xff08;Filter&#xff09;承担着关键角色。 本章将从寄存器层面深入剖析CAN接收过滤器的工作机制与配置方法&#xff0c;帮助理解如何高效筛选关键信息&#xff0c;减轻CPU负担。 通过合理使用过滤器&#xff0c;不仅能…...

java_基础Java 转义字符学习笔记

Java 转义字符学习笔记 在Java编程中&#xff0c;转义字符用于表示那些无法直接在代码中表示的字符。以下是一些常用的Java转义字符&#xff1a; \t - 制表符&#xff1a;用于实现对齐功能。\n - 换行符&#xff1a;用于在文本中换行。\ - 反斜杠&#xff1a;表示一个反斜杠字…...

JavaScript基础(七)之web APIs

第二部分:Web APIs 目录 第二部分:Web APIs 五、DOM-节点操作 5.1 日期对象 5.1.1 实例化 5.1.2 时间对象方法 5.1.3 时间戳 5.2 节点操作 5.2.1 DOM节点 5.2.2 查找节点 父节点查找: 子节点查找: 兄弟关系查找: 5.2.3 增加节点 创建节点 5.2.4 删除节点 …...

强化学习机器人路径规划——Sparrow复现

强化学习机器人路径规划——Sparrow-v1.1复现教程 Sparrow是一个开源的移动机器人路径规划模拟器,重视模拟速度和轻量化,使用DDQN强化学习方法进行训练。本文在其基础上,增加了绘制训练曲线教程,并给出了自制地图文件,以实现在自己的地图上进行训练。 模型示意图 源码地…...

怎样给MP3音频重命名?是时候管理下电脑中的音频文件名了

在处理大量音频文件时&#xff0c;给这些文件起一个有意义的名字可以帮助我们更高效地管理和查找所需的内容。通过使用专业的文件重命名工具如简鹿文件批量重命名工具&#xff0c;可以极大地简化这一过程。本文将详细介绍如何利用该工具对 MP3 音频文件进行重命名。 步骤一&am…...

【Nova UI】十二、打造组件库之按钮组件(上):迈向功能构建的关键一步

序言 在上一篇文章中&#xff0c;我们深入探索了 icon 组件从测试到全局注册的全过程&#x1f3af;&#xff0c;成功为其在项目中稳定运行筑牢了根基。此刻&#xff0c;组件库的建设之旅仍在继续&#xff0c;我们将目光聚焦于另一个关键组件 —— 按钮组件。按钮作为用户与界面…...

C++初阶-STL简介

目录 1.什么是STL 2.STL的版本 3.STL的六大组件 4.STL的重要性 4.1在笔试中 4.2在面试中 4.3.在公司中 5.如何学习STL 6.总结和之后的规划 1.什么是STL STL&#xff08;standard template library-标准模板库&#xff09;&#xff1b;是C标准库的重要组成部分&#xf…...

(最短路)洛谷 P6880 JOI2020 奥运公交 题解

题意 给定一个 n n n 点 m m m 边的有向图&#xff0c;每条边从 u u u 指向 v v v&#xff0c;经过这条边的代价为 c c c。点编号为 1 1 1 到 n n n&#xff0c;无自环。 我们可以翻转一条边&#xff0c;即让他从 u u u 指向 v v v 变为从 v v v 指向 u u u&#…...

动态规划算法题1

动态规划做题步骤 确定状态表示&#xff1a;dp表中某一个位置中的值所表示的含义就是状态表示根据状态表示推导状态转移方程&#xff1a;dp[i]等于什么状态转移方程就是什么&#xff0c;用之前或者之后的状态&#xff0c;推导出dp[i]的值初始化(防止越界)&#xff1a;根据状态…...

π0.5:带开放世界泛化的视觉-语言-动作模型

25年4月来自具身机器人创业公司 PI 公司的论文“π0.5: a Vision-Language-Action Model with Open-World Generalization”。 为了使机器人发挥作用&#xff0c;它们必须在实验室之外的现实世界中执行实际相关的任务。虽然视觉-语言-动作 (VLA) 模型在端到端机器人控制方面已…...

ESP32开发入门(四):ESP32-s3多串口开发实践

摘要 本文详细介绍ESP32-S3芯片的UART外设开发方法&#xff0c;涵盖UART0(默认调试串口)、UART1和UART2的配置与使用技巧&#xff0c;并提供完整示例代码&#xff0c;帮助开发者快速实现多设备串口通信。 一、ESP32-S3串口硬件资源 ESP32-S3芯片提供3个UART控制器&#xff1…...

树莓派学习专题<10>:使用V4L2驱动获取摄像头数据--申请和管理缓冲区

树莓派学习专题&#xff1c;10&#xff1e;&#xff1a;使用V4L2驱动获取摄像头数据--申请和管理缓冲区 1. 申请和管理缓冲区代码2. 代码解析3. 实测结果 1. 申请和管理缓冲区代码 /* 数据缓冲区 */ typedef struct tag_BufDesc {void *pvBufPtr ;size_t szBuf…...

Android10.0 Android.bp文件详解,以及内置app编写Android.bp文件

1.前言 在10.0的系统rom定制化开发中,在内置app的时候都是常用的用法,用Android.mk的常用,但是某些时候,会 使用Android.bp的方式来内置app,接下来就来使用常用的方式来写内置so aar jar等文件 2.Android.bp文件详解,以及内置app编写Android.bp文件的介绍 根据设计,An…...

git回退commit

在Git中回退提交(commit)主要有两种方法:使用 `git reset` 或 `git revert`,具体取决于是否需要保留提交历史或是否已推送到远程仓库。以下是详细步骤: 一、使用 `git reset`(适合本地未推送的提交) `git reset` 会移动分支的 HEAD 指针到指定提交,可选择是否保留修改。…...

arcpy列表函数的应用(4)

动态获取字段信息 在处理要素类或表时&#xff0c;可能需要动态获取字段信息&#xff0c;以便根据字段类型或名称进行特定操作。可以使用arcpy.ListFields()函数获取字段列表&#xff0c;并根据需要筛选字段。 示例&#xff1a; python # 获取指定要素类的所有字段 fields …...

02 业务流程架构

业务流程架构提供了自上而下的组织鸟瞰图&#xff0c;是业务流程的全景图。根据所采用的方法不同&#xff0c;有时被称为流程全景图或高层级流程图&#xff0c;提供了业务运营中所有业务流程的整体视图。 这样有助于理解企业内部各个业务流程之间的相互关系以及它们如何共同工…...

「Mac畅玩AIGC与多模态01」架构篇01 - 展示层到硬件层的架构总览

一、概述 AIGC&#xff08;AI Generated Content&#xff09;系统由多个结构层级组成&#xff0c;自上而下涵盖交互界面、API 通信、模型推理、计算框架、底层驱动与硬件支持。本篇梳理 AIGC 应用的六层体系结构&#xff0c;明确各组件在系统中的职责与上下游关系&#xff0c;…...

如何有效防止 SQL 注入攻击?

&#x1f512; 如何有效防止 SQL 注入攻击&#xff1f; SQL 注入&#xff08;SQL Injection&#xff09;是黑客通过构造恶意输入&#xff0c;篡改 SQL 查询语句的攻击方式。以下是 7 大防御策略&#xff0c;涵盖开发、测试和运维全流程。 ✅ 1. 使用参数化查询&#xff08;Pre…...

路由交换网络专题 | 第九章 | NAT地址转换 | NAT回流

拓扑图 &#xff08;1&#xff09;配置实现内网用户可以通过 NAT 转换地址访问外网。 // 配置一条静态路由通往PC2 [AR1]ip route-static 0.0.0.0 0 60.1.1.10 // 配置ACL匹配网段 [AR1]acl 2000 [AR1-acl-basic-2000]rule permit source 192.168.1.10 0.0.0.0 // 设置地址池(不…...

DFPatternFunctor遍历计算图

文件&#xff1a;include/tvm/relay/dataflow_pattern_functor.h 功能&#xff1a;定义 DFPatternFunctor 基类&#xff0c;为 DFPattern 提供访问者模式(Visitor Pattern)的实现框架&#xff0c;支持对不同类型的模式节点进行差异化处理。 继承关系&#xff1a; template &…...

Spring Boot中@RequestParam、@RequestBody、@PathVariable的区别与使用

Spring Boot中RequestParam、RequestBody、PathVariable的区别与使用 前言 在当今的Web开发领域&#xff0c;Spring Boot凭借其简洁、高效和强大的功能&#xff0c;成为了Java开发者构建Web应用的首选框架。在开发过程中&#xff0c;处理来自客户端的请求参数是一项常见且关键…...

大模型 SFT 中的关键技术总结学习

文章目录 微调策略LoRA 微调核心思想具体实现过程超参数与技巧实现步骤​ QLoRA 相关技术1. 核心原理2. 技术优势​3. 实现流程​4. 应用场景​ P-tuning核心思想关键技术点训练流程优点应用场景 P-tuning v2Prefix Tuning一、关键概念前缀&#xff08;Prefix&#xff09;虚拟标…...

AI如何重塑DDoS防护行业?六大变革与未来展望

一、AI驱动的攻击与防御&#xff1a;攻防博弈的全面升级 AI技术的引入使DDoS攻防进入“智能对抗”时代&#xff0c;攻击者与防御方均借助AI提升效率&#xff0c;形成新的技术平衡。 1. 攻击端&#xff1a;AI赋能攻击的智能进化 动态流量生成&#xff1a;攻击者利用生成对抗网…...

电池的寿命

思路&#xff1a; 首先&#xff0c;我们观察发现&#xff1a;由于每枚电池的使用时间不同&#xff0c;而我们又要减少浪费才能使所有电池加起来用得最久&#xff0c;不难发现&#xff1a;当n2时&#xff0c;输出较小值。 第一步&#xff1a;将电池分为两组&#xff0c;使两组…...

Android完整开发环境搭建/Studio安装/NDK/本地Gradle下载配置/创建AVD/运行一个Android项目/常用插件

目录 安装Android Studio 修改sdk位置 配置 HTTP 代理 安装 NDK 设置快捷键 Gradle 说明 setting.gradle init.gradle build.gradle 下载 相关设置 创建项目 阿里云加速 清理缓存并同步 创建AVD 实用插件 ADB Idea Android Drawable Importer GsonFormat …...

【KWDB 创作者计划】_KWDB引领数据库技术革新的璀璨之星

【KWDB 创作者计划】_KWDB引领数据库技术革新的璀璨之星 &#x1f31f;嗨&#xff0c;我是LucianaiB&#xff01; &#x1f30d; 总有人间一两风&#xff0c;填我十万八千梦。 &#x1f680; 路漫漫其修远兮&#xff0c;吾将上下而求索。 在当今数字化浪潮汹涌澎湃的时代&…...

设计模式--桥接模式详解

桥接模式&#xff08;bridge pattern&#xff09; 桥接模式时将抽象部分与它的实现部分分离&#xff0c;使他们可以独立的变化。它是一种对象结构型模式&#xff0c;又称为柄体&#xff08;Handle and Body&#xff09;模式或者接口&#xff08;interface&#xff09;模式&…...

Python+Selenium+Pytest+Allure PO模式UI自动化框架

一、框架结构 allure-report&#xff1a;测试报告base&#xff1a;定位元素封装data&#xff1a;数据log&#xff1a;日志文件page&#xff1a;页面封装文件夹report&#xff1a;缓存报告testcases&#xff1a;测试用例层utils&#xff1a;工具类run.py&#xff1a;执行文件 二…...

【C语言操作符详解(一)】--进制转换,原反补码,移位操作符,位操作符,逗号表达式,下标访问及函数调用操作符

目录 一.操作符的分类 二.二进制和进制转换 2.1--2进制转10进制 ​编辑 2.1.1--10进制转2进制数字 2.2--2进制转8进制和16进制 2.2.1--2进制转8进制 2.2.2--2进制转16进制 三.原码&#xff0c;反码&#xff0c;补码 四.移位操作符 4.1--左移操作符 4.2--右移操作符…...

回顾|Apache Cloudberry™ (Incubating) Meetup·2025 杭州站

2025 年 4 月 19 日&#xff0c;由酷克数据与中启乘数联合举办的 Apache Cloudberry™ (Incubating) Meetup 杭州站在浙江省杭州市滨江区滨江会展中心成功举办。本次活动邀请了 Cloudberry PPMC 团队成员、活跃内核贡献者以及中兴 EBASE-A、阿里云 ADB-PG、网易、中启乘数等多…...

使用 Autofac 实现依赖注入

前言&#xff1a;接上一篇文章&#xff0c;有了微软官方的依赖注入组件Microsoft.Extensions.DependencyInjection&#xff0c; 那么今天介绍一个新的开源的依赖注入组件Autofac 一、二者的差异Autofac和微软官方的依赖注入组件&#xff08;Microsoft.Extensions.DependencyIn…...

HTTP:十二.HTTPS

HTTPS 概述 超文本传输安全协议(英语:HyperText Transfer Protocol Secure,缩写:HTTPS;常称为HTTP over TLS、HTTP over SSL或HTTP Secure)是一种通过计算机网络进行安全通信的传输协议。HTTPS经由HTTP进行通信,利用TLS加密数据包。 HTTPS的主要目的是提供对网站服务器…...

《代码整洁之道》第12章 迭进 - 笔记

好的设计是如何形成的&#xff1f; 章节核心&#xff1a; 好的软件设计不是完全靠前期庞大的设计方案来完成的&#xff0c;而更多地是在持续的编码、测试和重构过程中&#xff0c;“涌现”或“演进”出来的。 设计不是一次性的前期活动 大白话&#xff1a; 作者认为&#x…...

数字巴别塔:全栈多模态开发框架如何用自然语言重构软件生产关系?

一、自然语言编程的范式革命 1. 从代码行数到语义密度 开发效率对比&#xff08;某金融 SaaS 案例&#xff09;&#xff1a; 开发方式代码量&#xff08;行&#xff09;开发时间&#xff08;天&#xff09;维护成本&#xff08;$/年&#xff09;传统 React5,2004512,000低代码…...

【C语言极简自学笔记】C 语言数组详解:一维数组与二维数组

在 C 语言中&#xff0c;数组是一种非常重要的数据结构&#xff0c;它可以将多个相同类型的元素组织在一起&#xff0c;以便于我们进行批量处理和操作。本文将详细介绍 C 语言中的一维数组和二维数组&#xff0c;包括它们的定义、初始化、元素访问以及内存存储等方面的内容。 …...

从零构建云原生秒杀系统——后端架构与实战

📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 一、引言:秒杀系统的挑战与机遇 在电商、票务、抢购等业务场景中,“秒杀”系统扮演着至关重要的角色。 秒杀活动通常会在极短时间内爆发出数十倍至数百倍的平时流量,这对后端系统的承载能力、响应…...

Linux Socket编程:从API到实战

Linux Socket编程完全指南&#xff1a;从API到实战 概述 Socket&#xff08;套接字&#xff09;是网络编程的基础&#xff0c;它允许不同主机或同一主机上的不同进程之间进行通信。在Linux系统中&#xff0c;Socket编程主要通过一系列系统调用来实现&#xff0c;这些API提供了…...

德州仪器(TI)—TDA4VM芯片详解(1)—产品特性

写在前面 本系列文章主要讲解德州仪器&#xff08;TI&#xff09;TDA4VM芯片的相关知识&#xff0c;希望能帮助更多的同学认识和了解德州仪器&#xff08;TI&#xff09;TDA4VM芯片。 若有相关问题&#xff0c;欢迎评论沟通&#xff0c;共同进步。(*^▽^*) 错过其他章节的同学…...

增强版wps-plugin-deepseek开源插件是DeepSeek 支持的 WPS 插件,在您的办公工作流程中提供智能文档自动化和 AI 驱动的生产力增强

一、软件介绍 文末提供程序和源码下载学习 增强版wps-plugin-deepseek开源插件专为WPS Office插件开发打造的Vue模板&#xff0c;搭配Vite构建工具&#xff0c;提供丰富的WPS API实操示例。虽然官方提供了TypeScript扩展包&#xff0c;但支持程度有限&#xff0c;因此本项目选…...

在 Cursor 中 配置 GitHub MCP Server

文章目录 1、简单回顾 sequentialthinking 的安装2、提出问题:如何在 cursor 配置 github mcp 呢3、结果如下How to Configure GitHub MCP in CursorPrerequisitesStep 1: Update Cursor (if needed)Step 2: Generate a GitHub Personal Access TokenStep 3: Open Cursor MCP S…...

uniapp-商城-40-shop 购物车 选好了 进行订单确认4 配送方式3 地址编辑

前面说了配送 和地址页面 当地址页面为空或需要添加地址时&#xff0c;需要添加地址。 我的地址页面有个按钮 就是添加地址 点击 添加地址 按钮 后&#xff0c;就会跳转到地址添加的页面 1、添加地址页面 2、添加地址文件夹以及文件的创建 3、添加地址的代码 <template…...

初步自定义layui的table(laravel 12)

layui的table是非常好的表格&#xff0c;有美观的样式&#xff0c;对接起来也很便捷。使用后端翻页传过来的数据&#xff0c;本地测试是好的&#xff0c;部署到服务器时&#xff0c;翻页不起作用。故而暂时采用一次性读取全部数据&#xff0c;发送给table&#xff0c;界面如下所…...

手写SpringMVC(基本框架)

服务器启动阶段处理 分析服务器启动阶段都都需要初始化什么&#xff1f; 1.初始化Spring容器 组件扫描包下的类纳入IOC容器管理创建视图解析器对象创建所有的拦截器对象扫描这和包下的所有类org.myspringmvc.web.servlet.mvc.method.annotation&#xff0c;全部实例化&#…...

JS-OCR-demo加载本地文件

背景&#xff1a; 在了解 Tesseract 的识别效果的时候&#xff0c;有个demo项目很好用。有个小毛病&#xff0c;就是没事都要从摄像头抓取图片&#xff0c;然后进行识别。如果可以从本地读取图&#xff0c;就更方便了。 实现&#xff1a; 下载项目代码&#xff1a;https://gi…...

MySQL 表的约束(一)

文章目录 表的约束空属性默认值列描述zerofill主键总结 表的约束 1. 为什么要有表的约束&#xff1f; 因为要保证数据的完整性和可约束性&#xff0c;合法性 空属性 两个值&#xff1a;null&#xff08;默认的&#xff09;和not null(不为空)数据库默认字段基本都是字段为空…...