如何生成比较像样的假数据

2024-02-09 00:18
文章标签 数据 比较 生成 像样

本文主要是介绍如何生成比较像样的假数据,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 问题

在做项目的时候经常会遇到这样的问题:

  • 根据数据模型建立了数据库,但是数据库中却没有数据,在给客户做Demo的时候必须要一条一条的添加假数据,而且这些假数据还得像模像样的,不能乱输入,尽是看不出任何意义的“aaaaa”、“ttttttttttttt”、“123123”、“是打发斯蒂芬”这样的数据。
  • 已经做好了一个系统,并且上线给部分客户使用了,现在要将该系统推广到所有的客户,所以需要做一个虚拟客户的系统,系统中需要有许多像样的数据,但是由于保密方面的原因,原有客户的数据必须经过处理,不能出现真实的信息。
  • 系统开发完成了,需要制造大量的假数据,以进行压力测试,看在有几百万上千万数据量的情况下的系统性能。

方案

其中要生成大量的没有意义的测试数据,以便进行压力测试,这个数据是最好生成的,只需要写几条SQL语句,多运行几次即可。如果不想写SQL语句,也可以使用数据生成工具:VisualStudio、PowerDesigner、DataFactory等都可以使用。我推荐使用DataFactory,有较强的定制性。

下面主要说一下另外一种假数据,那就是前面2种情况,具有一定业务规则和可读性的假数据。要生成比较像样的假数据主要是基于已有的系统,在真实数据的基础上进行随机的混淆和交叉,从而产生大量看起来比较真实但是实际上却全是假的数据。对于第一种情况,可以将其他系统中的对应实体表的数据导入到Demo环境中,然后再进行混淆交叉。

我们可以将系统中的数据分为:数字、日期和字符串3种类型分别进行混淆。

  1. 数字类型的数据混淆最简单,使用随机函数RAND()即可,如果是整数则可以再乘以一个系数后取整,也可以用原来的数据加上生成的随机数,从而使得数据的范围保持在原真实数据相同的分布。比如有Revenue字段,是从客户处的收入,大客户和小客户参数的收入数不能完全随机,可以在原有Revenue的基础上随机增加10000以内的数即可:Revenue+RAND()*10000
  2. 日期类型的数据混淆可以在原日期或者当前日期的基础上加减一个随机的天数形成,使用DATEADD()函数和RAND()函数即可。比如生成随机的最近100天内的日期:DATEADD("day",0-RAND()*100,GETDATE())
  3. 字符串类型的数据混淆最为复杂,因为字符串具有很明确的意义,比如名字字段、公司名字段等,如果随机的生成字符将没有任何意义。这时可以考虑将字符串拆分成两部分然后进行交叉组合,用随机的交叉组合来代替真是的数据。比如原来的姓名是:李宇春、曾轶可、刘著,经过交叉组合就会形成:李著、曾宇春、刘轶可之类的组合。

姓名的拆分是分为姓和名,而公司的拆分可以拆分成前2个字和后面的字。如果是英文姓名或者英文公司名则可以按照第一个空格将英文字符串拆分成第一个单词和后面的单词。然后将产生的两个字段存入临时表,用两个临时表进行交叉联接,得到两个字段的所有组合,然后再随机选出一定条数的数据,用选出的随机数据将原有数据替换即可。

示例

以一个HR系统为例。假设其中有一个Employee表,该表记录了员工的工号、姓名等信息,现在要对姓名进行处理,具体操作如下:

1.区分出中文名和英文名,分别进行拆分。中文姓名以第一个字为A列,剩下的字尾B列,英文名以第一个单词为A列,剩下的单词为B列,将拆分的数据存入临时表,具体SQL语句如下:

select SUBSTRING(Name,1,1) A,SUBSTRING(Name,2,10) B into #CName
from Employee
where UNICODE( Name)>255 --中文 
select Name,SUBSTRING(Name,1,CHARINDEX(' ',Name,1)) A,SUBSTRING(Name,CHARINDEX(' ',Name,1),50) B into #EName
from Employee
where UNICODE( Name)<255 --英文

2.让A列和B列进行交叉联接,得到姓名组合的全集,然后随机选出与源数据相同数据量的姓名存入临时表(临时表中有ID流水号字段)。假设员工表里有5000员工数据,则可以选取5000个随机姓名,代码如下:

create table #newCName(ID int identity primary key,Name nvarchar(50))
insert into #newCName(Name)
select top 5000 n1.A+n2.B
from #CName n1
cross join #CName n2
order by NEWID() --随机选取行

3.由于Employee中没有自增的ID字段,只有字符串形式的员工号作为主键,所以需要给每个员工号编一个流水号,用于和随机姓名中的流水号对应,以便接下来的UPDATE操作:

