【问题标题】:automatically populate table with dummy data in mysql在 mysql 中使用虚拟数据自动填充表
【发布时间】:2011-06-13 03:16:21
【问题描述】:

我有一个 MySQL 表,我想用一些虚拟数据填充它以进行测试 (50+)。

这个表有另一个表的外键,所以虚拟数据必须从那个表交叉引用,但又是随机的,即不能都是同一个外键。

它还有一个添加日期的字段,我想用一年内的随机日期填充它,例如2010 年的任何日期。

我的表结构是:

id, customer_id, date_added, title, total_cost

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

这样做的最佳方法是什么?我更喜欢直接在 MySQL 中执行此操作,但如果不是我的站点是在 Python 上运行的,那么在其中执行此操作的方法就可以了。

【问题讨论】:

    标签: python mysql


    【解决方案1】:

    如果没有 Python 编写的应用程序的外部帮助,我不会在 MySQL 中执行此操作。

    您的陈述中有几个要求最好以程序风格表达。 SQL 是一种基于集合的语言;我认为它不适合手头的任务。

    您会希望应用程序从源中获取数据,执行您需要的任何随机化和 PII 删除,然后根据您的要求构建测试数据。

    如果它是仅用于测试的数据库,您可以考虑一个内存数据库,您可以填充、修改所有您喜欢的内容,然后为您的下一次测试吹走。我正在考虑 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;
      

      【讨论】:

        【解决方案3】:

        对于测试业务规则,我实际上更喜欢经过深思熟虑的数据而不是随机数据。来自 excel->csv->db 或手动创建的插入语句。

        每个边界条件一行,比如:

        • 没有订单的客户
        • 一个总成本为零的客户
        • 一位客户名字中带有外来字(因为我总是忘记处理)
        • 一位客户姓名的最大长度
        • 一位客户有大量订单(以确保 GUI 仍然看起来不错)

        它使运行回归测试变得非常容易,因为您“知道”数据应该是什么样子。

        对于性能测试,只要数据分布真实(这会影响索引的有用性),随机数据就可以做得很好。如果您有非常高级的要求,最好的办法是使用一些为此目的而构建的软件。

        但您通常可以从一个整数表生成所需的所有数据,并巧妙地使用内置函数:

        • rand() -> 生成随机数。
        • mod() -> 用于创建重复序列 (1,2,3,1,2,3)
        • lpad() and rpad() -> 用于将字符串填充到指定长度

        【讨论】:

          【解决方案4】:

          如果您真的想对测试数据进行一些设置,您应该走夹具路线。这将帮助您建立一个非常好的开发环境,并且如果您正在使用一个框架,可以很好地集成到您的网站框架中。

          可以找到fixture模块here的文档链接

          如果您认为完成所有工作的工作量太大,请查看 MySQLdb 模块,该模块将帮助您将数据插入表中。

          链接回 stackoverflow 可能不太好,但有人已经回答了您提出的日期问题。你可以找到here

          【讨论】:

            【解决方案5】:

            因此,这个问题已经过时且已得到解答,但我认为您仍然需要知道这个stored procedure to load dummy data to MySQL,它从 MySQL 运行并根据数据类型自动填充虚拟数据。

            您只需要指定数据库名称、表名称和要填充的记录数。

            call populate('sakila','film',1000,'N');

            (您可能还想关注Git-Repo 以获取更新。)

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-09-23
              • 1970-01-01
              • 1970-01-01
              • 2019-07-01
              • 1970-01-01
              • 2019-05-04
              • 2015-06-20
              • 2014-09-22
              相关资源
              最近更新 更多