轻商城性能测试数据准备:用Python脚本+DBeaver快速生成10万条用户和商品数据
轻商城性能测试数据实战:Python+DBeaver高效生成10万级测试数据
电商平台的性能瓶颈往往出现在高并发场景下的数据处理能力。去年双十一期间,某中型电商平台因未充分进行压力测试,导致订单系统在流量峰值时崩溃,直接损失超过300万元。这个惨痛教训告诉我们:性能测试数据的质量直接决定测试结果的可信度。本文将手把手带你用Python脚本和DBeaver工具,为轻商城系统构建10万条符合业务逻辑的测试数据。
1. 测试数据准备的核心挑战
性能测试不是简单的"跑脚本",而是对系统极限的精准探测。我曾参与过一个社区团购项目的压测,由于初始数据只准备了5000条商品信息,测试进行到第3分钟就因库存耗尽而失败。这种"数据贫血症"会导致:
- 虚假的性能指标:当数据库只有少量数据时,索引效果会被高估
- 逻辑关联缺失:用户没有对应地址、商品缺少分类关联等
- 业务规则失效:如手机号重复、支付金额超出合理范围等
轻商城作为典型电商系统,需要准备以下基础数据表:
| 数据表 | 数据量 | 关键字段 | 关联关系 |
|---|---|---|---|
| litemall_user | 10万 | username, mobile, password | 与address一对多 |
| litemall_address | 20万 | user_id, address_detail | 必须关联有效user_id |
| litemall_goods | 10万 | name, price, stock | 需要关联分类和品牌 |
2. Python批量生成用户数据实战
使用PyCharm创建新的Python文件generate_users.py,核心代码如下:
import pymysql import random from faker import Faker # 初始化伪造数据工具 fake = Faker('zh_CN') def generate_phone(user_id): """生成符合中国规则的手机号""" prefix = random.choice(['130', '135', '138', '150', '186']) return f"{prefix}{str(user_id).zfill(8)[:8]}" conn = pymysql.connect( host="your_db_host", user="root", password="your_password", database="litemall", charset='utf8mb4' ) try: with conn.cursor() as cursor: for user_id in range(100000, 200000): # 10万用户 username = f"user_{user_id}" mobile = generate_phone(user_id) nickname = fake.name() user_sql = f""" INSERT INTO litemall_user (username, password, mobile, nickname) VALUES (%s, %s, %s, %s) """ cursor.execute(user_sql, ( username, '$2a$10$lTu9qi0hr19OC800Db.eludFr0AXuJUSrMHi/iPYhKRlPFeqJxlye', # 加密后的123456 mobile, nickname )) # 每个用户生成1-3个地址 for addr_num in range(random.randint(1, 3)): address_sql = """ INSERT INTO litemall_address (user_id, name, province, city, address_detail, tel) VALUES (%s, %s, %s, %s, %s, %s) """ cursor.execute(address_sql, ( user_id, nickname, fake.province(), fake.city(), fake.street_address(), mobile )) if user_id % 1000 == 0: conn.commit() print(f"已提交{user_id}条记录") conn.commit() finally: conn.close()关键优化点:
- 使用
faker库生成真实的中文姓名和地址 - 手机号生成算法确保:
- 前三位符合中国运营商号段
- 后八位基于用户ID生成但保持随机性
- 分批提交(每1000条)避免内存溢出
- 密码使用BCrypt加密存储(与生产环境一致)
注意:实际运行前需要安装依赖
pip install pymysql faker
3. DBeaver批量生成商品数据技巧
在DBeaver中执行以下SQL脚本,快速生成10万条商品数据:
-- 创建临时存储过程 DELIMITER // CREATE PROCEDURE generate_goods(IN count INT) BEGIN DECLARE i INT DEFAULT 0; DECLARE cat_id INT; DECLARE brand_id INT; DECLARE price DECIMAL(10,2); WHILE i < count DO -- 随机选择分类和品牌 SET cat_id = FLOOR(1 + RAND() * 10); SET brand_id = FLOOR(1 + RAND() * 5); SET price = ROUND(10 + RAND() * 1000, 2); INSERT INTO litemall_goods ( name, category_id, brand_id, price, stock, detail ) VALUES ( CONCAT('商品-', UUID_SHORT()), cat_id, brand_id, price, FLOOR(100 + RAND() * 900), CONCAT('<p>', CASE WHEN RAND() > 0.5 THEN '新款上市' ELSE '经典热卖' END, '</p>') ); SET i = i + 1; IF i % 1000 = 0 THEN COMMIT; END IF; END WHILE; COMMIT; END // DELIMITER ; -- 执行存储过程生成10万商品 CALL generate_goods(100000); -- 清理临时存储过程 DROP PROCEDURE generate_goods;数据真实性保障策略:
- 价格区间控制在10-1010元,符合电商长尾分布
- 库存设置在100-1000之间,避免测试时过早售罄
- 商品名称使用
UUID_SHORT()确保唯一性 - 与分类表、品牌表建立有效外键关联
4. 数据验证与性能调优
生成数据后需要验证数据质量,推荐以下SQL检查点:
-- 检查用户地址关联完整性 SELECT COUNT(*) FROM litemall_address WHERE user_id NOT IN (SELECT id FROM litemall_user); -- 检查商品分类分布 SELECT category_id, COUNT(*) as goods_count FROM litemall_goods GROUP BY category_id ORDER BY goods_count DESC; -- 检查价格分布 SELECT FLOOR(price/100)*100 as price_range, COUNT(*) as goods_count FROM litemall_goods GROUP BY price_range;对于超大规模数据(百万级),建议采用以下优化手段:
批量插入优化:
# Python批量插入示例 batch_size = 1000 users = [(f"user_{i}", generate_phone(i)) for i in range(100000)] for i in range(0, len(users), batch_size): cursor.executemany( "INSERT INTO litemall_user (username, mobile) VALUES (%s, %s)", users[i:i+batch_size] ) conn.commit()临时禁用索引和约束:
ALTER TABLE litemall_goods DISABLE KEYS; -- 执行批量插入 ALTER TABLE litemall_goods ENABLE KEYS;调整MySQL配置(my.cnf):
[mysqld] innodb_buffer_pool_size = 2G innodb_log_file_size = 512M innodb_flush_log_at_trx_commit = 0
5. JMeter测试数据关联技巧
在JMeter测试脚本中,可以通过CSV Data Set Config引用生成的测试数据:
导出部分用户数据到CSV:
SELECT username, mobile INTO OUTFILE '/tmp/user_credentials.csv' FIELDS TERMINATED BY ',' FROM litemall_user LIMIT 50000;JMeter参数化配置:
CSV文件路径:/path/to/user_credentials.csv 变量名称:username,mobile 分隔符:,在HTTP请求中使用变量:
{ "username": "${username}", "password": "123456" }
对于商品ID的随机获取,可以使用JMeter的__RandomFromMultipleVars函数:
${__RandomFromMultipleVars(goods_ids_1|goods_ids_2|goods_ids_3)}在测试过程中,通过ServerAgent监控数据库服务器指标时,要特别关注:
- CPU使用率:持续高于80%可能表明SQL需要优化
- 磁盘I/O:大量写操作时考虑增加缓冲池
- 锁等待时间:突增可能意味着事务隔离级别需要调整
