文档首页
MySQL 8.4 参考手册
相关文档 下载本手册
PDF (美国信函) - 39.9Mb
PDF (A4) - 40.0Mb
手册页 (TGZ) - 258.5Kb
手册页 (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 参考手册  /  ...  /  使用 MySQL Enterprise 数据掩码和去标识插件

8.5.3.2 使用 MySQL Enterprise 数据掩码和去标识插件

在使用 MySQL Enterprise 数据掩码和去标识之前,请按照 第 8.5.3.1 节“MySQL Enterprise 数据掩码和去标识插件安装” 中提供的说明进行安装。

要在应用程序中使用 MySQL Enterprise 数据掩码和去标识,请调用适合您要执行的操作的函数。有关函数的详细描述,请参见 第 8.5.3.4 节“MySQL Enterprise 数据掩码和去标识插件功能描述”。本节演示了如何使用这些函数执行一些代表性任务。首先介绍可用函数的概述,然后介绍一些函数在实际环境中的应用示例

掩码数据以删除标识特征

MySQL 提供通用掩码函数,用于掩码任意字符串,以及专用掩码函数,用于掩码特定类型的值。

通用掩码函数

mask_inner()mask_outer() 是通用函数,它们根据字符串中的位置掩码任意字符串的部分

  • mask_inner() 掩码其字符串参数的内部,保留两端未掩码。其他参数指定未掩码端的尺寸。

    mysql> SELECT mask_inner('This is a string', 5, 1);
    +--------------------------------------+
    | mask_inner('This is a string', 5, 1) |
    +--------------------------------------+
    | This XXXXXXXXXXg                     |
    +--------------------------------------+
    mysql> SELECT mask_inner('This is a string', 1, 5);
    +--------------------------------------+
    | mask_inner('This is a string', 1, 5) |
    +--------------------------------------+
    | TXXXXXXXXXXtring                     |
    +--------------------------------------+
  • mask_outer() 做相反的事情,掩码其字符串参数的两端,保留内部未掩码。其他参数指定掩码端的尺寸。

    mysql> SELECT mask_outer('This is a string', 5, 1);
    +--------------------------------------+
    | mask_outer('This is a string', 5, 1) |
    +--------------------------------------+
    | XXXXXis a strinX                     |
    +--------------------------------------+
    mysql> SELECT mask_outer('This is a string', 1, 5);
    +--------------------------------------+
    | mask_outer('This is a string', 1, 5) |
    +--------------------------------------+
    | Xhis is a sXXXXX                     |
    +--------------------------------------+

默认情况下,mask_inner()mask_outer() 使用 'X' 作为掩码字符,但允许可选的掩码字符参数

mysql> SELECT mask_inner('This is a string', 5, 1, '*');
+-------------------------------------------+
| mask_inner('This is a string', 5, 1, '*') |
+-------------------------------------------+
| This **********g                          |
+-------------------------------------------+
mysql> SELECT mask_outer('This is a string', 5, 1, '#');
+-------------------------------------------+
| mask_outer('This is a string', 5, 1, '#') |
+-------------------------------------------+
| #####is a strin#                          |
+-------------------------------------------+
专用掩码函数

其他掩码函数期望一个字符串参数,该参数表示特定类型的值,并将其掩码以删除标识特征。

注意

此处的示例使用返回适当类型值的随机值生成函数来提供函数参数。有关生成函数的更多信息,请参见 生成具有特定特征的随机数据

付款卡主账户号码掩码。掩码函数提供严格和宽松的主账户号码掩码。

  • mask_pan() 掩码除了最后四位数字之外的所有数字

    mysql> SELECT mask_pan(gen_rnd_pan());
    +-------------------------+
    | mask_pan(gen_rnd_pan()) |
    +-------------------------+
    | XXXXXXXXXXXX2461        |
    +-------------------------+
  • mask_pan_relaxed() 类似,但不会掩码指示付款卡发行机构的未掩码的前六位数字

    mysql> SELECT mask_pan_relaxed(gen_rnd_pan());
    +---------------------------------+
    | mask_pan_relaxed(gen_rnd_pan()) |
    +---------------------------------+
    | 770630XXXXXX0807                |
    +---------------------------------+

美国社会安全号码掩码。 mask_ssn() 掩码除了最后四位数字之外的所有数字

mysql> SELECT mask_ssn(gen_rnd_ssn());
+-------------------------+
| mask_ssn(gen_rnd_ssn()) |
+-------------------------+
| XXX-XX-1723             |
+-------------------------+
生成具有特定特征的随机数据

几个函数生成随机值。这些值可用于测试、模拟等。

gen_range() 返回从给定范围内随机选择的整数

mysql> SELECT gen_range(1, 10);
+------------------+
| gen_range(1, 10) |
+------------------+
|                6 |
+------------------+

gen_rnd_email() 返回 example.com 域中的随机电子邮件地址

mysql> SELECT gen_rnd_email();
+---------------------------+
| gen_rnd_email()           |
+---------------------------+
| [email protected] |
+---------------------------+

gen_rnd_pan() 返回随机的支付卡主账号

mysql> SELECT gen_rnd_pan();

(gen_rnd_pan() 函数的结果未显示,因为其返回值仅应用于测试目的,而不是用于发布。不能保证该号码未分配给合法的支付账户。)

gen_rnd_ssn() 返回随机的美国社会安全号码,其第一部分和第二部分分别从不用于合法号码的范围内选择

mysql> SELECT gen_rnd_ssn();
+---------------+
| gen_rnd_ssn() |
+---------------+
| 912-45-1615   |
+---------------+

gen_rnd_us_phone() 返回 555 区号的随机美国电话号码,不用于合法号码

mysql> SELECT gen_rnd_us_phone();
+--------------------+
| gen_rnd_us_phone() |
+--------------------+
| 1-555-747-5627     |
+--------------------+
使用字典生成随机数据

MySQL 企业版数据屏蔽和去标识化允许使用字典作为随机值的来源。要使用字典,首先必须从文件加载字典并为其命名。每个加载的字典都成为字典注册表的一部分。然后可以从注册的字典中选择项目,并将其用作随机值或用作其他值的替代值。

有效的字典文件具有以下特征

  • 文件内容为纯文本,每行一个词。

  • 空行将被忽略。

  • 文件必须至少包含一个词。

假设名为 de_cities.txt 的文件包含德国的以下城市名称

Berlin
Munich
Bremen

还假设名为 us_cities.txt 的文件包含美国以下城市名称

Chicago
Houston
Phoenix
El Paso
Detroit

假设 secure_file_priv 系统变量设置为 /usr/local/mysql/mysql-files。在这种情况下,将字典文件复制到该目录,以便 MySQL 服务器可以访问它们。然后使用 gen_dictionary_load() 将字典加载到字典注册表中并为其分配名称

mysql> SELECT gen_dictionary_load('/usr/local/mysql/mysql-files/de_cities.txt', 'DE_Cities');
+--------------------------------------------------------------------------------+
| gen_dictionary_load('/usr/local/mysql/mysql-files/de_cities.txt', 'DE_Cities') |
+--------------------------------------------------------------------------------+
| Dictionary load success                                                        |
+--------------------------------------------------------------------------------+
mysql> SELECT gen_dictionary_load('/usr/local/mysql/mysql-files/us_cities.txt', 'US_Cities');
+--------------------------------------------------------------------------------+
| gen_dictionary_load('/usr/local/mysql/mysql-files/us_cities.txt', 'US_Cities') |
+--------------------------------------------------------------------------------+
| Dictionary load success                                                        |
+--------------------------------------------------------------------------------+

要从字典中选择随机词,请使用 gen_dictionary()

mysql> SELECT gen_dictionary('DE_Cities');
+-----------------------------+
| gen_dictionary('DE_Cities') |
+-----------------------------+
| Berlin                      |
+-----------------------------+
mysql> SELECT gen_dictionary('US_Cities');
+-----------------------------+
| gen_dictionary('US_Cities') |
+-----------------------------+
| Phoenix                     |
+-----------------------------+

要从多个字典中选择随机词,请随机选择一个字典,然后从该字典中选择一个词

mysql> SELECT gen_dictionary(ELT(gen_range(1,2), 'DE_Cities', 'US_Cities'));
+---------------------------------------------------------------+
| gen_dictionary(ELT(gen_range(1,2), 'DE_Cities', 'US_Cities')) |
+---------------------------------------------------------------+
| Detroit                                                       |
+---------------------------------------------------------------+
mysql> SELECT gen_dictionary(ELT(gen_range(1,2), 'DE_Cities', 'US_Cities'));
+---------------------------------------------------------------+
| gen_dictionary(ELT(gen_range(1,2), 'DE_Cities', 'US_Cities')) |
+---------------------------------------------------------------+
| Bremen                                                        |
+---------------------------------------------------------------+

gen_blocklist() 函数允许用另一个字典中的词替换一个字典中的词,这会影响通过替换进行的屏蔽。其参数是需要替换的词、该词所在的字典以及用于选择替换词的字典。例如,要将美国城市替换为德国城市,或反之,请像这样使用 gen_blocklist()

mysql> SELECT gen_blocklist('Munich', 'DE_Cities', 'US_Cities');
+---------------------------------------------------+
| gen_blocklist('Munich', 'DE_Cities', 'US_Cities') |
+---------------------------------------------------+
| Houston                                           |
+---------------------------------------------------+
mysql> SELECT gen_blocklist('El Paso', 'US_Cities', 'DE_Cities');
+----------------------------------------------------+
| gen_blocklist('El Paso', 'US_Cities', 'DE_Cities') |
+----------------------------------------------------+
| Bremen                                             |
+----------------------------------------------------+

如果要替换的词不在第一个字典中,gen_blocklist() 将返回它而不做任何改变

mysql> SELECT gen_blocklist('Moscow', 'DE_Cities', 'US_Cities');
+---------------------------------------------------+
| gen_blocklist('Moscow', 'DE_Cities', 'US_Cities') |
+---------------------------------------------------+
| Moscow                                            |
+---------------------------------------------------+
使用屏蔽数据进行客户识别

在客户服务呼叫中心,一种常见的身份验证技术是要求客户提供他们的最后四位社会安全号码 (SSN) 数字。例如,客户可能会说她的名字是 Joanna Bond,她的最后四位 SSN 数字是 0007

假设包含客户记录的 customer 表具有以下列

  • id:客户 ID 号码。

  • first_name:客户名。

  • last_name:客户姓。

  • ssn:客户社会安全号码。

例如,该表可以定义如下

CREATE TABLE customer
(
  id         BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  first_name VARCHAR(40),
  last_name  VARCHAR(40),
  ssn        VARCHAR(11)
);

客户服务代表用于检查客户 SSN 的应用程序可能会执行类似这样的查询

mysql> SELECT id, ssn
mysql> FROM customer
mysql> WHERE first_name = 'Joanna' AND last_name = 'Bond';
+-----+-------------+
| id  | ssn         |
+-----+-------------+
| 786 | 906-39-0007 |
+-----+-------------+

但是,这会将 SSN 公开给客户服务代表,而客户服务代表只需要看到最后四位数字。相反,应用程序可以使用此查询仅显示屏蔽的 SSN

mysql> SELECT id, mask_ssn(CONVERT(ssn USING binary)) AS masked_ssn
mysql> FROM customer
mysql> WHERE first_name = 'Joanna' AND last_name = 'Bond';
+-----+-------------+
| id  | masked_ssn  |
+-----+-------------+
| 786 | XXX-XX-0007 |
+-----+-------------+

现在,代表只能看到必要的数字,并保护了客户隐私。

为什么 CONVERT() 函数用于 mask_ssn() 的参数?因为 mask_ssn() 需要长度为 11 的参数。因此,即使 ssn 定义为 VARCHAR(11),如果 ssn 列具有多字节字符集,它在传递给可加载函数时似乎比 11 字节更长,并且会发生错误。将值转换为二进制字符串可确保函数看到长度为 11 的参数。

当字符串参数没有单字节字符集时,其他数据屏蔽函数可能需要类似的技术。

创建显示屏蔽数据的视图

如果来自表的屏蔽数据用于多个查询,则定义一个生成屏蔽数据的视图可能很方便。这样,应用程序就可以从视图中选择数据,而无需在单个查询中执行屏蔽。

例如,可以对上一节中的 customer 表定义一个屏蔽视图,如下所示

CREATE VIEW masked_customer AS
SELECT id, first_name, last_name,
mask_ssn(CONVERT(ssn USING binary)) AS masked_ssn
FROM customer;

然后,查找客户的查询变得更简单,但仍然返回屏蔽数据

mysql> SELECT id, masked_ssn
mysql> FROM masked_customer
mysql> WHERE first_name = 'Joanna' AND last_name = 'Bond';
+-----+-------------+
| id  | masked_ssn  |
+-----+-------------+
| 786 | XXX-XX-0007 |
+-----+-------------+