php中memcache读取数据批量写入mysql

 更新时间:2016年11月25日 16:35  点击:2090
用 Memcache 可以缓解 php和数据库压力下面代码是解决高负载下数据库写入瓶颈问题。遇到最实用的:写入ip pv uv的时候 ,用户达到每分钟几万访问量,要记录这些数据,实时写入数据库必定奔溃

用以下技术就能解决。

还有如用户注册,同一时间断内,大量用户注册。可以缓存后一次性写入到数据库。

代码如下:

 代码如下 复制代码
public function cldata(){
$memcache_obj = new Memcache;
    $memcache_obj->connect('127.0.0.1', '11211');
    $all_items = $memcache_obj->getExtendedStats('items');
    foreach($all_items as $option=>$vall){
        if (isset($all_items[$option]['items'])) {
                 $items = $all_items[$option]['items'];
                 foreach ($items as $number => $item) {
                       $str    = $memcache_obj->getExtendedStats('cachedump', $number, 0);
                       $line   = $str[$option];
if(is_array($line) && count($line) > 0){
    foreach($line as $key => $value) {
        $keys[] = $key;
}
}
}
}
}
 
    dump(count($keys));//获取到key
    if(count($keys)>50){//要写入的数据条数     
        $end=50;
    }else{
        $end=count($keys);
    }
    
    for($i=0;$i<=$end;$i++){
        if(!strstr($keys[$i],'datadb')) continue;     
        $ksv = str_replace('datadb','',$keys[$i]);
        
    /*$logdata = unserialize(S('login'.$ksv));//登录写入
    if(is_array($logdata)){
        $this->addsuidinlogin($logdata[0],$logdata[1],$logdata[2],1);      
    }   */
        
        /*$sdata = unserialize(S('regadd'.$ksv));//注册写入
    if(is_array($sdata)){
        $this->baiduad($sdata[0],$sdata[1],$sdata[2],$sdata[3],$sdata[4],1);   
    }
    */
        $regdata = unserialize(S('datadb'.$ksv));     
        $ress[]=$regdata;
        S('datadb'.$ksv,null);
        
        
    } 
    $addb = M()->db(66,C('DB_WEB_AD'));//批量写入 addall
    $addb->table('mj_ad_count')->addall($ress);
    echo M()->getLastSql();
 
    
    
    
}

附:
可以使用的工具如:memadmin 还有memadmin 文档。

吓死人的节奏,在后台发现一个功能失效了,各种检测,然后检测到可能是数据库里的某个表不小心被删了。就先备份了一下数据(google浏览器下载)。替换原数据后,在替换回来。。呀的,然后导入就

错误
有可能您发现了 SQL 分析器的臭虫。请仔细检查您的查询,包括引号是否正确及是否匹配。其它可能的失败原因可能由于您上传了超过引用文本区域外的二进制数据。您还可以在 MySQL 命令行界面试一下您的查询。如果可能的话,以下会列出 MySQL 服务器的错误输出,这可能对您解决问题有一定的帮助作用。如果您仍然有问题,或者命令行界面执行成功而分析器出错,请将您的 SQL 查询缩减到导致问题的某一条语句,然后和下面剪切区中的数据一起提交一个臭虫报告:
----开始剪切----
………………(各种字符)
----结束剪切----
----开始原文---
………………(各种乱码)
在然后,就各种baidu、google、sougou。。。没找到解决办法。
记得过去搭建DZ站时也遇到这种问题。当时,就是无意的在导入时随便点了编码选择某项就导入进去。。可这次行不通,纠结。。再次百度看看有没有类似的修复软件。没找到= =#。 用Notepad++打开sql看看,没乱码,比较可以导入的sql文件。高版本的都可以导入,低版本应该不是问题,格式也没错。按照以往对这些上传文件思路。
在本地mysql里尝试导入.
先改下名字,上传看看。。发现没报上面的错误了!!!不过还是有 一行错误提示(英语也懒的去翻译了)。
然后重压缩在导入。。!!!OK,本地的mysql可以导入了。
去导入空间里的mysql.
压缩了的SQL还是报上面的哪个上面 臭虫 错误。我去。。。解压后上传,只导入了多说的表,外加 一行错误提示。太坑了,不懂。
索性本地上已经导入完整,再次从本地的mysql里导出,在上传。。解决。
总结:
看数据库内容是否完整且是否乱码(如果是,基本上就没救了= =)。
本地搭建phpmyadmin尝试导入(我用的是phpStudy绿色版的)
在然后各种主流、非主流思路。(编码转换、版本比较、格式比较……)
(我是改文件名后压缩本地mysql,在然后导出本地,在导入到空间,貌似有运气成分,呵呵。)
百度上说,可以用mysql自带的修复工具,尝试修复下。我数据库格式和内容都完整,且也懒得去装,就没有尝试了!
Ps:在也不用phpmyadmin来备份了。。= =

