首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL RAND() 生成不重複隨機姓名年齡:存儲過程實戰與種子機制詳解

     編輯:MySQL 綜合教學

MySQL RAND() 生成不重複隨機姓名年齡:存儲過程實戰與種子機制詳解

需求:向表插入 100 條測試數據,姓名從字符池隨機組合(2-3 字),年齡 20-50 區間隨機,**且相鄰兩行姓名+年齡不完全相同**。MySQL RAND() 配合存儲過程輕鬆實現。

RAND() 基礎與種子機制

  • RAND():返回 0~1 間浮點數,每次調用值不同。
  • RAND(N):指定種子 N,**同一查詢中多次調用返回固定序列**;不同查詢間序列相同。
  • 演示:
SELECT RAND(), RAND(5);
-- 第1次: 0.7946..., 0.4061...
-- 第2次: 0.1291..., 0.4061...  -- RAND(5) 固定,RAND() 變化
-- 第3次: 0.2615..., 0.4061...

存儲過程完整實現

DELIMITER $$
CREATE PROCEDURE `pro3`(num INT)
BEGIN
  DECLARE fname CHAR(1);       -- 姓氏
  DECLARE name1 CHAR(1);       -- 名字第1字
  DECLARE name2 CHAR(1);       -- 名字第2字(可選)
  DECLARE fullname VARCHAR(3); -- 完整姓名
  DECLARE pre_fullname VARCHAR(3) DEFAULT ''; -- 上一行姓名
  DECLARE age INT;             -- 年齡
  DECLARE i INT DEFAULT 1;     -- 計數器

  WHILE i <= num DO
    -- 1. 隨機姓氏(8 個常用姓)
    SET fname = SUBSTRING('趙錢孫李周吳鄭王', FLOOR(1 + 8 * RAND()), 1);
    
    -- 2. 隨機名字字符(14 個備選字)
    SET name1 = SUBSTRING('一二三四五六七八九十甲乙丙丁', ROUND(1 + 14 * RAND()), 1);
    SET name2 = SUBSTRING('一二三四五六七八九十甲乙丙丁', ROUND(1 + 14 * RAND()), 1);
    
    -- 3. 隨機決定 2 字或 3 字姓名
    IF ROUND(RAND()) = 0 THEN
      SET fullname = CONCAT(fname, name1);
    ELSE
      SET fullname = CONCAT(fname, name1, name2);
    END IF;
    
    -- 4. 隨機年齡 20-50
    SET age = FLOOR(20 + 31 * RAND());
    
    -- 5. 獲取上一行姓名(避免連續重複)
    SELECT `name` INTO pre_fullname FROM user1 ORDER BY id DESC LIMIT 1;
    
    -- 6. 去重邏輯:若與上一行相同則跳過本次循環(i 不增),否則插入並 i+1
    IF fullname = pre_fullname AND i > 1 THEN
      SET i = i;  -- 什麼都不做,繼續下一次循環重新隨機
    ELSEIF fullname IS NULL THEN
      SET i = i;  -- 防御性判斷
    ELSE
      INSERT INTO user1 VALUES (NULL, fullname, age);
      SET i = i + 1;
    END IF;
  END WHILE;
END$$
DELIMITER ;

執行與驗證

TRUNCATE TABLE user1;
CALL pro3(100);
SELECT * FROM user1;

輸出 100 行,**無任意相鄰兩行姓名+年齡完全相同**。示例片段:

+-----+-----------+-----+
| id  | name      | age |
+-----+-----------+-----+
| 1   | 吳甲九    | 32  |
| 2   | 趙丙      | 49  |
| 3   | 錢二      | 40  |
| 4   | 鄭二丙    | 34  |
| ... | ...       | ... |
| 100 | 吳十四    | 29  |
+-----+-----------+-----+

關鍵技術點解析

技術點實現方式說明
隨機整數區間 [a,b]FLOOR(a + (b-a+1)*RAND())年齡 20-50:FLOOR(20+31*RAND())
字符池隨機取字SUBSTRING(str, pos, 1) + FLOOR/ROUND姓氏池 8 字、名字池 14 字
變長姓名 (2/3 字)IF ROUND(RAND())=0 THEN 2字 ELSE 3字50% 概率各半
相鄰去重查詢上一行 ORDER BY id DESC LIMIT 1 比較相同則不計數重試
循環控制WHILE i <= num + 手動 i = i+1去重時 i 不增,保證最終行數

性能與擴展建議

  • 大批量 (10萬+):存儲過程單線程較慢,建議應用層批量生成 INSERT ... VALUES (...),(...),... 或 LOAD DATA。
  • 去重邏輯擴展:若需全局唯一(非相鄰),需建立唯一索引 UNIQUE KEY uk_name_age (name, age),捕獲 Duplicate entry 異常重試。
  • 隨機種子固定:測試需可復現時,調用 RAND(seed) 初始化,後續 RAND() 序列確定。

總結

MySQL RAND() + 存儲過程可實現**帶約束的隨機測試數據生成**;核心在於 FLOOR(a+(b-a+1)*RAND()) 區間取整、字符池 SUBSTRING 取字、**相鄰去重邏輯控制循環計數器**。生產級大數據建議應用層生成,資料庫只負責高效導入。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved