代码如下 | 复制代码 |
class mysql { private $host; private $user; private $pass; private $database; private $charset; function __construct($host,$user,$pass,$database,$charset) { $this--->host=$host; $this->user=$user; $this->pass=$pass; $this->database=$database; $this->charset=$charset; $this->connect(); } private function connect()//连接函数 { mysql_connect($this->host,$this->user,$this->pass) or die ("连接数据库服务器失败!"); mysql_select_db($this->database) or die ("连接数据库失败!"); mysql_query("set names $this->charset"); } function select($sql,$tab,$col,$value)//选择函数 { $select=mysql_query("select $sql from $tab where $col=$value"); $row=mysql_fetch_array($select); return $row; } function insert($tab,$col,$value)//插入数据函数 { mysql_query("INSERT INTO $tab($col)values($value)"); } function update($tab,$col,$new_value,$colm,$value)//更新数据函数 { mysql_query("UPDATE $tab SET $col=$new_value where $colm=$value"); } function delete($tab,$col,$value)//删除数据函数 { mysql_query("DELETE FROM $tab where $col=$value"); } function close()//关闭连接函数 { mysql_close(); } } //$mysql=new mysql("127.0.0.1","root","120360150","test","gbk");连接数据库 //$sql=$mysql->select("*","admin","id","3");//选择数据 //print_r($sql);//打印返回的数组 //$mysql->insert("admin","user_name,user_pass","'123','123'");插入数据 //$mysql->update("admin","user_pass","22","id","3");更新数据 //$mysql->delete("admin","id","4");删除数据 //$mysql->close();关闭连接 ?> |
代码如下 | 复制代码 |
<?php /** * 创建时间: 2012年5月21日 * * 说明:分卷文件是以_v1.sql为结尾(20120522021241_all_v1.sql) * 功能:实现mysql数据库分卷备份,选择表进行备份,实现单个sql文件及分卷sql导入 * 使用方法: * * ------1. 数据库备份(导出)------------------------------------------------------------ //分别是主机,用户名,密码,数据库名,数据库编码 $db = new DBManage ( 'localhost', 'root', 'root', 'test', 'utf8' ); // 参数:备份哪个表(可选),备份目录(可选,默认为backup),分卷大小(可选,默认2000,即2M) $db->backup (); * ------2. 数据库恢复(导入)------------------------------------------------------------ //分别是主机,用户名,密码,数据库名,数据库编码 $db = new DBManage ( 'localhost', 'root', 'root', 'test', 'utf8' ); //参数:sql文件 $db->restore ( './backup/20120516211738_all_v1.sql'); *---------------------------------------------------------------------- */ class DBManage { var $db; // 数据库连接 var $database; // 所用数据库 var $sqldir; // 数据库备份文件夹 var $record; // 换行符 private $ds = "n"; // 存储SQL的变量 public $sqlContent = ""; // 每条sql语句的结尾符 public $sqlEnd = ";"; /** * 初始化 * * @param string $host * @param string $username * @param string $password * @param string $thisatabase * @param string $charset */ function __construct($host = 'localhost', $username = 'root', $password = '', $thisatabase = 'test', $charset = 'utf8') { $this->host = $host; $this->username = $username; $this->password = $password; $this->database = $thisatabase; $this->charset = $charset; // 连接数据库 $this->db = mysql_connect ( $this->host, $this->username, $this->password ) or die ( "数据库连接失败." ); // 选择使用哪个数据库 mysql_select_db ( $this->database, $this->db ) or die ( "无法打开数据库" ); // 数据库编码方式 mysql_query ( 'SET NAMES ' . $this->charset, $this->db ); } /* * ------------------------------------------数据库备份start---------------------------------------------------------- */ /** * 数据库备份 * 参数:备份哪个表(可选),备份目录(可选,默认为backup),分卷大小(可选,默认2000,即2M) * * @param $string $dir * @param int $size * @param $string $tablename */ function backup($tablename = '', $dir = '', $size = 2000) { //$dir = $dir ? $dir : 'backup/'; //$size = $size ? $size : 2000; $sql = ''; // 只备份某个表 if (! empty ( $tablename )) { echo '正在备份表' . $tablename . '<br />'; // 插入dump信息 $sql = $this->_retrieve(); // 插入表结构信息 $sql .= $this->_insert_table_structure ( $tablename ); // 插入数据 $data = mysql_query ( "select * from " . $tablename ); // 文件名前面部分 $filename = date ( 'YmdHis' ) . "_" . $tablename; // 字段数量 $num_fields = mysql_num_fields ( $data ); // 第几分卷 $p = 1; // 循环每条记录 while ( $record = mysql_fetch_array ( $data ) ) { // 单条记录 $sql .= $this->_insert_record ( $tablename, $num_fields, $record ); // 如果大于分卷大小,则写入文件 if (strlen ( $sql ) >= $size * 1000) { $file = $filename . "_v" . $p . ".sql"; if ($this->_write_file ( $sql, $file, $dir )) { echo "表-" . $tablename . "-卷-" . $p . "-数据备份完成,生成备份文件 <span style='color:#f00;'>$dir$filename</span><br />"; } else { echo "备份表-" . $tablename . "-失败<br />"; } // 下一个分卷 $p ++; // 重置$sql变量为空,重新计算该变量大小 $sql = ""; } } // sql大小不够分卷大小 if ($sql != "") { $filename .= "_v" . $p . ".sql"; if ($this->_write_file ( $sql, $filename, $dir )) { echo "表-" . $tablename . "-卷-" . $p . "-数据备份完成,生成备份文件 <span style='color:#f00;'>$dir$filename</span><br />"; } else { echo "备份卷-" . $p . "-失败<br />"; } } } else { // 备份全部表 if ($tables = mysql_query ( "show table status from " . $this->database )) { echo "读取数据库结构成功!<br />"; } else { exit ( "读取数据库结构成功!<br />" ); } // 插入dump信息 $sql .= $this->_retrieve(); // 文件名前面部分 $filename = date ( 'YmdHis' ) . "_all"; // 查出所有表 $tables = mysql_query ( 'SHOW TABLES' ); // 第几分卷 $p = 1; // 循环所有表 while ( $table = mysql_fetch_array ( $tables ) ) { // 获取表名 $tablename = $table [0]; // 获取表结构 $sql .= $this->_insert_table_structure ( $tablename ); $data = mysql_query ( "select * from " . $tablename ); $num_fields = mysql_num_fields ( $data ); // 循环每条记录 while ( $record = mysql_fetch_array ( $data ) ) { // 单条记录 $sql .= $this->_insert_record ( $tablename, $num_fields, $record ); // 如果大于分卷大小,则写入文件 if (strlen ( $sql ) >= $size * 1000) { $file = $filename . "_v" . $p . ".sql"; // 写入文件 if ($this->_write_file ( $sql, $file, $dir )) { echo "-卷-" . $p . "-数据备份完成,生成备份文件<span style='color:#f00;'>$dir$file</span><br />"; } else { echo "备份卷-" . $p . "-失败<br />"; } // 下一个分卷 $p ++; // 重置$sql变量为空,重新计算该变量大小 $sql = ""; } } } // sql大小不够分卷大小 if ($sql != "") { $filename .= "_v" . $p . ".sql"; if ($this->_write_file ( $sql, $filename, $dir )) { echo "-卷-" . $p . "-数据备份完成,生成备份文件 <span style='color:#f00;'>$dir$filename<br />"; } else { echo "备份卷-" . $p . "-失败<br />"; } } } } /** * 插入数据库备份基础信息 * * @return string */ private function _retrieve() { $value = ''; $value .= '--' . $this->ds; $value .= '-- MySQL database dump' . $this->ds; $value .= '-- Created by DBManage class, Power By yanue. ' . $this->ds; $value .= '-- http://yanue.net ' . $this->ds; $value .= '--' . $this->ds; $value .= '-- 主机: ' . $this->host . $this->ds; $value .= '-- 生成日期: ' . date ( 'Y' ) . ' 年 ' . date ( 'm' ) . ' 月 ' . date ( 'd' ) . ' 日 ' . date ( 'H:i' ) . $this->ds; $value .= '-- MySQL版本: ' . mysql_get_server_info () . $this->ds; $value .= '-- PHP 版本: ' . phpversion () . $this->ds; $value .= $this->ds; $value .= '--' . $this->ds; $value .= '-- 数据库: `' . $this->database . '`' . $this->ds; $value .= '--' . $this->ds . $this->ds; $value .= '-- -------------------------------------------------------'; $value .= $this->ds . $this->ds; return $value; } /** * 插入表结构 * * @param unknown_type $table * @return string */ private function _insert_table_structure($table) { $sql = ''; $sql .= "--" . $this->ds; $sql .= "-- 表的结构" . $table . $this->ds; $sql .= "--" . $this->ds . $this->ds; // 如果存在则删除表 $sql .= "DROP TABLE IF EXISTS `" . $table . '`' . $this->sqlEnd . $this->ds; // 获取详细表信息 $res = mysql_query ( 'SHOW CREATE TABLE `' . $table . '`' ); $row = mysql_fetch_array ( $res ); $sql .= $row [1]; $sql .= $this->sqlEnd . $this->ds; // 加上 $sql .= $this->ds; $sql .= "--" . $this->ds; $sql .= "-- 转存表中的数据 " . $table . $this->ds; $sql .= "--" . $this->ds; $sql .= $this->ds; return $sql; } /** * 插入单条记录 * * @param string $table * @param int $num_fields * @param array $record * @return string */ private function _insert_record($table, $num_fields, $record) { // sql字段逗号分割 $insert = $comma = ""; $insert .= "INSERT INTO `" . $table . "` VALUES("; // 循环每个子段下面的内容 for($i = 0; $i < $num_fields; $i ++) { $insert .= ($comma . "'" .mysql_real_escape_string ( $record [$i] ) . "'"); $comma = ","; } $insert .= ");" . $this->ds; return $insert; } /** * 写入文件 * * @param string $sql * @param string $filename * @param string $dir * @return boolean */ private function _write_file($sql, $filename, $dir) { $dir = $dir ? $dir : './backup/'; // 不存在文件夹则创建 if (! file_exists ( $dir )) { mkdir ( $dir ); } $re = true; if (! @$fp = fopen ( $dir . $filename, "w+" )) { $re = false; echo "打开文件失败!"; } if (! @fwrite ( $fp, $sql )) { $re = false; echo "写入文件失败,请文件是否可写"; } if (! @fclose ( $fp )) { $re = false; echo "关闭文件失败!"; } return $re; } /* * * -------------------------------上:数据库导出-----------分割线----------下:数据库导入-------------------------------- */ /** * 导入备份数据 * 说明:分卷文件格式20120516211738_all_v1.sql * 参数:文件路径(必填) * * @param string $sqlfile */ function restore($sqlfile) { // 检测文件是否存在 if (! file_exists ( $sqlfile )) { exit ( "文件不存在!请检查" ); } $this->lock ( $this->database ); // 获取数据库存储位置 $sqlpath = pathinfo ( $sqlfile ); $this->sqldir = $sqlpath ['dirname']; // 检测是否包含分卷,将类似20120516211738_all_v1.sql从_v分开,有则说明有分卷 $volume = explode ( "_v", $sqlfile ); $volume_path = $volume [0]; echo "请勿刷新及关闭浏览器以防止程序被中止,如有不慎!将导致数据库结构受损<br />"; echo "正在导入备份数据,请稍等!<br />"; if (empty ( $volume [1] )) { echo "正在导入sql:<span style='color:#f00;'>" . $sqlfile . '</span><br />'; // 没有分卷 if ($this->_import ( $sqlfile )) { echo "数据库导入成功!"; } else { exit ( '数据库导入失败!' ); } } else { //$volume_id = array(); // 存在分卷,则获取当前是第几分卷,循环执行余下分卷 $volume_id = explode ( ".sq", $volume [1] ); // 当前分卷为$volume_id $volume_id = intval ( $volume_id [0] ); while ( $volume_id ) { $tmpfile = $volume_path . "_v" . $volume_id . ".sql"; // 存在其他分卷,继续执行 if (file_exists ( $tmpfile )) { // 执行导入方法 echo "正在导入分卷<span style='color:#f00;'>" . $tmpfile . '</span><br />'; if ($this->_import ( $tmpfile )) { } else { exit ( "导入分卷<span style='color:#f00;'>" . $tmpfile . '</span>失败!可能是数据库结构已损坏!请尝试从分卷1开始导入' ); } } else { echo "此分卷备份全部导入成功!<br />"; return; } $volume_id++; } } } /** * 将sql导入到数据库(普通导入) * * @param string $sqlfile * @return boolean */ private function _import($sqlfile) { // sql文件包含的sql语句数组 $sqls = array (); $f = fopen ( $sqlfile, "rb" ); // 创建表缓冲变量 $create = ''; while ( ! feof ( $f ) ) { // 读取每一行sql $line = fgets ( $f ); // 如果包含'-- '等注释,或为空白行,则跳过 if (trim ( $line ) == '' || preg_match ( '/--*?/', $line, $match )) { continue; } // 如果结尾包含';'(即为一个完整的sql语句,这里是插入语句),并且不包含'ENGINE='(即创建表的最后一句), if (! preg_match ( '/;/', $line, $match ) || preg_match ( '/ENGINE=/', $line, $match )) { // 将本次sql语句与创建表sql连接存起来 $create .= $line; // 如果包含了创建表的最后一句 if (preg_match ( '/ENGINE=/', $create, $match )) { // 则将其合并到sql数组 $sqls [] = $create; // 清空当前,准备下一个表的创建 $create = ''; } // 跳过本次 continue; } $sqls [] = $line; } fclose ( $f ); // 循环sql语句数组,分别执行 foreach ( $sqls as $sql ) { str_replace ( "n", "", $sql ); if (! mysql_query ( trim ( $sql ) )) { echo mysql_error (); return false; } } return true; } /* * -------------------------------数据库导入end--------------------------------- */ // 关闭数据库连接 private function close() { mysql_close ( $this->db ); } // 锁定数据库,以免备份或导入时出错 private function lock($tablename, $op = "WRITE") { if (mysql_query ( "lock tables " . $tablename . " " . $op )) return true; else return false; } // 解锁 private function unlock() { if (mysql_query ( "unlock tables" )) return true; else return false; } // 析构 function __destruct() { mysql_query ( "unlock tables", $this->db ); mysql_close ( $this->db ); } } $db = new DBManage ( 'localhost', 'root', '', 'tao', 'gbk' ); //$db->backup ('tao_admin'); $db->restore ( './backup/20140228222713_tao_admin_v1.sql'); |
大数据的时候,压力不在PHP,主要在MySQL。
PHP可以做负载均衡,10台机器抗不住就用20台或者100台,这都不是瓶颈。
但是MySQL是单点的,无论做多少从库,都是优化查询,更新数据就无法只是简单的通过加机器解决了。
而且查询也可以通过Memcache缓存减轻压力,所以不必要做多少从库的,一般1主4从就可以了。
下面主要介绍下数据库的解决方案:
假设用户可以通过“登录名”、“邮箱”或“手机号”登录。
表结构如下:
登录名与ID表,根据login_hash分100张表
CREATE TABLE user_login(
login_name VARCHAR() 用户登录名,可以是“登录名”、“邮箱”或“手机号”登录
login_hash BIGINT 用户登录名的HASH码
user_id BIGINT 用户ID
);
CREATE TABLE user_login0 LIKE user_login;
CREATE TABLE user_login1 LIKE user_login;
… …
CREATE TABLE user_login100 LIKE user_login;
ID与用户信息表,根据user_id分100张表
CREATE TABLE user_info(
user_id BIGINT 用户ID
login_pwd CHAR() 用户登录密码
… … 其他信息,家庭住址、手机号、性别等等
);
CREATE TABLE user_info0 LIKE user_info;
CREATE TABLE user_info1 LIKE user_info;
… …
CREATE TABLE user_info2 LIKE user_info;
业务实现逻辑:
依赖服务器:实现一个自增ID的服务(相当于oracle的sequence),也可以自己实现(用PHP+MySQL或者用C实现都可以)。目的是可以 从这个服务中取ID,每次取的ID数都是在上次基础上+1,和MySQL的autoincrement很像,只是不能在表内部自增。
注册流程
1)验证用户名、邮箱、手机号、密码等格式。省略…
2)从服务中取一个ID,假设是115。
3)如果用户的登录类型是邮箱(如:$loginName=’songhuan@zixue.it’),则在登录名前加上前缀登录名结果(如:$loginName=’mail_songhuan@zixue.it’)
4)求登录名的HASH值:$loginHash=md5($loginName); 对md5值hash,可以求asc码,或者用自己的算法,最后得出$loginHash=16位或32位的整数
5)$tableName = ‘user_login’ . ($loginHash%100),如果获取user_login表名,假如结果为user_login88。
$tableName = ‘user_info’ . (115%100),如果获取user_info表名。
6)执行SQL:
INSERT INTO user_login88 (login_name, login_hash, user_id) VALUES (‘songhuan@zixue.it’, 183239324323, 1);
INSERT INTO user_info15 (user_id, login_pwd) VALUES (115, ‘afieflefiefladifadfadfe’);
登录流程 www.111cn.net
1)如果用户的登录类型是邮箱(如:$loginName=’songhuan@zixue.it’),则在登录名前加上前缀登录名结果(如:$loginName=’mail_songhuan@zixue.it’)
2)$loginHash=ord(md5($loginName));
3)$tableName = ‘user_login’ . ($loginHash%100); 假如结果为user_login88
4)执行SQL:SELECT id FROM user_login88 WHERE login_hash = $loginHash;
如果查询不到数据,则登录名不存在
5)如果能获取到,id=115,则$tableName = ‘user_info’ . (115%100);
SELECT id, pwd … FROM user_info15 WHERE id = 115;
6)匹配密码,如果密码不相等,返回false
7)如果密码相等,将用户ID加密放入COOKIE,将用户信息存入Memcache
临时写的一个东西省时间而写的,因为有几千个产品带大图,所以我们写了这么一个程序了,希望对各位有帮助。
目录效果如
导入方法
http://www.111cn.net/ a.php?typeid=你的id&path=你的目录
处理php文件
代码如下 | 复制代码 |
$typeid = $_GET['typeid']; $path = $_GET['path']; if( $path =="" )
$sql2 ="INSERT INTO `dedecms_addonarticle17` (`aid`, `typeid`, `body`, `redirecturl`, `templet`, `userip`, `s_type`) VALUES mysql_query( $sql3 ) or die( mysql_error().$sql3 ); echo '导入成功'; print_r($array); |
之后碰到一个小问题,就是导入数据在栏目可以看到,但在所有数据中看不到记录,生成时只有选择栏目生成才可以但用一键生成有问题,这个时我在发布时间是固定一个以前的时间了,大家可以使用time函数来获取当前时间了。
本站原创文章,转让注明来自http://www.111cn.net/phper/php.html
吓死人的节奏,在后台发现一个功能失效了,各种检测,然后检测到可能是数据库里的某个表不小心被删了。就先备份了一下数据(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了,这样数据库就移到了另一个地方,同时也方便你移站了。