使用下面的语句,可以让数据库自动生成800万条数据,以目前所学,这似乎太魔幻,难道他还可以像python中的for循环一样?是的。DELIMITER $$CREATE FUNCTION rand_string(n INT)RETURNS VARCHAR(255)DETERMINISTICBEGIN DECLARE chars_str VARCHAR(100) DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTYVWXYZ'; DECLARE return_str VARCHAR(255) DEFAULT ''; DECLARE i INT DEFAULT 0; WHILE i < n DO SET return_str = CONCAT(return_str,SUBSTRING(chars_str,FLOOR(1+RAND()*52),1)); SET i=i+1; END WHILE; RETURN return_str;END $$# 生成一个 10~510 之间的随机整数,用来模拟员工的部门 / 奖金等随机数值。CREATE FUNCTION rand_num()RETURNS INT(5)DETERMINISTICBEGIN DECLARE i INT DEFAULT 0; SET i = FLOOR(10+RAND()*500); RETURN i;END $$CREATE PROCEDURE insert_emp(IN START INT(10),IN max_num INT(10))BEGIN DECLARE i INT DEFAULT 0; SET autocommit=0; REPEAT SET i=i+1; INSERT INTO emp VALUES ((START+i),rand_string(6),'salesman',0001,CURDATE(),2000,4000,rand_num()); UNTIL i=max_numEND REPEAT;COMMIT;END $$CALL insert_emp(100001,8000000)$$DELIMITER ;
这一句是修改 MySQL 的语句结束符,MySQL 默认用 ; 表示一句SQL结束,但函数 / 存储过程内部会用到很多 ; 符号,如果不修改,MySQL 会误以为代码提前结束,从而报错。所以临时把结束符改成 $$,最后再用 DELIMITER ; 改回默认。下面通过注释的形式逐行解释上面的语句命令。-- 1. 创建自定义函数,函数名:rand_string-- 接收1个整数类型参数 n,代表要生成的随机字符串的长度CREATE FUNCTION rand_string(n INT)-- 2. 声明函数的返回值类型:长度最大255的字符串RETURNS VARCHAR(255)-- 3. 函数特性声明(固定语法,此处为系统要求的配置)DETERMINISTIC-- 4. 函数体开始(所有逻辑代码写在 BEGIN 和 END 之间)BEGIN -- 5. 定义变量:chars_str 存储所有可用的字符(大小写英文字母) DECLARE chars_str VARCHAR(100) DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTYVWXYZ'; -- 6. 定义变量:return_str 最终要返回的随机字符串,初始值为空 DECLARE return_str VARCHAR(255) DEFAULT ''; -- 7. 定义循环计数器变量 i,初始值为 0 DECLARE i INT DEFAULT 0; -- 8. WHILE 循环:当计数器 i 小于 传入的长度 n 时,循环执行代码 WHILE i < n DO -- 9. 核心逻辑:拼接随机字符 -- 拆解: -- RAND():生成0~1之间的随机小数 -- RAND()*52:对应上面chars_str一共有52个英文字母 -- FLOOR(1+...):向下取整,得到1~52之间的随机整数(字符的位置) -- SUBSTRING(字符串, 随机位置, 1):从字符集中截取1个随机字符 -- CONCAT:把新截取的字符拼接到结果字符串后面 SET return_str = CONCAT(return_str,SUBSTRING(chars_str,FLOOR(1+RAND()*52),1)); -- 10. 计数器 +1(循环一次,计数加1,直到等于n时停止循环) SET i=i+1; -- 11. 结束 WHILE 循环 END WHILE; -- 12. 返回最终拼接完成的随机字符串 RETURN return_str;-- 13. 函数体结束,使用自定义的结束符 $$END $$
-- 创建自定义函数 函数名:rand_num,无传入参数CREATE FUNCTION rand_num()-- 指定函数返回值类型:整型,显示宽度5RETURNS INT(5)-- 函数属性标识(语法固定写法)DETERMINISTIC-- 函数体开始BEGIN -- 声明局部变量i,整型,初始默认值为0 DECLARE i INT DEFAULT 0; -- 生成 10 ~ 510 之间的随机整数并赋值给i-- RAND() 生成 0 ≤ x < 1 的随机小数-- RAND()*500 生成 0 ≤ x < 500 的随机小数-- 10+RAND()*500 生成 10 ≤ x < 510 的随机小数-- FLOOR() 向下取整,抹掉小数部分,得到 10 ~ 509 的整数 SET i = FLOOR(10+RAND()*500); -- 将变量i的值作为函数返回值返回 RETURN i;-- 函数体结束,匹配自定义分隔符$$END $$
-- 创建存储过程,名字叫 insert_emp-- IN 表示这是输入参数:-- START:起始员工编号-- max_num:要插入的总数据条数CREATE PROCEDURE insert_emp(IN START INT(10),IN max_num INT(10))-- 存储过程逻辑开始BEGIN -- 声明一个计数器变量 i,初始值是 0 -- 作用:记录已经插入了多少条数据 DECLARE i INT DEFAULT 0; -- 关闭 MySQL 自动提交功能 -- 作用:批量插入大量数据时必须关闭,否则速度极慢、卡死 -- 默认每插入1条就提交1次,这里改成最后一次性提交 SET autocommit=0; -- REPEAT 循环开始 -- 作用:重复执行里面的插入语句,就是你理解的【for循环】 REPEAT -- 每循环一次,计数器 +1 -- 第一次:i=1,第二次:i=2 ... 直到 i=8000000 SET i=i+1; -- 核心:向 emp 表插入 1 条员工数据 -- 每循环一次,就插入 1 条!循环多少次,就插多少条数据 INSERT INTO emp VALUES ( START+i, -- 员工编号:从 START 开始依次递增(100001、100002...) rand_string(6), -- 员工姓名:调用函数生成6位随机字符串 'salesman', -- 职位:固定为销售员 0001, -- 领导编号:固定写0001 CURDATE(), -- 入职日期:当前系统日期 2000, -- 工资:固定2000 4000, -- 津贴:固定4000 rand_num() -- 奖金/部门号:调用函数生成随机数 ); -- 循环停止条件:当计数器 i 等于 总条数 max_num 时,停止循环 UNTIL i=max_num -- 结束 REPEAT 循环 END REPEAT; -- 一次性提交所有插入的数据(800万条一起提交,速度极快) COMMIT;-- 存储过程结束END $$
-- 调用名为 insert_emp 的存储过程-- 第一个参数 100001:员工编号起始值,从100001开始往后自增-- 第二个参数 8000000:一共要向emp表插入 800万 条测试数据CALL insert_emp(100001,8000000)$$