MySQL用隨機數(shù)據(jù)填充外鍵表

參考:
http://blog.itpub.net/29254281/viewspace-1686302/

準備環(huán)境
1.創(chuàng)建數(shù)字輔助表
create table nums(id int not null primary key);

delimiter $$
create procedure pFastCreateNums(cnt int)
begin
    declare s int default 1;
    truncate table nums;
    insert into nums select s;
    while s*2<=cnt do
        insert into nums select id+s from nums;
        set s=s*2;
    end while;
end $$
delimiter ;


call pFastCreateNums(1000000);

數(shù)字輔助表的行數(shù)決定最后能生成的表行數(shù)的最大值.

2.創(chuàng)建生成隨機字符的函數(shù)

  1. DROP FUNCTION IF EXISTS rand_string;
  2. delimiter //
  3. CREATE FUNCTION rand_string(l_num int UNSIGNED,l_type tinyint UNSIGNED)
  4. RETURNS varchar(2000)
  5. BEGIN
  6.  -- Function : rand_string
  7.  -- Author : dbachina#dbachina.com
  8.  -- Date : 2010/5/30
  9.  -- l_num : The length of random string
  10.  -- l_type: The string type
  11.  -- 1.0-9
  12.  -- 2.a-z
  13.  -- 3.A-Z
  14.  -- 4.a-zA-Z
  15.  -- 5.0-9a-zA-Z
  16.  -- :
  17.   -- MySQL> select rand_string(12,5) random_string;
  18.   -- +---------------+
  19.   -- | random_string |
  20.   -- +---------------+
  21.   -- | 3KzGJCUJUplw |
  22.   -- +---------------+
  23.   -- 1 row in set (0.00 sec)
  24.  DECLARE i int UNSIGNED DEFAULT 0;
  25.  DECLARE v_chars varchar(64) DEFAULT '0123456789';
  26.   DECLARE result varchar (2000) DEFAULT '';
  27.  
  28.   IF l_type = 1 THEN
  29.     SET v_chars = '0123456789';
  30.   ELSEIF l_type = 2 THEN
  31.     SET v_chars = 'abcdefghijklmnopqrstuvwxyz';
  32.   ELSEIF l_type = 3 THEN
  33.     SET v_chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  34.   ELSEIF l_type = 4 THEN
  35.     SET v_chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  36.   ELSEIF l_type = 5 THEN
  37.     SET v_chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  38.   ELSE
  39.     SET v_chars = '0123456789';
  40.   END IF;
  41.  
  42.   WHILE i < l_num DO
  43.       SET result = concat( result,substr(v_chars,ceil(rand()*(length(v_chars)-1)),1) );
  44.     SET i = i + 1;
  45.   END WHILE;
  46.   RETURN result;
  47. END;
  48. //
  49. delimiter ;



