注册表新增数据库存储同步

This commit is contained in:
2025-10-11 11:56:19 +08:00
parent 4e34063373
commit 47c68cadf3
23 changed files with 4396 additions and 160 deletions
+241
View File
@@ -0,0 +1,241 @@
const { defaultLogger } = require('../utils/logger');
const logger = defaultLogger.child('RegistrySchema');
/**
* 注册表数据库表结构管理
*/
class RegistrySchema {
constructor(databaseManager) {
this.db = databaseManager;
}
/**
* 初始化所有注册表相关的数据库表
*/
async initializeTables() {
try {
await this.createArtistsTable();
await this.createArtworksTable();
await this.createRegistryMetaTable();
logger.info('注册表数据库表初始化完成');
return { success: true };
} catch (error) {
logger.error('初始化注册表数据库表失败:', error);
throw error;
}
}
/**
* 创建艺术家表
*/
async createArtistsTable() {
const tableName = 'registry_artists';
if (await this.db.tableExists(tableName)) {
logger.debug(`${tableName} 已存在,跳过创建`);
return;
}
const createSQL = `
CREATE TABLE ${tableName} (
id INT AUTO_INCREMENT PRIMARY KEY,
artist_name VARCHAR(255) NOT NULL UNIQUE COMMENT '艺术家名称',
normalized_name VARCHAR(255) NOT NULL COMMENT '标准化后的艺术家名称',
artwork_count INT DEFAULT 0 COMMENT '作品数量',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
INDEX idx_artist_name (artist_name),
INDEX idx_normalized_name (normalized_name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='注册表艺术家表';
`;
await this.db.createTable(tableName, createSQL);
}
/**
* 创建作品表
*/
async createArtworksTable() {
const tableName = 'registry_artworks';
if (await this.db.tableExists(tableName)) {
logger.debug(`${tableName} 已存在,跳过创建`);
return;
}
const createSQL = `
CREATE TABLE ${tableName} (
id INT AUTO_INCREMENT PRIMARY KEY,
artist_id INT NOT NULL COMMENT '艺术家ID',
artwork_id BIGINT NOT NULL COMMENT '作品ID',
artist_name VARCHAR(255) NOT NULL COMMENT '艺术家名称(冗余字段,便于查询)',
file_path TEXT COMMENT '文件路径(可选)',
download_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '下载时间',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
UNIQUE KEY uk_artist_artwork (artist_id, artwork_id),
INDEX idx_artwork_id (artwork_id),
INDEX idx_artist_id (artist_id),
INDEX idx_artist_name (artist_name),
INDEX idx_download_date (download_date),
FOREIGN KEY (artist_id) REFERENCES registry_artists(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='注册表作品表';
`;
await this.db.createTable(tableName, createSQL);
}
/**
* 创建注册表元数据表
*/
async createRegistryMetaTable() {
const tableName = 'registry_meta';
if (await this.db.tableExists(tableName)) {
logger.debug(`${tableName} 已存在,跳过创建`);
return;
}
const createSQL = `
CREATE TABLE ${tableName} (
id INT AUTO_INCREMENT PRIMARY KEY,
meta_key VARCHAR(100) NOT NULL UNIQUE COMMENT '元数据键',
meta_value TEXT COMMENT '元数据值',
description TEXT COMMENT '描述',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
INDEX idx_meta_key (meta_key)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='注册表元数据表';
`;
await this.db.createTable(tableName, createSQL);
// 插入初始元数据
await this.initializeMetaData();
}
/**
* 初始化元数据
*/
async initializeMetaData() {
const metaData = [
{
meta_key: 'version',
meta_value: '1.0.5',
description: '注册表版本号'
},
{
meta_key: 'storage_type',
meta_value: 'database',
description: '存储类型:database 或 json'
},
{
meta_key: 'created_at',
meta_value: new Date().toISOString(),
description: '注册表创建时间'
},
{
meta_key: 'last_migration',
meta_value: new Date().toISOString(),
description: '最后一次迁移时间'
}
];
for (const meta of metaData) {
try {
await this.db.insert('registry_meta', meta);
} catch (error) {
// 如果键已存在,忽略错误
if (!error.message.includes('Duplicate entry')) {
throw error;
}
}
}
}
/**
* 获取表结构信息
*/
getTableInfo() {
return {
artists: {
tableName: 'registry_artists',
description: '存储艺术家信息',
fields: {
id: '主键ID',
artist_name: '艺术家名称',
normalized_name: '标准化后的艺术家名称',
artwork_count: '作品数量',
created_at: '创建时间',
updated_at: '更新时间'
}
},
artworks: {
tableName: 'registry_artworks',
description: '存储作品信息',
fields: {
id: '主键ID',
artist_id: '艺术家ID(外键)',
artwork_id: '作品ID',
artist_name: '艺术家名称(冗余字段)',
file_path: '文件路径',
download_date: '下载时间',
created_at: '创建时间',
updated_at: '更新时间'
}
},
meta: {
tableName: 'registry_meta',
description: '存储注册表元数据',
fields: {
id: '主键ID',
meta_key: '元数据键',
meta_value: '元数据值',
description: '描述',
created_at: '创建时间',
updated_at: '更新时间'
}
}
};
}
/**
* 检查所有表是否存在
*/
async checkTablesExist() {
const tables = ['registry_artists', 'registry_artworks', 'registry_meta'];
const results = {};
for (const table of tables) {
results[table] = await this.db.tableExists(table);
}
return results;
}
/**
* 删除所有注册表相关的表(谨慎使用)
*/
async dropAllTables() {
const tables = ['registry_artworks', 'registry_artists', 'registry_meta'];
try {
// 按照外键依赖顺序删除表
for (const table of tables) {
if (await this.db.tableExists(table)) {
await this.db.query(`DROP TABLE ${table}`);
logger.info(`${table} 已删除`);
}
}
logger.info('所有注册表相关的表已删除');
return { success: true };
} catch (error) {
logger.error('删除注册表表失败:', error);
throw error;
}
}
}
module.exports = RegistrySchema;