create table #newEmployeeID(ID int identity primary key,EmployeeID varchar(10))
insert into #newEmployeeID
select EmployeeId
from Employee
where UNICODE( Name)>255 --中文

4.更新Employee表中的姓名字段为随机生成的姓名:

update Employee
set Name=n.Name
from Employee e
inner join #newEmployeeID i
on e.EmployeeId=i.EmployeeID
inner join #newCName n
on i.ID=n.ID
where UNICODE(e.Name)>255 --只更新中文姓名

5.用同样的方法,可以对英文姓名进行混淆交叉替换。

优化

这里需要注意的是第2步,使用了CROSS JOIN操作,也就是求两个表的笛卡尔积,如果一个表中有10W条数据,那么将会产生100亿行结果,然后再进行排序,那将是近乎不可能完成的任务,所以必须减少进行笛卡尔积的表的数据量,比如每个表只取500条不重复的数据,那么修改后的SQL语句是:

select top 5000 n1.A+n2.B
from
(select distinct top 500 A from #CName )n1 --取不重复的500个姓
cross join
(select distinct top 500 B from #CName ) n2--取不重复的500个名
order by NEWID() --随机选取行

这样最多只是500*500条记录,进行排序选取随机行将会很快完成。

这篇关于如何生成比较像样的假数据的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/692623

相关文章

MySQL中比较运算符的具体使用

《MySQL中比较运算符的具体使用》本文介绍了SQL中常用的符号类型和非符号类型运算符,符号类型运算符包括等于(=)、安全等于(=)、不等于(/!=)、大小比较(,=,,=)等,感兴趣的可以了解一下... 目录符号类型运算符1. 等于运算符=2. 安全等于运算符<=>3. 不等于运算符<>或!=4. 小于运

python生成随机唯一id的几种实现方法

《python生成随机唯一id的几种实现方法》在Python中生成随机唯一ID有多种方法,根据不同的需求场景可以选择最适合的方案,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习... 目录方法 1:使用 UUID 模块(推荐)方法 2:使用 Secrets 模块(安全敏感场景)方法

MyBatis-Plus通用中等、大量数据分批查询和处理方法

《MyBatis-Plus通用中等、大量数据分批查询和处理方法》文章介绍MyBatis-Plus分页查询处理,通过函数式接口与Lambda表达式实现通用逻辑,方法抽象但功能强大,建议扩展分批处理及流式... 目录函数式接口获取分页数据接口数据处理接口通用逻辑工具类使用方法简单查询自定义查询方法总结函数式接口

SQL中如何添加数据(常见方法及示例)

《SQL中如何添加数据(常见方法及示例)》SQL全称为StructuredQueryLanguage,是一种用于管理关系数据库的标准编程语言,下面给大家介绍SQL中如何添加数据,感兴趣的朋友一起看看吧... 目录在mysql中,有多种方法可以添加数据。以下是一些常见的方法及其示例。1. 使用INSERT I

Python使用vllm处理多模态数据的预处理技巧

《Python使用vllm处理多模态数据的预处理技巧》本文深入探讨了在Python环境下使用vLLM处理多模态数据的预处理技巧,我们将从基础概念出发,详细讲解文本、图像、音频等多模态数据的预处理方法,... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

MySQL 删除数据详解(最新整理)

《MySQL删除数据详解(最新整理)》:本文主要介绍MySQL删除数据的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、前言二、mysql 中的三种删除方式1.DELETE语句✅ 基本语法: 示例:2.TRUNCATE语句✅ 基本语

C# 比较两个list 之间元素差异的常用方法

《C#比较两个list之间元素差异的常用方法》:本文主要介绍C#比较两个list之间元素差异,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. 使用Except方法2. 使用Except的逆操作3. 使用LINQ的Join,GroupJoin

MyBatisPlus如何优化千万级数据的CRUD

《MyBatisPlus如何优化千万级数据的CRUD》最近负责的一个项目,数据库表量级破千万,每次执行CRUD都像走钢丝,稍有不慎就引起数据库报警,本文就结合这个项目的实战经验,聊聊MyBatisPl... 目录背景一、MyBATis Plus 简介二、千万级数据的挑战三、优化 CRUD 的关键策略1. 查

python实现对数据公钥加密与私钥解密

《python实现对数据公钥加密与私钥解密》这篇文章主要为大家详细介绍了如何使用python实现对数据公钥加密与私钥解密,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录公钥私钥的生成使用公钥加密使用私钥解密公钥私钥的生成这一部分,使用python生成公钥与私钥,然后保存在两个文

mysql中的数据目录用法及说明

《mysql中的数据目录用法及说明》:本文主要介绍mysql中的数据目录用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、版本3、数据目录4、总结1、背景安装mysql之后,在安装目录下会有一个data目录,我们创建的数据库、创建的表、插入的