目录
简单介绍下两种引擎
- InnoDB支持事务功能、外键、行级锁等一些关系数据库的高级功能。
- MYISAM的性能更优,占用的存储空间少。
两种存储引擎各有优劣,怎么选择要视具体应用而定。
日志类的表只有添加和查询两种操作,业务简单,当然是要用MyISAM更合适。
下面测试下查询和存储方面具体相差多少
开始实测
数据准备:
- InnoDB和MyISAM各创建一张表,分别导入十万条数据
- 给`sql`字段创建全文索引
MYISAM表结构:
1CREATE TABLE `api_request_log` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) unsigned DEFAULT '0' COMMENT 'admin_id',
`user_name` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'admin_name',
`method` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '接口请求方式',
`path` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '接口地址',
`params` varchar(5000) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '请求参数',
`result` varchar(5000) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '返回结果',
`exec_time` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '接口用时,单位秒',
`sql` text COLLATE utf8mb4_unicode_ci COMMENT '执行的sql',
`ip` varchar(15) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '客户端IP',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `api_request_log_method_index` (`path`),
FULLTEXT KEY `api_request_log_params_fulltext` (`params`),
FULLTEXT KEY `api_request_log_sql_fulltext` (`sql`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='接口请求记录';
innodbdb表的实际数据和myisam表的数据是一样的,下图中显示的不准确
-
从数据占用的容量对比看MyISAM占用空间更小
-
从查询效率对比看MyISAM也确实更快
Laravel的建表语句
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateApiRequestLogTable extends Migration
{
public function up()
{
Schema::create('api_request_log', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id')->nullable()->default(0)->comment('admin_id');
$table->string('user_name',50)->nullable()->default(0)->comment('admin_name');
$table->string('method',10)->nullable()->default('')->comment('接口请求方式');
$table->string('path')->nullable()->default('')->comment('接口地址')->index();
$table->string('params',5000)->nullable()->default('')->comment('请求参数')->fulltext();
$table->string('result',5000)->nullable()->default('')->comment('返回结果');
$table->string('exec_time',10)->nullable()->comment('接口用时,单位秒');
$table->text('sql')->default('')->nullable()->comment('执行的sql')->fulltext();
$table->string('ip',15)->default('')->nullable()->comment('客户端IP');
$table->timestamp('created_at')->useCurrent()->comment('创建时间');
// $table->index('path');
$table->engine = 'MyISAM';
});
DB::statement("alter table `api_request_log` comment '接口请求记录'");
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('api_request_log');
}
}
Laravel定时任务-清理日志,只保留最新30万条记录
<?php
namespace App\Console\Commands;
use App\Models\ApiRequestLog;
use Illuminate\Console\Command;
class CleanApiLog extends Command
{
protected $signature = 'api-log:clean {limit=300000}';
protected $description = '清理接口请求记录表数据 可选参数limit来设置保留最新多少条数据(默认值是30万) ';
public function __construct()
{
parent::__construct();
}
public function handle(){
// 获取参数 保留多少条数据
$limit = $this->argument('limit');
$delete_count = $last_id = 0;
// 获取最新数据的ID
$last_id = ApiRequestLog::query()->latest()->value('id');
if ($last_id){
$end_id = $last_id - $limit; // 获取截止的ID
if ($end_id > 0){
$delete_count = ApiRequestLog::query()->where('id', '<', $end_id)->delete();
}
}
$msg = '清理接口请求记录表数据:执行完成 limit='.$limit.',last_id='.$last_id.',delete_count='.$delete_count;
info($msg);
return $this->info($msg);
}
}