Yii 2自動分表モデル
5797 ワード
実はある同級生の「ダイナミックモデル」を参考にしました
サブテーブルモデル
サブテーブルは元のテーブルをテンプレートとして使用して構造コピーを行い、コピーしたサブテーブル構造は、元のテーブルの構造、インデックスなどの変更を同期しません.
表を分割して使用する前に、元の表を十分に最適化することをお勧めします.
サブテーブル後のModelではfindBySqlメソッドはサポートされていません.
redis;
if($redis->sismember(static::$tableSetKey, $tableName))
return $tableName;
//if hit db
$db = static::getDb();
if($db->createCommand("SHOW TABLES LIKE '{$tableName}'")->queryAll()){
$redis->sadd(static::$tableSetKey, $tableName);
return $tableName;
}else{ //maybe
$redis->srem(static::$tableSetKey, $tableName);
}
//just do it
$originalTable = static::$originalName;
$createTableRet = $db->createCommand("SHOW CREATE TABLE `{$originalTable}`")->queryOne();
$createTable = str_replace("`{$originalTable}`","`{$tableName}`",$createTableRet['Create Table']);
$createTable = preg_replace('/\sAUTO_INCREMENT=\d+/','',$createTable);
try{
$db->createCommand($createTable)->execute();
$redis->sadd(static::$tableSetKey, $tableName);
}catch (Exception $ex){
throw new Exception("Error execute sql: {$createTable}");
}
return $tableName;
}
/**
* find
* @param $targetKey
* @return \yii\db\ActiveQuery
*/
public static function findx($targetKey = null){
static::$tableName = static::renderTable($targetKey);
return Yii::createObject(ActiveQuery::className(), [get_called_class(), ['from' => [static::tableName()]]]);
}
/**
* findAll
* @param null $targetKey
* @param array $params
* @return \yii\db\ActiveQuery[]
*/
public static function findAllx($targetKey = null,$params = []){
return static::findByConditionx($targetKey, $params)->all();
}
/**
* @Override
* @param array $row
* @return static
*/
public static function instantiate($row){
return new static(static::$targetKey);
}
/**
* findBySql
* @param string $sql
*/
public static function findBySql($sql){
throw new InvalidCallException("not allowed. {$sql}");
}
/**
* findOne
* @param null $targetKey
* @param array $condition
* @return null|static|ActiveQuery
*/
public static function findOnex($targetKey = null, $condition = []){
return static::findByConditionx($targetKey, $condition)->one();
}
/**
*
* @param null $targetKey
* @param $condition
* @return ActiveQuery[]|ActiveQuery
* @throws InvalidConfigException
*/
protected static function findByConditionx($targetKey = null, $condition){
$query = static::findx($targetKey);
if (!ArrayHelper::isAssociative($condition)) {
// query by primary key
$primaryKey = static::primaryKey();
if (isset($primaryKey[0])) {
$condition = [$primaryKey[0] => $condition];
} else {
throw new InvalidConfigException('"' . get_called_class() . '" must have a primary key.');
}
}
return $query->andWhere($condition);
}
}
サブテーブルモデル
where([]);
* @use Test::findAllx($vip_card,[]);
* @use Test::findOnex($vip_card,[]);
*
*/
class Test extends Modelx
{
// ,
protected static $originalName = 'test';
//redis set key
protected static $tableSetKey = 'project:tableset';
/**
*
* @Override
* @return string
*/
public static function getTableName(){
return static::$originalName . '_'. (static::$targetKey % 10);
}
}
サブテーブルは元のテーブルをテンプレートとして使用して構造コピーを行い、コピーしたサブテーブル構造は、元のテーブルの構造、インデックスなどの変更を同期しません.
表を分割して使用する前に、元の表を十分に最適化することをお勧めします.
サブテーブル後のModelではfindBySqlメソッドはサポートされていません.