Initial commit: 宁夏智慧养殖监管平台
This commit is contained in:
128
backend/check-primary-keys.js
Normal file
128
backend/check-primary-keys.js
Normal file
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
* 检查数据库中所有表的主键ID分布情况
|
||||
* @file check-primary-keys.js
|
||||
* @description 分析各表的主键ID范围,为重新排序做准备
|
||||
*/
|
||||
|
||||
const { sequelize } = require('./config/database-simple');
|
||||
const { QueryTypes } = require('sequelize');
|
||||
|
||||
async function checkPrimaryKeys() {
|
||||
try {
|
||||
console.log('=== 检查数据库表主键ID分布情况 ===\n');
|
||||
|
||||
// 获取所有表名
|
||||
const tables = await sequelize.query(
|
||||
"SELECT TABLE_NAME as table_name FROM information_schema.tables WHERE table_schema = DATABASE() AND table_type = 'BASE TABLE'",
|
||||
{ type: QueryTypes.SELECT }
|
||||
);
|
||||
|
||||
console.log(`发现 ${tables.length} 个表:\n`);
|
||||
|
||||
const tableStats = [];
|
||||
|
||||
for (const table of tables) {
|
||||
const tableName = table.table_name;
|
||||
|
||||
try {
|
||||
// 检查表是否有id字段
|
||||
const columns = await sequelize.query(
|
||||
`SELECT COLUMN_NAME as column_name, DATA_TYPE as data_type, IS_NULLABLE as is_nullable, COLUMN_KEY as column_key
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE() AND TABLE_NAME = '${tableName}' AND COLUMN_NAME = 'id'`,
|
||||
{ type: QueryTypes.SELECT }
|
||||
);
|
||||
|
||||
if (columns.length === 0) {
|
||||
console.log(`❌ ${tableName}: 没有id字段`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 获取ID统计信息
|
||||
const stats = await sequelize.query(
|
||||
`SELECT
|
||||
COUNT(*) as total_count,
|
||||
MIN(id) as min_id,
|
||||
MAX(id) as max_id,
|
||||
COUNT(DISTINCT id) as unique_count
|
||||
FROM ${tableName}`,
|
||||
{ type: QueryTypes.SELECT }
|
||||
);
|
||||
|
||||
const stat = stats[0];
|
||||
|
||||
// 检查ID连续性
|
||||
const gapCheck = await sequelize.query(
|
||||
`SELECT COUNT(*) as gap_count
|
||||
FROM (
|
||||
SELECT id + 1 as next_id
|
||||
FROM ${tableName}
|
||||
WHERE id + 1 NOT IN (SELECT id FROM ${tableName})
|
||||
AND id < (SELECT MAX(id) FROM ${tableName})
|
||||
) as gaps`,
|
||||
{ type: QueryTypes.SELECT }
|
||||
);
|
||||
|
||||
const hasGaps = gapCheck[0].gap_count > 0;
|
||||
|
||||
const tableInfo = {
|
||||
tableName,
|
||||
totalCount: parseInt(stat.total_count),
|
||||
minId: stat.min_id,
|
||||
maxId: stat.max_id,
|
||||
uniqueCount: parseInt(stat.unique_count),
|
||||
hasGaps,
|
||||
needsReorder: stat.min_id !== 1 || hasGaps
|
||||
};
|
||||
|
||||
tableStats.push(tableInfo);
|
||||
|
||||
console.log(`✅ ${tableName}:`);
|
||||
console.log(` - 记录数: ${tableInfo.totalCount}`);
|
||||
console.log(` - ID范围: ${tableInfo.minId} - ${tableInfo.maxId}`);
|
||||
console.log(` - 唯一ID数: ${tableInfo.uniqueCount}`);
|
||||
console.log(` - 有间隙: ${hasGaps ? '是' : '否'}`);
|
||||
console.log(` - 需要重排: ${tableInfo.needsReorder ? '是' : '否'}`);
|
||||
console.log('');
|
||||
|
||||
} catch (error) {
|
||||
console.log(`❌ ${tableName}: 检查失败 - ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 汇总统计
|
||||
console.log('\n=== 汇总统计 ===');
|
||||
const needReorderTables = tableStats.filter(t => t.needsReorder);
|
||||
console.log(`需要重新排序的表: ${needReorderTables.length}/${tableStats.length}`);
|
||||
|
||||
if (needReorderTables.length > 0) {
|
||||
console.log('\n需要重新排序的表:');
|
||||
needReorderTables.forEach(table => {
|
||||
console.log(`- ${table.tableName} (${table.minId}-${table.maxId}, ${table.totalCount}条记录)`);
|
||||
});
|
||||
}
|
||||
|
||||
return tableStats;
|
||||
|
||||
} catch (error) {
|
||||
console.error('检查主键失败:', error);
|
||||
throw error;
|
||||
} finally {
|
||||
await sequelize.close();
|
||||
}
|
||||
}
|
||||
|
||||
// 如果直接运行此脚本
|
||||
if (require.main === module) {
|
||||
checkPrimaryKeys()
|
||||
.then(() => {
|
||||
console.log('\n检查完成!');
|
||||
process.exit(0);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('检查失败:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { checkPrimaryKeys };
|
||||
Reference in New Issue
Block a user