在MySQL中自动填充带有虚拟数据的表

1 投票
5 回答
5059 浏览
提问于 2025-04-16 10:22

我有一个MySQL表格,想要填充一些测试用的假数据(50条以上)。

这个表格有一个外键,指向另一个表格,所以这些假数据必须和那个表格的数据相互关联,但又要是随机的,也就是说不能全部使用同一个外键。

此外,它还有一个“添加日期”的字段,我想用一年内的随机日期来填充,比如说2010年里的任意日期。

我的表格结构是:

id, customer_id, date_added, title, total_cost

其中id是主键,customer_id是外键,date_added是日期字段。

那么,最好的方法是什么呢?我更希望直接在MySQL里操作,但如果不行的话,我的网站是用Python搭建的,所以在Python里也可以实现。

5 个回答

2

我不会在MySQL中直接这样做,而是会借助一个用Python写的应用程序。

你的需求有几个方面,最好用一种程序化的方式来表达。SQL是一种基于集合的语言,我觉得它不太适合处理你现在要做的事情。

你需要一个应用程序来接收数据,进行必要的随机化和个人信息去除,然后根据你的要求构建测试数据。

如果这个数据库只是用来测试,你可以考虑使用一个内存数据库,这样你可以随意填充和修改数据,然后在下一个测试时再清空它。我在想像Hypersonic、Derby或TimesTen这样的东西。

2

快速简单的解决办法:

drop table if exists orders;
drop table if exists customers;

create table customers
(
cust_id int unsigned not null auto_increment primary key,
name varchar(255) not null
)
engine=innodb;

create table orders
(
order_id int unsigned not null auto_increment primary key,
cust_id int unsigned not null,
order_date datetime not null,
foreign key (cust_id) references customers(cust_id) on delete cascade
)
engine=innodb;


drop procedure if exists load_test_data;

delimiter #

create procedure load_test_data()
begin

declare v_max_customers int unsigned default 0;
declare v_max_orders int unsigned default 0 ;
declare v_counter int unsigned default 0 ;
declare v_rnd_cust_id int unsigned default 0;
declare v_base_date datetime;

  set foreign_key_checks = 0;

  truncate table orders;
  truncate table customers;

  set foreign_key_checks = 1;

  set v_base_date = "2010-01-01 00:00:00";

  set v_max_customers = 1000;
  set v_max_orders = 10000; 

  start transaction;

  set v_counter = 0;
  while v_counter < v_max_customers do
        insert into customers (name) values (concat('Customer ', v_counter+1));
    set v_counter=v_counter+1;
  end while;

  commit;

  start transaction;

  set v_counter = 0;
  while v_counter < v_max_orders do

    set v_rnd_cust_id = floor(1 + (rand() * v_max_customers));

        insert into orders (cust_id, order_date) values (v_rnd_cust_id, v_base_date + interval v_counter hour);
    set v_counter=v_counter+1;
  end while;

  commit;

end #

delimiter ;

call load_test_data();

select * from customers order by cust_id desc limit 10;
select * from orders order by order_id desc limit 10;
0

如果你想认真设置一些测试数据,建议你使用“fixture”这个方法。这可以帮助你建立一个不错的开发环境,并且如果你在用某个网站框架,它可能会很好地融入其中。

你可以在这里找到关于fixture模块的文档链接。

如果你觉得这样做有点麻烦,可以看看MySQLdb模块,它可以帮助你把数据插入到你的表里。

虽然回链接到StackOverflow可能不太合适,但其实有人已经回答了你问的日期问题。你可以在这里找到答案。

撰写回答