注意以下事项:
必要知识:
mysql编码:
在mysql的安装目录,如:
E:\Program Files\MySQL\MySQL Server 5.0\my.ini
可以找到mysql库的编码,大部分情况下,可以设置为uft-8:
default-character-set=utf8
或gbk:
default-character-set=gbk
编码不对,就会造成无法导入.修改编码后要重启数据库才会生效.
1.条件:在同一台服务器,
mysql数据库可以用平台的导出导入功能正常备份及还原.
2.条件:不同服务器上,在my.ini编码一致的情况下,
mysql数据库可以用平台的导出导入功能正常备份及还原.
2.条件:不同服务器上,在my.ini编码不一致的情况下,
必须修改my.ini成为一致的编码,mysql数据库才可以用平台的导出导入功能正常备份及还原.
3.对于用phpmyadmin或其他工具导入的文件,您需要再次加工后,才能用平台的导入功能:
以phpmyadmin为例,导出后,将生成的SQL语句另存为一个.sql文件,然后,用记事本修改它:
(1)找到CREATE DATABASE开头的这一行如:
CREATE DATABASE `数据库名` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci;
在前面加上--符号,取消这行的运行权(原因是导入时是用普通用户角度导入,不允许建立数据库)
这样,才有可能用平台的导入功能导入.
(2)然后,您可以看看这个库的编码是否和您服务器上的一致
如果编码不一致,那么,
<1>要么用phpmymyadmin重新备份成编码一致的.sql文件才能导入.(在phpmyadmin登陆的首页可以选编码)
<2>要么是修改my.ini中的编码,并重启Mysql才能导入(重启Mysql可以在服务器上,管理工具,服务管理中重启),这种方式成功机会高一些,建议这样操作.

一、数据库的导出
一般而言,数据库的导出是为了备份或者为了数据库的移置。那么导出时我们一般选择SQL或者Excel,而不选择Word,PDF等。导出时选择要导出的表或者所有表。选项选择时要注意,要选择没有必要的选项,如果选择了其他选项会给数据库入库带来麻烦或错误。那么到底选择什么呢?
在结构选项(structure)选项中,我们一般使用Add if not exists,Add auto_increment  value,Enclose table and field names with backquotes(使用中文相应地翻译成汉字就成),也就是在选项的前面框内打勾(你不会告诉我这个你不会吧),在数据(data)选项中选择 Complete inserts,Extended inserts,Use hexadecimal for BLOB,Export type 为Insert,当然如果你是为了更新或替换可选择UPDATE或replace。当Save as file前打勾时,会自动存为文件(推荐),然后按Go,这样数据库就存为zip,gzip或bzip格式了。
二、数据库的导入
    尤其要注意的是,我在数据库的导入时先建好了与导出数据库同名的一个空数据库(没 有表的)才能导入,否则经常报错。建好了数据库后点击相应数据库进入(当然要在phpMyAdmin环境下了),这时我们再点击Import按纽,忘记说 了,如果你选择的是压缩的导出结果,最好先解压成一个文件形式,虽然phpMyAdmin说可以识别压缩文件(Imported file compression will be automatically detected from: 无, gzip, zip),其实还是识别不了的:<),不然,phpMyAdmin会告诉你发现了臭虫(真有臭虫倒好),字符集选择与导出时一样,默认utf8,然 后点击Go或执行就OK了,这样数据库就移到了另一个地方,同时也方便你移站了。

在php中我们要查看mysql数据库的信息我们可以直接连接mysql之后再调用mysql相关语句就可以实现了,下面给各位整理了一篇文章希望对大有帮助。

首先我们需要了解下查询MySQL数据库/表相关信息的SQL语句:

 代码如下 复制代码

