MySQL数据脱敏(Data masking plugin functions)
对于企业而言,数据脱敏可以在数据共享或测试时用于保护敏感数据(如信用卡,社保卡,地址等)。通过对敏感数据进行脱敏处理,组织可以最大限度地降低数据泄露和未经授权访问的风险,同时仍能够使用真实的开发,测试和分析目的所需的数据。

有很多方法进行数据脱敏,比如遮挡,替换,洗牌和加密,等等,它们适用于不同场景。本文主要聚焦「遮挡」,用特定符号 (比如 X 或) 遮挡敏感数据,这种方法可以在脱敏的同时保持原有数据感观。
MySQL 企业级数据脱敏插件
MySQL 官方这边,数据脱敏只作为插件在 MySQL 企业版中提供 。 MySQL 数据脱敏插件的工作原理是插件中包含了用于进行数据脱敏的语法,例如 mask_inner, mask_outer, mask_ssn 等。

组织里有权限的人员(通常来说是数据库管理员)会首先定义一个显示脱敏数据的视图 (VIEW)。即使用户对敏感数据的访问受限,他们也可以将该视图视为一张表。因此,要访问数据,用户不是直接使用脱敏语法进行直接查询,而是从视图中查询即可。
这种方法很直接,但也有一定限制:
- 依赖于细粒度的 MySQL 用户账户 / 角色。实际上,大多数 MySQL 实例只有少数几个用户。要采用此插件,需要重新设计 MySQL 中的账户设置。
- 不同的脱敏规则需要定义不同的视图。随着底层表和变体数量增加,这会越来越难管理。
- 没有专门的模块来管理脱敏(毕竟只是普通的 MySQL VIEW)。
Percona 数据脱敏插件
Percona是前述 MySQL 插件的免费开源实现。它也提供了一组用于脱敏数据的函数。

