10个百万级数据表需经过程序处理后整理导入到新表中
CI刚入手几天新人初发帖,求助老鸟们手上有个案子涉及到千万级(分十一个表,每个近百万)的数据量,数据全部从EXCEL手工导出到MYSQL花了好几天时间
现在需要通过WEB的方式查询编辑用到数据
因为数据不规范有重复记录,所以现在初用CI2.1.1在整个导入代码来导
目前的方式是这样
一次性读取100条记录存入对象
循环对其进行处理并存入临时数组
然后将数组数据存入新的表内,循环一次存入一次 (原先的想法是循环100条记录后处理过的数据存一数组,再把存入数组的数据一次插入到新表内,以减少数据库操作,因PHP也是现学现卖所以没有实现成功)
因为会有重复记录100条记录,平均实际进行插入操作40次
然后返回视图,停顿一秒JS自动跳转执行下一次导入操作
现在以这种方式导入数据,
执行程序跳转时,浏览器进度条没有像打开新页面那样跳转一次刷新一次,另外处理到30000条记录的时候,网页就停止影响.
望高人指点迷津~~
代码回帖附上
模型
<?php
class Madmin extends CI_Model {
function __construct()
{
parent::__construct();
$this->load->database();
}
function get_customer_record($ic_number,$cur_record)//根据字段ic_number查询一条记录
{
$this->db->select('ic_number,mobile_phone,other_phone');
$this->db->where('ic_number',$ic_number);
if ($cur_record > 100)
{
$query = $this->db->get('customer',5,$cur_record-5);//重复的记录都相近
}else{
$query = $this->db->get('customer');
}
return $query->row();
}
function get_customer_list_page($db_name,$offset,$limit)//自定读取某数据表N条记录
{
$query = $this->db->get($db_name,$limit,$offset);
return $query->result();
}
function insert_db($data)//处理过的数据通过数组插入到指定的表
{
$this->db->insert('customer',$data))
}
function update_db($ic_number,$phone_type,$phone)//根据条件更新mobile_phone,other_phone字段数据
{
if ($phone_type == 'mobile')
{
$this->db->set('mobile_phone',$phone);
}else{
$this->db->set('other_phone',$phone);
}
$this->db->where('ic_number',$ic_number);
$this->db->update('customer');
}
}
?>
控制器:
<?php
class Admin extends CI_Controller {
var $base_url;
function __construct()
{
parent::__construct();
$this->load->helper('url');
$this->base_url = $this->config->item('base_url');
$this->load->library('pagination');
}
//将客户数据从各零散数据表,通过清除重复记录,判断同信息不同电话号码信息
//重新整理后导入custmoer表内
function customer_import()//导入整理客户数据
{
$data['baseurl'] = $this->base_url;
$source = 'maybank_0';
$cur_record = $this->uri->segment(3);
if (empty($cur_record)){$cur_record = 0;}
$limit = 10;
$data['cur_record'] = $cur_record + $limit;
$data['limit'] = $limit;
$this->load->model('Madmin');
if ($source <> Null)
{
$temp_data = array();
$data['import_data'] = $this->Madmin->get_customer_list_page($source,$cur_record,$limit);
foreach ($data['import_data'] as $row)
{
++$cur_record;
if (substr($row->phone,0,1) == '1' or substr($row->phone,0,2) == '01' or substr($row->phone,0,3) == '001' or substr($row->phone,0,3) == '601')
//检测电话号为手机的号码
{
$temp_data['mobile_phone'] = $row->phone;
$phone_type = 'mobile';
}else{
$temp_data['other_phone'] = $row->phone;
$phone_type = 'other';
}
$result = $this->Madmin->get_customer_record($row->ic_number,$cur_record);
if (!empty($result))
{
if ($result->ic_number == $row->ic_number)
//根据身份证号(ic_number)判断是否有重复记录和电话号码类型,忽悠重复记录及更新或追加电话号码信息
{
$phone = '';
if ($phone_type == 'mobile' and $result->mobile_phone <> NULL)
{
$phone = $result->mobile_phone.','.$row->phone;
}else if ($phone_type == 'other' and $result->other_phone <> NULL){
$phone = $result->other_phone.','.$row->phone;
}else{
$phone = $row->phone;
}
$this->Madmin->update_db($row->ic_number,$phone_type,$phone);
unset($temp_data);
continue;
}
}
$temp_data['name'] = $row->name;
$temp_data['category_id'] = 1;
$temp_data['ic_number'] = $row->ic_number;
$temp_data['address_1'] = $row->address_1;
$temp_data['address_2'] = $row->address_2;
$temp_data['address_3'] = $row->address_3;
$temp_data['address_4'] = $row->address_4;
$temp_data['postcode'] = $row->postcode;
$temp_data['sex'] = $row->sex;
$temp_data['name'] = $row->name;
$temp_data['race_cd'] = $row->race_cd;
$temp_data['credit_limit'] = 0;
$this->Madmin->insert_db($temp_data);
unset($temp_data);
}
$data['success'] = '共执行处理 '.$data['cur_record'].' 条记录!['.date("H:i:s").']</br>';
}
$this->load->view('customer_import',$data);
}
}
视图:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<base href="<?=$baseurl?>">
<title>数据导入处理</title>
</head>
<body>
<?=$success?>
<?
if ((844610-$cur_record) > $limit)
{
$url = site_url("admin/customer_import/$cur_record");
echo('<script>');
echo("setTimeout(location.href='$url',2000);");
echo('</script>');
}else{
echo('数据全部导入成功!');
}?>
</body>
</html>
大哥们今天都休息哦!!?? 自己顶一顶..
我问的问题太初级了吗 还是太高级拉 :( 再顶一顶。。 1、如果你这个是一次性的导入工作,建议用个脚本或写个应用程序来做,更合适
2、千万级别的数据量,数据库和应用可能需要做一些优化工作,否则效率可能会低,想无脑高效查询的话可以考虑一下Nosql数据库 谢谢楼上的。。
现在这样写算是分段导入吧。。DZ的论坛有用过吗?后台备份数据库时类似的功能,计划是那样
不知道算不算真正的分段导入,不会一下卡死MYSQL 路过顶一顶。
经过一段时间其他事务的处理,又回到要处理这个事情上面
页:
[1]