SHOW DATABASES                                //列出 MySQL Server 数据库。
SHOW TABLES [FROM db_name]                    //列出数据库数据表。
SHOW CREATE TABLES tbl_name                    //导出数据表结构。
SHOW TABLE STATUS [FROM db_name]              //列出数据表及表状态信息。
SHOW COLUMNS FROM tbl_name [FROM db_name]     //列出资料表字段
SHOW FIELDS FROM tbl_name [FROM db_name],DESCRIBE tbl_name [col_name]。
SHOW FULL COLUMNS FROM tbl_name [FROM db_name]//列出字段及详情
SHOW FULL FIELDS FROM tbl_name [FROM db_name] //列出字段完整属性
SHOW INDEX FROM tbl_name [FROM db_name]       //列出表索引。
SHOW STATUS                                  //列出 DB Server 状态。
SHOW VARIABLES                               //列出 MySQL 系统环境变量。
SHOW PROCESSLIST                             //列出执行命令。
SHOW GRANTS FOR user                         //列出某用户权限

由上述SQL语句可以看到,我们可以使用SHOW FULL COLUMNS来列出字段及详情信息,示例代码:

 代码如下 复制代码
$rescolumns = mysql_query("SHOW FULL COLUMNS FROM ".TB_NAME."") ;
while($row = mysql_fetch_array($rescolumns)){
//  echo '字段名称:'.$row['Field'].'-数据类型:'.$row['Type'].'-注释:'.$row['Comment'];
//  echo '<br/> www.111cn.net <br/>';
  print_r($row);
}

打印结果:

 代码如下 复制代码

Array ( [0] => id [Field] => id [1] => char(2) [Type] => char(2) [2] => utf8_general_ci [Collation] => utf8_general_ci [3] => NO [Null] => NO [4] => PRI [Key] => PRI [5] => [Default] => [6] => [Extra] => [7] => select,insert,update,references [Privileges] => select,insert,update,references [8] => [Comment] => )

Array ( [0] => title [Field] => title [1] => char(50) [Type] => char(50) [2] => utf8_general_ci [Collation] => utf8_general_ci [3] => YES [Null] => YES [4] => [Key] => [5] => [Default] => [6] => [Extra] => [7] => select,insert,update,references [Privileges] => select,insert,update,references [8] => 建议存储:标题、姓名等信息 [Comment] => 建议存储:标题、姓名等信息 )

Array ( [0] => des [Field] => des [1] => varchar(255) [Type] => varchar(255) [2] => utf8_general_ci [Collation] => utf8_general_ci [3] => YES [Null] => YES [4] => [Key] => [5] => [Default] => [6] => [Extra] => [7] => select,insert,update,references [Privileges] => select,insert,update,references [8] => [Comment] => )

…………

补充说明信息:

当然你也可以通过mysql_list_fields — 列出 MySQL 结果中的字段。mysql_list_fields() 取得给定表名的信息,参数是数据库名和表名,返回一个结果指针。
但是,mysql_list_fields() 函数已过时。最好用 mysql_query() 来发出一条 SHOW COLUMNS FROM table [LIKE 'name'] 的 SQL 语句来代替。详细可参考PHP帮助文档:PHP: mysql_list_fields - Manua

文章详细介绍了csv文件在php中快速导入到mysql数据库中的例子,虽然从最简单的几百MB的到最后使用插件实现几个GB数据导入中间有一些嗑碰了,但结果还是好的。

对于数百万条数据量的CSV文件,文件大小可能达到数百M,如果简单读取的话很可能出现超时或者卡死的现象。

为了成功将CSV文件里的数据导入数据库,分批处理是非常必要的。

下面这个函数是读取CSV文件中指定的某几行数据:

 代码如下 复制代码

/**
 * csv_get_lines 读取CSV文件中的某几行数据
 * @param $csvfile csv文件路径
 * @param $lines 读取行数
 * @param $offset 起始行数
 * @return array
 * */
function csv_get_lines($csvfile, $lines, $offset = 0) {
    if(!$fp = fopen($csvfile, 'r')) {
     return false;
    }
    $i = $j = 0;
 while (false !== ($line = fgets($fp))) {
  if($i++ < $offset) {
   continue;
  }
  break;
 }
 $data = array();
 while(($j++ < $lines) && !feof($fp)) {
  $data[] = fgetcsv($fp);
 }
 fclose($fp);
    return $data;
}
调用方法:

 

$data = csv_get_lines('path/bigfile.csv', 10, 2000000);

print_r($data);

函数主要采用行定位的思路,通过跳过起始行数来实现文件指针定位。

至于数据如何入库本文不再详细讲述。

上述函数对500M以内的文件进行过测试,运行通畅,对于1GB的文件发现有点慢了,于是再接着找方法。

如何快速完整的操作大文件仍然还存在一些问题。

1、如何快速获取CSV大文件的总行数?