同样,保护原始数据的方法是使用视图 (VIEW)。 然而,Percona 数据脱敏仅适用于 Percona Server for MySQL。如果你使用更主流的 MySQL,那就需要另寻他路了。
General purpose¶通用脱敏
The general purpose data masking functions are the following:
.
| Function | Description |
| mask_inner(string, margin1, margin2 [, character]) | Returns a result where only the inner part of a string is masked. A different masking character can be specified. |
| mask_outer(string, margin1, margin2 [, character]) | Masks the outer part of the string. The inner section is not masked. A different masking character can be specified. |
Examples¶
An example of mask_inner:
mysql> SELECT mask_inner('123456789', 1, 2);
Expected output
+-----------------------------------+
| mask_inner('123456789', 1, 2) |
+-----------------------------------+
|1XXXXXX89 |
+-----------------------------------+
An example of mask_outer:
mysql> SELECT mask_outer('123456789', 2, 2);
Expected output
+------------------------------------+
| mask_outer('123456789', 2, 2). |
+------------------------------------+
| XX34567XX |
+------------------------------------+
Special Purpose¶特殊脱敏
The special purpose data masking functions are as follows:
| Parameter | Description |
| mask_pan(string) | Masks the Primary Account Number (PAN) by replacing the string with an “X” except for the last four characters. The PAN string must be 15 characters or 16 characters in length. |
| mask_pan_relaxed(string) | Returns the first six numbers and the last four numbers. The rest of the string is replaced by “X”. |
| mask_ssn(string) | Returns a string with only the last four numbers visible. The rest of the string is replaced by “X”. |
Examples¶
An example of mask_pan.
mysql> SELECT mask_pan (gen_rnd_pan());
Expected output
+------------------------------------+
| mask_pan(gen_rnd_pan()) |
+------------------------------------+
| XXXXXXXXXXX2345 |
+------------------------------------+
An example of mask_pan_relaxed:
mysql> SELECT mask_pan_relaxed(gen_rnd_pan());
Expected output
+------------------------------------------+
| mask_pan_relaxed(gen_rnd_pan()) |
+------------------------------------------+
| 520754XXXXXX4848 |
+------------------------------------------+
An example of mask_ssn:
mysql> SELECT mask_ssn('555-55-5555');
Expected output
+-------------------------+
| mask_ssn('555-55-5555') |
+-------------------------+
| XXX-XX-5555 |
+-------------------------+
Generate random data for specific requirements¶随机脱敏
These functions generate random values for specific requirements.
| Parameter | Description |
| gen_range(lower, upper) | Generates a random number based on a selected range and supports negative numbers. |
| gen_rnd_email() | Generates a random email address. The domain is example.com. |
| gen_rnd_pan([size in integer]) | Generates a random primary account number. This function should only be used for test purposes. |
| gen_rnd_us_phone() | Generates a random U.S. phone number. The generated number adds the 1 dialing code and is in the 555 area code. The 555 area code is not valid for any U.S. phone number. |
| gen_rnd_ssn() | Generates a random, non-legitimate US Social Security Number in an AAA-BBB-CCCC format. This function should only be used for test purposes. |
Examples¶
An example of gen_range(lower, upper):
mysql> SELECT gen_range(10, 100);
Expected output
+--------------------------------------+
| gen_range(10,100) |
+--------------------------------------+
| 56 |
+--------------------------------------+
An example of gen_range(lower, upper) with negative numbers:
mysql> SELECT gen_range(-100,-80);
Expected output
+--------------------------------------+
| gen_range(-100,-80) |
+--------------------------------------+
| -91 |
+--------------------------------------+
An example of gen_rnd_email():
mysql> SELECT gen_rnd_email();
Expected output
+---------------------------------------+
| gen_rnd_email() |
+---------------------------------------+
| sma.jrts@example.com |
+---------------------------------------+
An example of mask_pan(gen_rnd_pan()):
mysql> SELECT mask_pan(gen_rnd_pan());
Expected output
+-------------------------------------+
| mask_pan(gen_rnd_pan()) |
+-------------------------------------+
| XXXXXXXXXXXX4444 |
+-------------------------------------+
An example of gen_rnd_us_phone():
mysql> SELECT gen_rnd_us_phone();
Expected output
+-------------------------------+
| gen_rnd_us_phone() |
+-------------------------------+
| 1-555-635-5709 |
+-------------------------------+
An example of gen_rnd_ssn():
mysql> SELECT gen_rnd_ssn()
Expected output
+-----------------------------+
| gen_rnd_ssn() |
+-----------------------------+
| 995-33-5656 |
+-----------------------------+
Use dictionaries to generate random terms¶字典脱敏
Use a selected dictionary to generate random terms. The dictionary must be loaded from a file with the following characteristics:
-
Plain text
-
One term per line
-
Must contain at least one entry
Copy the dictionary files to a directory accessible to MySQL. Percona Server for MySQL* 8.0.21-12 enabled using the secure-file-priv option for gen_dictionary_load(). The secure-file-priv option defines the directories where gen_dictionary_load() loads the dictionary files.
Note
Percona Server for MySQL 8.0.34 deprecates the gen_blacklist() function. Use gen_blocklist() instead.
| Parameter | Description | Returns |
| gen_blacklist(str, dictionary_name, replacement_dictionary_name) | Replaces a term with a term from a second dictionary. Deprecated in Percona Server for MySQL 8.0.34. | A dictionary term |
| gen_blocklist(str, dictionary_name, replacement_dictionary_name) | Replaces a term with a term from a second dictionary. | A dictionary term |
| gen_dictionary(dictionary_name) | Randomizes the dictionary terms | A random term from the selected dictionary. |
| gen_dictionary_drop(dictionary_name) | Removes the selected dictionary from the dictionary registry. | Either success or failure |
| gen_dictionary_load(dictionary path, dictionary name) | Loads a file into the dictionary registry and configures the dictionary name. The name can be used with any function. If the dictionary is edited, you must drop and then reload the dictionary to view the changes. | Either success or failure |
Example¶
An example of gen_blocklist():
mysql> SELECT gen_blocklist('apple', 'fruit', 'nut');
Expected output
+-----------------------------------------+
| gen_blocklist('apple', 'fruit', 'nut') |
+-----------------------------------------+
| walnut |
+-----------------------------------------+
An example of gen_dictionary():
mysql> SELECT gen_dictionary('trees');
Expected output
+--------------------------------------------------+
| gen_dictionary('trees') |
+--------------------------------------------------+
| Norway spruce |
+--------------------------------------------------+
An example of gen_dictionary_drop():
mysql> SELECT gen_dictionary_drop('mytestdict')
Expected output
+-------------------------------------+
| gen_dictionary_drop('mytestdict') |
+-------------------------------------+
| Dictionary removed |
+-------------------------------------+
An example of gen_dictionary_load(path, name):
mysql> SELECT gen_dictionary_load('/usr/local/mysql/dict-files/testdict', 'testdict');
Expected output
+-------------------------------------------------------------------------------+
| gen_dictionary_load('/usr/local/mysql/mysql/dict-files/testdict', 'testdict') |
+-------------------------------------------------------------------------------+
| Dictionary load successfully |
+-------------------------------------------------------------------------------+
相关文章:
MySQL数据脱敏(Data masking plugin functions)
对于企业而言,数据脱敏可以在数据共享或测试时用于保护敏感数据(如信用卡,社保卡,地址等)。通过对敏感数据进行脱敏处理,组织可以最大限度地降低数据泄露和未经授权访问的风险,同时仍能够使用真…...
Flutter 07 框架和三棵树(Widgets、Elements和RenderObjects)
一、Flutter框架的整体结构: Flutter是Google推出并开源的跨平台开发框架,主打跨平台、高保真、高性能。开发者可以通过Dart语 言开发Flutter应用,一套代码同时运行在ios和Android平台。不仅如此,Flutter还支持Web、桌面、嵌 入应…...
EasyExcel 导出冻结指定行
导出的实体类 package org.jeecg.modules.eis.test;import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.*; import lombok.Getter; import lombok.Setter; import org.apache.poi.ss.usermodel.HorizontalAlignment;import…...
ke9案例三:页面提交文件,我服务器端接收
案例三:页面提交文件,我服务器端接收 ProcessFile.java 1value "/process-file" 2获取邮件消息的所有部分part--Collection<Part> partsrequest.getParts(); 3遍历每一个part 4之后可以打印头文件等String headerpart.getHeader("content-disposition&q…...
springboot调用第三方接口json转换成对象
请求接口是一个比较常见的需求,接口返回一般是一个json类型,需要进行组装成对应的类,例 {"status_code": 200,"message": "success","data": {"cost": 286.6933,"bom_list": […...
uniapp使用vue3和ts开发小程序自定义tab栏,实现自定义凸出tabbar效果
要实现自定义的tabbar效果,可以使用自定义tab覆盖主tab来实现,当程序启动或者从后台显示在前台时隐藏自带的tab来实现。自定义一个tab组件,然后在里面实现自定义的逻辑。 组件中所使用的组件api可以看:Tabbar 底部导航栏 | uView…...
麒麟信安获批牵头成立国家关键领域信创行业产教融合共同体
日前,由麒麟信安、长沙理工大学、长沙职业技术学院联合牵头成立的国家关键领域信创行业产教融合共同体(以下简称:共同体)已获湖南省教育厅批准,并推荐至教育部。 目前共同体已吸引10余家联盟单位及全国20余家企业、高…...
好消息,微信消费者投诉工具升级,可以直接回复用户、处理投诉了。。。
大家好,我是小悟 兄弟们,阅读本文之前,建议先阅读【连夜干出来一个自动处理【微信消费者投诉管理系统】,支持多商户】。 为了使工具更好用,也为帮助商户更好地处理消费者投诉,提升用户满意度,…...
手动修复 rabbitmq 报错 “Crash dump is being written to“
rabbitmq 报错: 2023-11-07 16:38:52.682 [error] emulator Error in process <0.368.0> on node rabbitrabbitmq-0.rabbitmq-discovery.openstack.svc.cluster.local with exit value: {shutdown,[{mnesia_loader,handle_exit,2,[{file,"mnesia_loader.erl"}…...
日志门面技术
1.JCL public abstract class LogFactory {public static Log getLog(Class clazz) throws LogConfigurationException {// 默认实现类为LogFactoryImplreturn getFactory().getInstance(clazz);} }利用LogFactoryImpl实例化具体的日志框架。其中,如果存在log4j依赖…...
机器人制作开源方案 | 管内检测维护机器人
一、作品简介 作者:李泽彬,李晋晟,杜张坤,禹馨雅 单位:运城学院 指导老师:薛晓峰 随着我国的社会主义市场经济的飞速发展和科学技术的革新,各行各业的发展越来越离不开信息化和网络化的…...
k8s存储卷
目录 1、emptyDir存储卷 2、hostPath存储卷 3、nfs共享存储卷 4、PVC 和 PV 4.1 PV和PVC之间的相互作用遵循这个生命周期: 4.2 PV的状态 4.3 一个PV从创建到销毁的具体流程如下: 静态PVC: 动态PVC 1、emptyDir存储卷 当Pod被分配给节…...
View 自定义 - 属性 xml
一、概念 在 xml 中为控件设置的属性。自定义属性名称如果使用系统已定义的,例如 textSize 会在编译时报错。 格式类型定义/使用 string 字符串 <attr name "myContent" format "color" /> android:myContent "Hello Word!&quo…...
2007-2022年全国各地级市金融机构网点数据
2007-2022年地级市金融机构网点数据 1、时间:2007-2022年 2、指标:行政区划代码、年份、城市名称、所属省份、银行网点数量、其中-政策性银行及国家开发银行营业网点占比、其中-商业银行营业网点数量占比、其中-农村金融机构营业网点数量占比 3、范围…...
OpenAI开发者大会掀起风暴:GPT模型价格狂降50%,应用商店即将亮相,AI技术将引爆全球!
OpenAI首届开发者大会召开了! 关键信息: GPT-4升级版GPT-4 Turbo来了,上下文窗口达到128k,为GPT-4的4倍;OpenAI还降低了几乎所有模型的API使用价格,整体便宜了一半多;GPT-4系列的多模态能力向B…...
yo!这里是STL::unordered系列简单模拟实现
目录 前言 相关概念介绍 哈希概念 哈希冲突与哈希函数 闭散列 框架 核心函数 开散列 框架 核心函数 哈希表(开散列)的修改 迭代器实现 细节修改 unordered系列封装 后记 前言 我们之前了解过map和set知道,map、set的底层结构是…...
基础课25——业务流程分析
1.流程的定义&作用 业务流程是企业中一系列创造价值的活动的组合,它是企业运营的基础,也是企业提高效率、优化资源配置的重要手段。通过优化业务流程,企业可以更好地满足客户需求,提高客户满意度,同时也可以提高自…...
快速实现一个企业级域名 SSL 证书有效期监控巡检系统
Why 现在对于企业来说,HTTPS 已经不是可选项,已经成为一个必选项。HTTPS 协议采用 SSL 协议,采用公开密钥的技术,提供了一套 TCP/IP 传输层数据加密的机制。SSL 证书是一种遵守 SSL 协议的服务器数字证书,一般是由权威…...
[SSD综述 1.5] SSD 主控和固件核心功能详解(万字)
依公知及经验整理,原创保护,禁止转载。 1. 主控概述1.1 主控作用 2. 主控的硬件功能和实现2.1 主控处理器2.2 闪存、主机接口2.3 主控纠错2.4 断电保护 3 固件功能3.1 FTL3.2 预留空间(Over-provisioning)3.3 Trim3.4 写入放大(Write amplification)3.5 …...
Mybatis-Plus前后端分离多表联查模糊查询分页
数据准备 数据库配置: /*Navicat Premium Data TransferSource Server : localhost_3306Source Server Type : MySQLSource Server Version : 80100 (8.1.0)Source Host : localhost:3306Source Schema : test01Target Server Type : MySQLT…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...
[特殊字符] 手撸 Redis 互斥锁那些坑
📖 手撸 Redis 互斥锁那些坑 最近搞业务遇到高并发下同一个 key 的互斥操作,想实现分布式环境下的互斥锁。于是私下顺手手撸了个基于 Redis 的简单互斥锁,也顺便跟 Redisson 的 RLock 机制对比了下,记录一波,别踩我踩过…...
向量几何的二元性:叉乘模长与内积投影的深层联系
在数学与物理的空间世界中,向量运算构成了理解几何结构的基石。叉乘(外积)与点积(内积)作为向量代数的两大支柱,表面上呈现出截然不同的几何意义与代数形式,却在深层次上揭示了向量间相互作用的…...
