很多主流mvc框架都提供了切换数据库访问方法
thinkphp切换数据库
分表的话 在查询前先根据分表规则把表名查出
这里用两台机子简单以同个业务库分库,同个表分表,演示插入、查询如何定位库和表并最终成功执行
两台机子:
server1:192.168.1.198
server2:192.168.1.199
两台机子都执行下面操作
1、先创建10个数据库,每个数据库10个表
当然也可以改成百库百表,也可手动创建,我为了方便写了个脚本批量创建
create.php";
}else{
//echo "create error!";
}
}
}
}
}else{
echo "connect error!!!!";
}
Config.php
$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'];
}
}
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 的库
* (224 / 10) % 10 = 1 为编号为 2 的表
*/
'database_split' => array(1, 10),
'table_split' => array(10, 10),
),
),
);
return $config;
Model.php
config = new Config($this->dbnamePrefix, $this->tablePrefix, $id); //根据id找到对应库和表
$this->connection = new Pdo($this->config->dsn, $this->config->user, $this->config->password);//实例化pdo
$this->connection->exec("set names utf8");
$this->dbname = $this->config->dbname;
$this->table = $this->config->table;
}
public function update(array $data, array $where = array()){
}
public function select(array $condition){
$sqlwhere='';
if(!empty($condition)){
foreach ($condition as $field => $value) {
$where[] = '`'.$field.'`='."'".addslashes($value)."'";
}
$sqlwhere .= ' '.implode(' and ', $where);
}
$sql="select * from ".$this->dbname.'.'.$this->table;
if($sqlwhere){
$sql.=" where $sqlwhere";
}
$res=$this->connection->query($sql);
$data['data']=$res->fetchAll(PDO::FETCH_ASSOC);
$data['info']=array("dsn"=>$this->config->dsn,"dbname"=>$this->dbname,"table"=>$this->table,"sql"=>$sql);
return $data;
}
public function insert(array $arrData) {
$name = $values = '';
$flag = $flagV = 1;
$true = is_array( current($arrData) );//判断是否一次插入多条数据
if($true) {
//构建插入多条数据的sql语句
foreach($arrData as $arr) {
$values .= $flag ? '(' : ',(';
foreach($arr as $key => $value) {
if($flagV) {
if($flag) $name .= "$key";
$values .= "'$value'";
$flagV = 0;
} else {
if($flag) $name .= ",$key";
$values .= ",'$value'";
}
}
$values .= ') ';
$flag = 0;
$flagV = 1;
}
} else {
//构建插入单条数据的sql语句
foreach($arrData as $key => $value) {
if($flagV) {
$name = "$key";
$values = "('$value'";
$flagV = 0;
} else {
$name .= ",$key";
$values .= ",'$value'";
}
}
$values .= ") ";
}
$sql = "insert into ".$this->dbname.'.'.$this->table." ($name) values $values";
if( ($rs = $this->connection->exec($sql) ) > 0 ) {
return array("dsn"=>$this->config->dsn,"dbname"=>$this->dbname,"table"=>$this->table,"sql"=>$sql);
}
return false;
}
public function query($sql){
return $this->connection->query($sql);
}
}
使用主键id作为分表字段,那最好就不要使用自增了,可使用uuid
User.php
$userId,'name'=>'大明'.$userId,'password'=>'14e1b600b1fd579f47433b88e8d85291','sex'=>'男');
if($result=$user->insert($data)){
echo '插入成功:','';
print_r($result);
}
$condition=array("id"=>$userId);
$list=$user->select($condition);
if($list){
echo '查询成功:','';
print_r($list);
}