办法一:直接获取文件内容,使用换行符进行拆分得出总行数,这种办法对小文件可行,处理大文件时不可行;

办法二:使用fgets一行一行遍历,得出总行数,这种办法比办法一好一些,但大文件仍有超时的可能;

办法三:借助SplFileObject类,直接将指针定位到文件末尾,通过SplFileObject::key方法获取总行数,这种办法可行,且高效。

具体实现方法:

 代码如下 复制代码
$csv_file = 'path/bigfile.csv';
$spl_object = new SplFileObject($csv_file, 'rb');
$spl_object->seek(filesize($csv_file));
echo $spl_object->key();

2、如何快速获取CSV大文件的数据?

仍然使用PHP的SplFileObject类,通过seek方法实现快速定位。

 代码如下 复制代码
$csv_file = 'path/bigfile.csv';
$start = 100000;  // 从第100000行开始 www.111cn.net读取
$num = 100;    // 读取100行
$data = array();
$spl_object = new SplFileObject($csv_file, 'rb');
$spl_object->seek($start);
while ($num-- && !$spl_object->eof()) {
 $data[] = $spl_object->fgetcsv();
 $spl_object->next();
}
print_r($data);

 

综合上面两点,整理成一个csv文件读取的类:

 代码如下 复制代码

class CsvReader {
 private $csv_file;
 private $spl_object = null;
 private $error;
 
 public function __construct($csv_file = '') {
  if($csv_file && file_exists($csv_file)) {
   $this->csv_file = $csv_file;
  }
 }
 
 public function set_csv_file($csv_file) {
  if(!$csv_file || !file_exists($csv_file)) {
   $this->error = 'File invalid';
   return false;
  }
  $this->csv_file = $csv_file;
  $this->spl_object = null;
 }
 
 public function get_csv_file() {
  return $this->csv_file;
 }
 
 private function _file_valid($file = '') {
  $file = $file ? $file : $this->csv_file;
  if(!$file || !file_exists($file)) {
   return false;
  }
  if(!is_readable($file)) {
   return false;
  }
  return true;
 }
 
 private function _open_file() {
  if(!$this->_file_valid()) {
   $this->error = 'File invalid';
   return false;
  }
  if($this->spl_object == null) {
   $this->spl_object = new SplFileObject($this->csv_file, 'rb');
  }
  return true;
 }

 public function get_data($length = 0, $start = 0) {
  if(!$this->_open_file()) {
   return false;
  }
  $length = $length ? $length : $this->get_lines();
  $start = $start - 1;
  $start = ($start < 0) ? 0 : $start;
  $data = array();
  $this->spl_object->seek($start);
  while ($length-- && !$this->spl_object->eof()) {
   $data[] = $this->spl_object->fgetcsv();
   $this->spl_object->next();
  }
  return $data;
 }
 
 public function get_lines() {
  if(!$this->_open_file()) {
   return false;
  }
  $this->spl_object->seek(filesize($this->csv_file));
  return $this->spl_object->key();
 }
 
 public function get_error() {
  return $this->error;
 }
}

调用方法如下:

 代码如下 复制代码

include('CsvReader.class.php');

$csv_file = 'path/bigfile.csv';

$csvreader = new CsvReader($csv_file);

$line_number = $csvreader->get_lines();

$data = $csvreader->get_data(10);

 

echo $line_number, chr(10);

print_r($data);

 

其实,上述CsvReader类并不只针对CSV大文件,对于其他文本类型的大文件或超大文件同样可用,前提是将类中fgetcsv方法稍加改动为current即可。

 

很多时候,数据库中的数据需要导出成excel,以下是最简便的方法,不用导出excel的类,即使功能简单,但是对于没有复杂需求的项目“见效快”。

先定义头部信息,表示输出一个excel。然后再以table的形式把数据库的信息循环的echo出来,就好了。

 代码如下 复制代码

