php分库分表例⼦,mysql分库分表实战及php代码操作完整实例当单表达到⼏千万时,查询⼀次要很久,如果有联合查询,有可能会死在那
分库分表主要就是解决这个问题,减⼩数据库的负担,缩短查询时间
分库:
1)按功能分
⽤户类库、商品类库、订单类库、⽇志类、统计类库...
1)按地区分
每个城市或省市⼀个同样的库,加上后缀或前缀如:db_click_bj、db_
分表:
1、横向分表 解决表记录太⼤问题
1)按某个字段分,
如:discuz的附件表分成10个附件分表pre_forum_attachment_0到pre_forum_attachment_9,还有1个附件索引表
pre_forum_attachment存储tid和附件id关系
根据主题的tid最后⼀位来决定附件要保存在哪个分表,
2)按⽇期分表
⼀些⽇志、统计类的可以按年、⽉、⽇、周分表
如:点击量统计click_201601、click_201602
3)使⽤mysql的merge
先把分表创建好,然后创建总表指定engine= MERGE UNION=(table1,table2) INSERT_METHOD = LAST;
2、纵向分表 解决列过多问题
1)经常组合查询的列放在⼀个表,常⽤字段的表可考虑Memory引擎
2)不经常使⽤的字段单独成表
3)把text、blob等⼤字段拆分放在附表
如:phpcms的⽂章表分成主表v9_news和从表v9_news_data,主表存标题、关键字、浏览量等,从表存具体内容、模板等
很多主流mvc框架都提供了切换数据库访问⽅法
thinkphp切换数据库
$this->db(1,"mysql://root:123456@localhost:3306/test")->query("查询sql");//数据库连接信息可放在配置⽂件
$this->db(1)->query("查询sql");//下次直接使⽤编号1定位
分表的话 在查询前先根据分表规则把表名查出
这⾥⽤两台机⼦简单以同个业务库分库,同个表分表,演⽰插⼊、查询如何定位库和表并最终成功执⾏
两台机⼦:
server1:192.168.1.198
server2:192.168.1.199
两台机⼦都执⾏下⾯操作
1、先创建10个数据库,每个数据库10个表
当然也可以改成百库百表,也可⼿动创建,我为了⽅便写了个脚本批量创建
create.php
ini_set('memory_limit', '-1');
$con=mysql_connect("192.168.1.198","open","123456");
if($con){
for($i=0;$i<10;$i++){//10个库
$sql="drop database cloude_{$i};";//删库 谨慎
mysql_query($sql);
$sql="create database cloude_{$i} default character set utf8 collate utf8_general_ci;"; $do=mysql_query($sql,$con)or die(mysql_error());
if($do){
mysql_select_db("cloude_{$i}",$con);
mysql_query("set name gtf8");
for($j=0;$j<10;$j++){//10个表
$sql="drop table if exists user_{$j};";
mysql_query($sql);
$sql="create table user_{$j}
(
id char(36) not null primary key,
name char(15) not null default '',
password char(32) not null default '',
sex char(1) not null default '男'
)engine=InnoDB;";
$do=mysql_query($sql,$con) or die(mysql_error());
if($do){
//echo "create table user_{$j} successful!
";
}else{
//echo "create error!";
}
}
}
}
}else{
echo "connect error";
}
2、分库分表路由实现
Config.php
class Config{
public $dsn;
public $user;
public $password;
public $dbname; //分库分表后得到的数据库名
public $table; //分库分表后得到的表名
private static $config;//mysql配置数组
private static $configFile = 'mysql.php'; //配置⽂件路径
public function __construct($dbname, $table, $id = 0){
if (is_null(static::$config)) {
$config = include(static::$configFile);
static::$config = $config;
}
$config = static::$config;
if (isset($config['shared']) && isset($config['shared'][$dbname])) {
$dbconfig = $config['shared'][$dbname];
$id = is_numeric($id) ? (int)$id : crc32($id);
$database_id = ($id / $dbconfig['database_split'][0]) % $dbconfig['database_split'][1]; $table_id = ($id / $dbconfig['table_split'][0]) % $dbconfig['table_split'][1];
foreach ($dbconfig['host'] as $key => $conf) {
list($from, $to) = explode('-', $key);
if ($from <= $database_id && $database_id <= $to) {
$the_config = $conf;
}
}
$this->dbname = $dbname . '_' . $database_id;
$this->table = $table . '_' . $table_id;
} else {
$this->dbname = $dbname;
$this->table = $table;
$the_config = $config['db'][$dbname];
}
$c = $the_config;
if (isset($c['unix_socket']) && $c['unix_socket']) {
$this->dsn = sprintf('mysql:dbname=%s;unix_socket=%s', $this->dbname, $c['unix_socket']);
} else {
$this->dsn = sprintf('mysql:dbname=%s;host=%s;port=%s', $this->dbname, $c['host'], $c['port']); }
$this->user = $c['user'];
$this->password = $c['password'];
}
}
3、数据库配置⽂件
mysql.php
$default = array(
'unix_socket' => null,
'host' => '192.168.1.198',
'port' => '3306',
'user' => 'open',
'password' => '123456',
);
$db_199 = array(
'unix_socket' => null,
'host' => '192.168.1.199',
'port' => '3306',
'user' => 'open',
'password' => '123456',
);
$config = array(
/
/ 不进⾏分库分表的数据库
'db' => array(
'hadoop' => $default,
),
// 分库分表
'shared' => array(
'cloude' => array(
'host' => array(
/**
* 编号为 0 到 4 的库使⽤的链接配置
*/
'0-4' => $default,
/**
* 编号为 5 到 9 的库使⽤的链接配置
*/
'5-9' => $db_199,
),
// 分库分表规则
/**
* 下⾯的配置对应10库10表
* 如果根据 uid 进⾏分表,假设 uid 为 224,对应的库表为:
* (224 / 1) % 10 = 4 为编号为 4 的库
php修改数据库内容
* (224 / 10) % 10 = 1 为编号为 2 的表
*/
'database_split' => array(1, 10),
'table_split' => array(10, 10),
),
),
);
return $config;
4、模型类操作数据库
Model.php
require_once 'Config.php';//引⼊配置信息
class Model{
public $config;//数据库配置
public $connection;//pdo
protected $dbnamePrefix; //库前缀如cloude_50 前缀为cloude protected $tablePrefix; //表前缀

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。