MySQL製作具有千萬條測試資料的測試庫

lichlaughing發表於2020-11-29

有時候需要製造一些測試的資料,以mysql官方給的測試庫為基礎,插入十萬,百萬或者千萬條資料。利用一些函式和儲存過程來完成。

官方給的測試庫地址:https://github.com/datacharmer/test_db

匯入官方的資料庫,做了一些簡化,留下了部門表,員工表和僱傭表三張表,去掉了外來鍵關聯。因為是測試資料,日期的對應關係不具備準確性。

必要的函式

生成隨機字串

RAND():生成0~1之間的隨機數

FLOOR:向下整數 (FlOOR(1.2)=1)

CEILING 向上取整 (CEILING(1.2)=2)

substring:擷取字串

concat:字串連線

CREATE DEFINER=`root`@`localhost` FUNCTION `rand_string`(n INT) RETURNS varchar(255) CHARSET latin1
BEGIN
	DECLARE chars_str 	varchar(100) DEFAULT 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
    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()*62 ),1));
        SET i = i +1;
    END WHILE;
    RETURN return_str;
END

檢視自定義的所有函式

show function status

測試使用:

select rand_string(5);

生成隨機年月日字串

生成一個指定時間段內的隨機日期

SELECT
	date(
	from_unixtime( unix_timestamp( '2000-01-01' ) + floor( rand() * ( unix_timestamp( '2020-12-31' ) - unix_timestamp( '2000-01-01' ) + 1 ) ) ));

函式:生成指定時間段內的隨機日期

CREATE DEFINER=`root`@`localhost` FUNCTION `rand_date_string`(startDate varchar(255),endDate varchar(255)) RETURNS varchar(255) CHARSET latin1
BEGIN
   DECLARE return_str varchar(255) DEFAULT '';
	
	 SET return_str =date(
		from_unixtime( unix_timestamp( startDate ) 
				+ floor( rand() * ( unix_timestamp( endDate ) - unix_timestamp( startDate ) + 1 ) ) 
			)
	 );
   
    RETURN return_str;
END

測試使用:

select rand_date_string('2000-01-01','2020-12-31');
//結果
2001-09-10

儲存過程生成資料

給每個部門插入一百萬員工,那麼員工表就有九百萬的資料。

CREATE DEFINER=`root`@`localhost` PROCEDURE `data`()
BEGIN
	
	DECLARE i INT DEFAULT 1;
	DECLARE j INT DEFAULT 0;
	DECLARE id INT DEFAULT 0;
	WHILE i < 10 DO
			WHILE j < 1000000 DO
				insert into employees_m (emp_no,birth_date,first_name,last_name,gender,hire_date) VALUES(
					id,rand_date_string('1970-01-01','1997-01-01'),rand_string(5),rand_string(5),'M',NOW());
				
				insert into dept_emp_m (emp_no,dept_no,from_date,to_date) values(
					 id,concat('d00',i),rand_date_string('1990-01-01','2020-12-31'),'2020-12-31');
					 
			SET j=j+1;   
			SET id=id+1;   
			END WHILE;
	SET j = 0;
	SET i=i+1;     
	END WHILE;

END

插入九百萬條資料大概用時:4868s

上面的方式插入資料會很慢,可以將資料插入到記憶體表,就是將表的儲存引擎修改為MEMORY這樣就會使用記憶體去儲存資料,會比直接插入到INNODB引擎的表中快很多,只不過就是沒有持久化,但是速度賊快,插入一千萬條資料大概需要時間: 1227.89s

附錄

修改表儲存引擎

ALTER TABLE dept_emp_m ENGINE=MEMORY;

調整記憶體表的大小,修改配置檔案

[mysqld]
max_heap_table_size = 2048M
tmp_table_size = 2048M

相關文章