<?php

 

 header("Content-type:application/vnd.ms-excel");

 header("Content-Disposition:filename=xls_region.xls");

 $cfg_dbhost = 'localhost';

 $cfg_dbname = 'testdb';

 $cfg_dbuser = 'root';

 $cfg_dbpwd = 'root';

 $cfg_db_language = 'utf8';

 // END 配置

 


 //链接数据库

 $link = mysql_connect($cfg_dbhost,$cfg_dbuser,$cfg_dbpwd);

 mysql_select_db($cfg_dbname);

 //选择编码 www.111Cn.net

 mysql_query("set names ".$cfg_db_language);

 

 //users表

 $sql = "desc users";

 

 $res = mysql_query($sql);

 echo "<table><tr>";

 //导出表头(也就是表中拥有的字段)

 while($row = mysql_fetch_array($res)){

  $t_field[] = $row['Field']; //Field中的F要大写,否则没有结果

  echo "<th>".$row['Field']."</th>";

 }

 echo "</tr>";

 //导出100条数据

 $sql = "select * from users limit 100";

 $res = mysql_query($sql);

 while($row = mysql_fetch_array($res)){

  echo "<tr>";

  foreach($t_field as $f_key){

   echo "<td>".$row[$f_key]."</td>";

  }

  echo "</tr>";

 }

 echo "</table>";

 

?>

 

[!--infotagslink--]

相关文章

  • C#从数据库读取图片并保存的两种方法

    这篇文章主要介绍了C#从数据库读取图片并保存的方法,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...2021-01-16
  • C#中txt数据写入的几种常见方法

    这篇文章主要给大家介绍了关于C#中txt数据写入的几种常见方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-25
  • php把读取xml 文档并转换成json数据代码

    在php中解析xml文档用专门的函数domdocument来处理,把json在php中也有相关的处理函数,我们要把数据xml 数据存到一个数据再用json_encode直接换成json数据就OK了。...2016-11-25
  • PHP分布式框架如何使用Memcache同步SESSION教程

    本教程主要讲解PHP项目如何用实现memcache分布式,配置使用memcache存储session数据,以及memcache的SESSION数据如何同步。 至于Memcache的安装配置,我们就不讲了,以前...2016-11-25
  • c# 对CSV文件操作(写入、读取、修改)

    这篇文章主要介绍了c# 如何对CSV文件操作,帮助大家更好的理解和学习C#,感兴趣的朋友可以了解下...2020-11-03
  • python读取和保存mat文件的方法

    本文主要介绍了python读取和保存mat文件的方法,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-08-25
  • Android中使用SDcard进行文件的读取方法

    首先如果要在程序中使用sdcard进行存储,我们必须要在AndroidManifset.xml文件进行下面的权限设置: 在AndroidManifest.xml中加入访问SDCard的权限如下: <!--...2016-09-20
  • PHP+memcache实现消息队列案例分享

    memche消息队列的原理就是在key上做文章,用以做一个连续的数字加上前缀记录序列化以后消息或者日志。然后通过定时程序将内容落地到文件或者数据库。php实现消息队列的用处比如在做发送邮件时发送大量邮件很费时间的问...2014-05-31
  • perl大文件读取处理的模块介绍

    perl CPAN中有一个Tie-File 模块极大方便了对大文件的操作...2020-06-29
  • 使用MSScriptControl 在 C# 中读取json数据的方法

    下面小编就为大家带来一篇使用MSScriptControl 在 C# 中读取json数据的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • C#实现appSettings节点读取与修改的方法

    这篇文章主要介绍了C#实现appSettings节点读取与修改的方法,是非常实用的技巧,需要的朋友可以参考下...2020-06-25
  • golang文件读取-按指定BUFF大小读取方式

    这篇文章主要介绍了golang文件读取-按指定BUFF大小读取方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-12-22
  • Java读取PDF中的表格的方法示例

    本文主要介绍了Java读取PDF中的表格的方法示例,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-10-22
  • R语言读取csv文件出错的解决方案

    这篇文章主要介绍了R语言读取csv文件出错的解决方案,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-05-06
  • php读取本地php文件源代码输出显示

    下在看一个利用fopen,file_get_contents读取本地服务器中.php文件的代码并显示的一些方法总结 如我有两个文件a.php,b.php。 a.php文件中的语句是: 代码如...2016-11-25
  • Windows系统中使用C#读取文本文件内容的小示例

    这篇文章主要介绍了Windows系统中使用C#读取文本文件内容的小示例,包括一次一行地读取文本文件的方法,需要的朋友可以参考下...2020-06-25
  • python 根据excel中颜色区分读取的操作

    这篇文章主要介绍了python 根据excel中颜色区分读取的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-06
  • mybatis-plus读取JSON类型的方法实现

    这篇文章主要介绍了mybatis-plus读取JSON类型的方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-09-25
  • C#使用文件流读取文件的方法

    这篇文章主要介绍了C#使用文件流读取文件的方法,涉及C#中FileInfo类操作文件的技巧,需要的朋友可以参考下...2020-06-25
  • 基于Python正确读取资源文件

    这篇文章主要介绍了基于Python正确读取资源文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-14