概述:当一个表的数据很大,比如200G,这时太大,我们只靠索引也不好使了,这时我们需要分表和分区处理。分表有两种形式(水平分表和垂直分表)。
一、水平分表
核心思想:把一个大表,分割N个小表,小表和大表结构一样,只是把数据分散到不同的表中。
1.1 简单例子:比如说是通过ID直接登录(例如QQ号),可以直接使用下面的例子
每次登录验证的时候只要把传过来的id除3取模,根据模可以找到对应的表,然后再去对应的表做查询操作,以下为php的相关操作,注册以及登录。
register.php
1 <?php 2 //接收参数 3 //测试的参数有:Pwd,Name, Email 4 extract($_POST); 5 6 //检查是否为空 7 if(empty($Pwd) || empty($Name) || empty($Email)){ 8 die('参数不能为空!'); 9 } 10 11 //连接数据库 12 $link = mysql_connect('127.0.0.1:3306','root', 'root'); 13 if(!$link){ 14 die('数据库连接失败!'); 15 } 16 17 //选择数据库:这个数据库有:uuid表(产生Id的表)、User0表(存放模为0的用户信息)、User1表(存放模为1的用户信息)和User2表(存放模为2的用户信息) 18 mysql_select_db('test'); 19 20 $sql = 'INSERT INTO uuid VALUES(null)'; 21 if(mysql_query($sql, $link)){ 22 //获取刚刚插入的Id 23 $id = mysql_insert_id(); 24 25 //根据 Id%3 来确定该新用户存放的表 26 $table_name = 'User'.$Id%3; 27 28 $pwd = md5($Pwd); 29 $sql = "INSERT INTO $table_name VALUES($id, $Name, $pwd, $Email )"; 30 31 if(mysql_query($sql, $link)){ 32 echo '注册成功!'; 33 }else{ 34 echo '注册失败!'; 35 } 36 }
login.php
1 <?php 2 header("Content-Type:text/html;charset:utf-8"); 3 4 //接收参数:Id, Pwd 5 extract($_POST); 6 7 //判断是否为空 8 if(empty($Id) || empty($Pwd)){ 9 die('参数不能为空!'); 10 } 11 12 //连接数据库 13 $link = mysql_connect('127.0.0.1:3306', 'root', 'root'); 14 if(!$link){ 15 die('连接失败!'); 16 } 17 18 //选择数据库 19 mysql_select_db('test'); 20 21 $table_name = 'User'.$Id%3; 22 $sql = "SELECT * FROM $table_name WHERE Id = $Id"; 23 $rst = mysql_query($sql, $link); 24 25 if($row = mysql_fetch_assoc($rst)){ 26 $db_pwd = $row['Pwd']; 27 28 if($db_pwd == md5($Pwd)){ 29 echo '登录成功!'; 30 }else{ 31 echo '用户名或者密码错误!'; 32 } 33 }else{ 34 echo 'Id错误!'; 35 }
1.1 通过邮箱登录,通过邮箱对表进行分割
邮箱基本原理都是和Id差不多,就是要通过一个算法把md5字符串转成十进制的数,然后再取模,以下为把十六进制的md5字符串转成十进制的函数。
function bin_todec($list,$bin){
static $arr = array(
'0'=>0,
'1'=>1,
'2'=>2,
'3'=>3,
'4'=>4,
'5'=>5,
'6'=>6,
'7'=>7,
'8'=>8,
'9'=>9,
'A'=>10,
'B'=>11,
'C'=>12,
'D'=>13,
'E'=>14,
'F'=>15
);
if(!is_array($list))$list = array($list);
if($bin == 10) return $list; // 为十进制不转换
$outarr = array();//定义输出保存数组
foreach ($list as $num) {
$atnum = str_split($num); // 将字符串切割为字符数组
$atlen = count($atnum);
$total = 0;
$i = 1;
foreach ($atnum as $v) {
$v = strtoupper($v);
if(array_key_exists($v, $arr)){
if($arr[$v] ==0) continue;
$total = $total +$arr[$v]*pow($bin,$atlen-$i);
}
$i++;
}
$outarr[] = $total;
}
return $outarr;
}
$str = 'aa7g9gyut@u4545';
$arr = bin_todec(md5($str),16);
echo prev($arr).'<br/>';
// 这里不能使用$arr[0]%30 因为可能得到一个负数
$no = fmod(prev($arr),30);
echo 'no = '.$no;