準備實驗表.
    先創(chuàng)建一些帶有外鍵約束的表.數(shù)據(jù)庫名稱是 probe

  1. CREATE TABLE `t_jvm_info` (
  2.   `id` bigint(20) NOT NULL AUTO_INCREMENT,
  3.   `app_name` varchar(32) NOT NULL COMMENT '應用名稱',
  4.   `host_name` varchar(32) NOT NULL COMMENT '主機名稱',
  5.   `collect_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '采集時間',
  6.   `version` varchar(32) NOT NULL DEFAULT '' COMMENT 'jvm版本',
  7.   `vendor` varchar(32) NOT NULL DEFAULT '' COMMENT '廠商',
  8.   `java_home` varchar(64) NOT NULL DEFAULT '' COMMENT '客戶端javahome路徑',
  9.   `loaded_class_count` int(11) NOT NULL DEFAULT '-1' COMMENT '已經(jīng)加載的類數(shù)量',
  10.   `unloaded_class_count` int(11) NOT NULL DEFAULT '-1' COMMENT '已經(jīng)卸載的類數(shù)量',
  11.   `total_loaded_class_count` int(11) NOT NULL DEFAULT '-1' COMMENT '累計加載的類數(shù)量',
  12.   `heap_init` float NOT NULL DEFAULT '-1' COMMENT '堆內存初始大小',
  13.   `heap_committed` bigint(20) NOT NULL DEFAULT '-1' COMMENT 'os分配給jvm的堆內存',
  14.   `heap_max` bigint(20) NOT NULL DEFAULT '-1' COMMENT '堆內存上限',
  15.   `heap_used` bigint(20) NOT NULL DEFAULT '-1' COMMENT '已經(jīng)使用的堆內存大小',
  16.   `non_heap_init` bigint(20) NOT NULL DEFAULT '-1' COMMENT '非堆內存初始大小',
  17.   `non_heap_committed` bigint(20) NOT NULL DEFAULT '-1' COMMENT 'os分配給jvm的非堆內存',
  18.   `non_heap_max` bigint(20) NOT NULL DEFAULT '-1' COMMENT '非堆內存上限',
  19.   `non_heap_used` bigint(20) NOT NULL DEFAULT '-1' COMMENT '已經(jīng)使用的非堆內存大小',
  20.   `current_thread_count` int(11) NOT NULL DEFAULT '-1' COMMENT '當前jvm線程總數(shù)',
  21.   `total_started_thread_count` int(11) NOT NULL DEFAULT '-1' COMMENT '累計啟動過的線程總數(shù)',
  22.   `peak_thread_count` int(11) NOT NULL DEFAULT '-1' COMMENT '線程數(shù)量最大值',
  23.   `daemon_thread_count` int(11) NOT NULL DEFAULT '-1' COMMENT 'daemon線程數(shù)量',
  24.   PRIMARY KEY (`id`),
  25.   KEY `app_name` (`app_name`,`host_name`,`collect_time`),
  26.   KEY `host_name` (`host_name`,`collect_time`)
  27. ) ENGINE=InnoDB AUTO_INCREMENT=2001 DEFAULT CHARSET=utf8mb4 COMMENT='jvm采集信息表';

  28. CREATE TABLE `t_jvm_gc_info` (
  29.   `id` bigint(20) NOT NULL AUTO_INCREMENT,
  30.   `t_jvm_info_id` bigint(20) NOT NULL COMMENT 'jvm采集信息表id',
  31.   `name` varchar(32) NOT NULL COMMENT 'gc類型名稱',
  32.   `gctime` bigint(20) NOT NULL DEFAULT '-1' COMMENT 'gc時間',
  33.   `gccount` bigint(20) NOT NULL DEFAULT '-1' COMMENT 'gc次數(shù)',
  34.   PRIMARY KEY (`id`),
  35.   KEY `t_jvm_info_id` (`t_jvm_info_id`),
  36.   CONSTRAINT `t_jvm_gc_info_ibfk_1` FOREIGN KEY (`t_jvm_info_id`) REFERENCES `t_jvm_info` (`id`)
  37. ) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=utf8mb4 COMMENT='jvm gc采集信息表';

創(chuàng)建可以自動生成數(shù)據(jù)的存儲過程


  1. drop procedure if exists auto_fill ;
  2. delimiter $$
  3. create procedure auto_fill(pDb varchar(32),pTableList varchar(1024))
  4. begin
  5.     declare done int default 0;
  6.     declare v_dbName varchar(128);
  7.     declare v_fullTableName varchar(128);
  8.     declare v_tableName varchar(128);
  9.     declare v_rowCount int;
  10.     declare cur_test CURSOR for select dbName,fullTableName,tableName,rowCount from tmp_table_info;
  11.     DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

  12.     -- 臨時表,用于保存拆分參數(shù)之后的結果.主要信息就是數(shù)據(jù)庫名稱和表名稱
  13.     drop table if exists tmp_table_info;
  14.     create temporary table tmp_table_info
  15.     select    pDb dbName,
  16.      concat(pDb,'.',substring_index ( value_str,',',1 )) fullTableName ,
  17.      substring_index ( value_str,',',1 ) tableName,
  18.      substring_index ( value_str,',',-1 ) rowCount
  19.     from (
  20.         select substring_index(substring_index(pTableList,';',b.id),';',-1) value_str
  21.         from
  22.         nums b
  23.         where b.id <= (length(pTableList) - length(replace(pTableList,';',''))+1)
  24.     ) t1;
  25.     
  26.     -- 禁用外鍵
  27.     SET FOREIGN_KEY_CHECKS=0;
  28.     open cur_test;
  29.     repeat
  30.         fetch cur_test into v_dbName,v_fullTableName,v_tableName,v_rowCount;
  31.         if done!=1 then

  32.             set @sql=concat('insert ignore into ',v_dbName,'.',v_tableName,' select ');
  33.             select
  34.             @sql:=concat(@sql,
  35.                 case
  36.                     when extra='auto_increment' then concat('id,')
  37.                     when data_type='int' then if(rowCount is null,'round(rand()*2147483647),',concat('round(rand()*',rowCount,'),'))
  38.                     when data_type='bigint' then if(rowCount is null,'round(rand()*9223372036854775807),',concat('round(rand()*',rowCount,'),'))
  39.                     when data_type='smallint' then 'round(rand()*32767),'
  40.                     when data_type='tinyint' then 'round(rand()*127 ),'
  41.                     when data_type='varchar' then concat('rand_string(',CHARACTER_MAXIMUM_LENGTH,',5),')
  42.                     when data_type='date' then 'now()-interval round(90*rand()) day,'
  43.                     when data_type='datetime' then 'now()-interval round(90*rand()) day,'
  44.                     when data_type='timestamp' then 'now()-interval round(90*rand()) day,'
  45.                     when data_type in('double','float') then 'round(rand()*32767,5),'
  46.                     when data_type like '%text%' then concat('rand_string(2048,5),')
  47.                 end
  48.             ) s
  49.             from (
  50.                 select
  51.                     k.referenced_table_name,
  52.                     k.referenced_column_name,
  53.                     c.table_schema,
  54.                     c.table_name,
  55.                     c.column_name,
  56.                     c.data_type,
  57.                     c.CHARACTER_MAXIMUM_LENGTH,
  58.                     c.extra,
  59.                     t.rowCount
  60.                 from information_schema.columns c
  61.                 left join information_schema.KEY_COLUMN_USAGE k on(
  62.                     c.table_schema=k.table_schema and
  63.                     c.table_name=k.table_name and
  64.                     c.column_name=k.column_name and
  65.                     k.constraint_name
  66.                         in    (select constraint_name from information_schema.REFERENTIAL_CONSTRAINTS)
  67.                 )
  68.                 left join tmp_table_info t on(t.dbName=k.table_schema and t.tableName=k.table_name)
  69.                 where (c.table_schema,c.table_name) =(v_dbName,v_tableName)
  70.                 order by c.ORDINAL_POSITION
  71.             ) t2
  72.             ;
  73.             set @sql=left(@sql,char_length(@sql)-1);
  74.             select nullif ('please stand by...',@sql:=concat(@sql,' from nums where id<=',v_rowCount,';')) info;
  75.             prepare statement from @sql;
  76.             execute statement;
  77.             commit;
  78.         end if;
  79.     until done end repeat;
  80.     close cur_test;
  81.         
  82.     -- 恢復外鍵
  83.     SET FOREIGN_KEY_CHECKS=1;


  84. end ;
  85. $$
  86. delimiter ;

執(zhí)行存儲過程填充數(shù)據(jù)

call auto_fill('probe','t_jvm_gc_info,100000;t_jvm_info,2000');

過程第一個參數(shù)是 數(shù)據(jù)庫名稱
第二個參數(shù)是 表名和行數(shù)的字符串列表.

測試數(shù)據(jù)生成自行刪除外鍵約束即可



文章標題:MySQL用隨機數(shù)據(jù)填充外鍵表
URL鏈接:http://muchs.cn/article0/jsdooo.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供定制網(wǎng)站、軟件開發(fā)、手機網(wǎng)站建設外貿網(wǎng)站建設、網(wǎng)站導航品牌網(wǎng)站建設

廣告

聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)