【问题标题】:如何从MYSQL中的多个表中动态屏蔽特定列
【发布时间】:2022-01-20 06:55:41
【问题描述】:

我有多个表,例如 EMPLOYEE、EMPLOYEEMail 和更多表。 出于参考目的,我放了一些示例数据和 2 个表格

CREATE TABLE EMPLOYEE (
  empId INTEGER PRIMARY KEY,
  name TEXT NOT NULL,
  dept TEXT NOT NULL,
  phone bigint
);


INSERT INTO EMPLOYEE VALUES (0001, 'Clark', 'Sales',9001234567);
INSERT INTO EMPLOYEE VALUES (0002, 'Dave', 'Accounting',9000123456);
INSERT INTO EMPLOYEE VALUES (0003, 'Ava', 'Sales',9000012345);

CREATE TABLE EMPLOYEEMail (
  empId INTEGER PRIMARY KEY,
  MailID TEXT NOT NULL,
  AlternateMail TEXT NOT NULL
);


INSERT INTO EMPLOYEEMail VALUES (0001, 'hello123@gmail.com','hi123@gmail.com');
INSERT INTO EMPLOYEEMail VALUES (0002, 'good123@gmail.com','bye123@gmail.com');
INSERT INTO EMPLOYEEMail VALUES (0003, 'super123@gmail.com','fast123@gmail.com');

查询

SELECT CONCAT(SUBSTR(phone, 1, 6), REPEAT('*', CHAR_LENGTH(phone) - 6)) AS masked_phone
FROM `EMPLOYEE`;

select  
CONCAT(LEFT(UUID(), 8), '@', SUBSTRING_INDEX(`MailID`, '@', -1)) as phone,
CONCAT(LEFT(UUID(), 8), '@', SUBSTRING_INDEX(`AlternateMail`, '@', -1)) as AlternateMail
from EMPLOYEEMail;

输出:

ma​​sked_phone

900123****
900012****
900001****

电话备用邮件

d8883d67@gmail.com  d8883d92@gmail.com
d8883dd0@gmail.com  d8883dde@gmail.com
d8883df3@gmail.com  d8883dff@gmail.com

选择查询可以正常工作,但我需要屏蔽多个列,所有列都将以逗号分隔的值出现,像这样

(MailID ,AlternateMail,Phone,SSN,BankAccount,Addrress)

我正在寻找一个循环语句,我将在其中将这些值与 Information_schema.columns 表,该列与给定值匹配。

我正在尝试使用@column 和@tablename 将它们循环到动态选择语句中,并将屏蔽值加载到临时表中。 请就此向我提出建议。

【问题讨论】:

  • 你的第一个查询可以写得更简单SELECT INSERT(phone,7,10,"****") as masked_phone FROM EMPLOYEE;dbfiddle.uk/…
  • @ErgestBasha 是的,同意我们可以用多种方式写作。但我正在寻找动态循环
  • 你需要在动态SQL(准备好的语句)。
  • 是的,正在寻找那个@Akina
  • 通常需要按混淆值加入或分组,例如计算不同的电子邮件。我建议使用像 sha256 这样的确定性单向函数来代替非确定性混淆。 sha256 不允许恢复原始值,但允许 join 和 groupby 与非混淆值一样工作

标签: mysql sql


【解决方案1】:

您为什么不使用 View 的概念来实现这一点? 视图的好处之一是隐藏原始表格中的特定信息或以其他方式将其可视化,而无需触及原始数据。

在您的情况下,您只需要使用上面的查询创建一个视图来隐藏电话号码、电子邮件等的特定部分。

CREATE VIEW employee_info_encrypted AS
    SELECT  CONCAT(SUBSTR(phone, 1, 6), REPEAT('*', CHAR_LENGTH(phone) - 6)) AS masked_phone,
            CONCAT(LEFT(UUID(), 8), '@', SUBSTRING_INDEX(`MailID`, '@', -1)) as phone,
            CONCAT(LEFT(UUID(), 8), '@', SUBSTRING_INDEX(`AlternateMail`, '@', -1)) as AlternateMail
    FROM `EMPLOYEE`
    inner join EMPLOYEEMail on EMPLOYEEMail.empId = EMPLOYEE.empId;

然后,通过运行以下查询,您将获得屏蔽信息:

select * from employee_info_encrypted;

每当您想在响应中添加新列时,您只需更改查看代码,它将根据新条件更改响应。

【讨论】:

    【解决方案2】:

    我认为 substring屏蔽 电子邮件地址更漂亮,这样敏感数据将保持秘密。

    SELECT CONCAT("****", SUBSTRING(`EMPLOYEEMail`.`MailID`, LOCATE('@', `EMPLOYEEMail`.`MailID`) - 4 )) AS MailID, 
    CONCAT("****", SUBSTRING(`EMPLOYEEMail`.`AlternateMail`, LOCATE('@', `EMPLOYEEMail`.`AlternateMail`) - 4 )) AS AlternateMail, 
    INSERT(`EMPLOYEE`.`phone`,7,10,"****") as masked_phone
    FROM EMPLOYEE
    JOIN EMPLOYEEMail ON EMPLOYEE.empId=EMPLOYEEMail.empId;
    

    使用您的解决方案(从电子邮件地址中完全屏蔽用户名),查询变得毫无意义,因为没有任何内容涉及原始数据

    【讨论】:

    • 我有多个表我想处理所有表的相同列
    • 您可以使用多个连接扩展此查询,并向选择添加更多字段。
    • 它们是键列彼此不同,那么我该如何加入那些甚至列名匹配的列
    • 那么您需要为相同的命名列引入 alias 名称。例如:SELECT table1.name AS t1_name, table2.name AS t2_name, .... etc...
    • 先生,您能再过一遍这个问题吗?我想要一个使用 Information_scheam 表的动态查询
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-22
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 2013-04-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多