Expand description
Schema 缓存模块 — 数据表字段元数据缓存(对齐 PHP think\db\Fetch::getFields)
本模块提供数据表字段元数据(schema)的缓存能力,对齐 PHP ThinkPHP
think\db\Fetch 的字段缓存机制。在 PHP 端,每次查询表字段信息都需要
执行 SHOW COLUMNS FROM <table>(MySQL)或等价 SQL,为避免重复查询,
ThinkPHP 将字段元数据缓存到 Cache 中(默认永不过期)。
§PHP 对齐
§核心 API 映射
| PHP 方法 | Rust 方法 | 说明 |
|---|---|---|
Fetch::getFields($table) | SchemaCache::get_schema | 从缓存读取字段元数据 |
Fetch::setFieldCache($table, $data) | SchemaCache::set_schema | 写入字段缓存 |
Fetch::getFieldCacheKey($table) | SchemaCache::cache_key | 构造缓存 key |
Cache::delete($key) | SchemaCache::forget_schema | 清除单表字段缓存 |
Cache::clear() | SchemaCache::clear | 清除所有字段缓存 |
Cache::has($key) | SchemaCache::has_schema | 判断字段缓存是否存在 |
Fetch::getFields 内部回源 | SchemaCache::remember_schema | 缓存未命中时回源加载 |
§PHP getFields 缓存行为
PHP think\db\Fetch::getFields 核心逻辑:
protected function getFields(string $tableName): array
{
// 1. 从缓存读取
if ($this->config['fields_cache']) {
$guid = $tableName . $this->connection->getConfig('fields_cache_flag');
$content = $this->connection->getCacheHandler()->get($guid);
if ($content) {
return $content; // 缓存命中
}
}
// 2. 缓存未命中,查询数据库
$fields = $this->connection->getFields($tableName);
// 3. 写入缓存(永不过期)
if ($this->config['fields_cache']) {
$guid = $tableName . $this->connection->getConfig('fields_cache_flag');
$this->connection->getCacheHandler()->set($guid, $fields);
}
return $fields;
}关键行为对齐:
- 默认 TTL = None(永不过期),对齐 PHP
$expire = null - 缓存 key 格式:
schema_cache:<table_name>(PHP 端为db_<flag>_<table_name>) - 缓存未命中时通过 loader 回源加载(对齐 PHP
getFields内部查询)
§PHP 字段元数据结构
PHP getFields 返回的字段元数据结构:
[
'id' => [
'name' => 'id',
'type' => 'int(11) unsigned',
'notnull' => true,
'default' => null,
'primary' => true,
'autoinc' => true,
],
'name' => [
'name' => 'name',
'type' => 'varchar(255)',
'notnull' => false,
'default' => null,
'primary' => false,
'autoinc' => false,
],
]Rust 端通过 ColumnDefinition 提供等价结构,并扩展 unsigned、comment 字段。
§架构说明
- 基于
Cachefacade:复用crate::cache::Cache的驱动管理、序列化、标签系统, 不重新实现底层存储 - 标签批量清除:所有字段缓存 key 注册到标签(tag),
SchemaCache::clear通过标签一次性清除所有表字段缓存,对齐 PHPCache::clear()的批量语义 - 无锁设计:
SchemaCache自身状态在构造后不可变(key_prefix、tag_name), 所有并发安全由底层Cache保证(RwLock+parking_lot) - 可配置前缀:通过
SchemaCache::with_prefix可自定义缓存 key 前缀, 支持多实例隔离(如不同数据库连接使用不同前缀)
§使用示例
ⓘ
use sz_rust_core::cache::{Cache, MemoryCacheDriver};
use sz_rust_core::schema_cache::{SchemaCache, TableSchema, ColumnDefinition};
use std::sync::Arc;
// 创建 Cache facade
let cache = Arc::new(Cache::new());
cache.register_default(MemoryCacheDriver::new());
// 创建 SchemaCache
let schema_cache = SchemaCache::new(cache.clone());
// 构造表字段元数据
let schema = TableSchema::new("users", vec![
ColumnDefinition::new("id", "int(11) unsigned")
.nullable(false)
.primary_key(true)
.auto_increment(true),
ColumnDefinition::new("name", "varchar(255)")
.nullable(false),
]);
// 写入缓存(永不过期)
schema_cache.set_schema("users", &schema, None).unwrap();
// 从缓存读取
let cached = schema_cache.get_schema("users").unwrap().unwrap();
assert_eq!(cached.columns.len(), 2);
// remember_schema:缓存未命中时自动加载
let schema = schema_cache.remember_schema("orders", |_table| {
Ok(TableSchema::new("orders", vec![
ColumnDefinition::new("id", "bigint(20)")
.primary_key(true)
.auto_increment(true),
]))
}).unwrap();Structs§
- Column
Definition - 单个字段定义(对齐 PHP
think\db\Fetch::getFields返回的单字段元数据) - Schema
Cache - 数据表字段缓存(对齐 PHP
think\db\Fetch字段缓存机制) - Table
Schema - 数据表字段元数据(对齐 PHP
think\db\Fetch::getFields返回的完整字段列表)
Enums§
- Schema
Cache Error - Schema 缓存错误