天天看點

php mysql分表查詢效率_PHP 若Mysql單表存在資料量過大,進行邏輯分表

假設資料庫存在一個log表,用于記錄使用者作業系統的使用記錄。

有如下字段

user_id 操作人id

record_time 操作時間

operate_type 操作類型

record_content 操作内容

php mysql分表查詢效率_PHP 若Mysql單表存在資料量過大,進行邏輯分表

這個單表情況下,若日積月累的情況下,資料會逐日增多,最終達到百萬行的情況,這個時候如果是查詢表資料,會很慢。

于是,在PHP開發中可以在插入資料之前進行邏輯處理,并将單表分割成多個表。

原理

以日志表做示例。

根據目前時間的年月做基礎,使用PHP動态建立表,達到在2020-03月存儲的資料在log_2020_03表中,而2020-04月存儲的日志在log_2020_04表中

php mysql分表查詢效率_PHP 若Mysql單表存在資料量過大,進行邏輯分表

PHP代碼

class Log

{

private static $_instance;

private function __construct() {}

private function __clone() {}

public static function getInstance()

{

if (!(self::$_instance instanceof self)) {

self::$_instance = new self;

}

return self::$_instance;

}

public function record($userid,$typeId,$content,$time)

{

$redis = new Redis();

$redis->connect( '127.0.0.1', '6379' ); //redis伺服器位址和端口

$redis->auth( 'password' ); //redis密碼

$redis->select( 'db' ); //選擇redis庫

//log表名按照按照 'log_年_月'的規則

$ruleTable = 'log_' . date('Y-m');

$isExist = $redis->exists($ruleTable); //檢測redis中是否有log表的标志

//若redis查詢時未發現log表的标志,則動态建立log表

if ( !$isExist ) {

$sql = "CREATE TABLE `{$ruleTable}` (

`user_id` int(10) NOT NULL,

`record_time` datetime NOT NULL,

`operate_type` tinyint(10) NOT NULL,

`record_content` varchar(20) COLLATE utf8_unicode_ci NOT NULL

) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";

//執行mysql 此處省略資料庫連接配接代碼

$result = mysqli_query($sql);

//并記錄log表标志到redis中

$redis->setex($ruleTable,-1,1); //redis key位'log_年_月' 永久不過期 值為1

}

$sql = "INSERT INTO `log` (`user_id`, `record_time`, `operate_type`, `record_content`)

VALUES ('{$userId}', '{$time}, '{$typeId}', '{$content}')";

//執行mysql 此處省略資料庫連接配接代碼

$result = mysqli_query($sql);

//關閉redis連接配接

$redis->close();

}

}

Log::getInstance()->record( 1,10,'随便記錄',date('Y-m-d H:i:s') );