feat: 完成数据库种子数据系统开发
- 创建完整的种子数据系统 (seed_data.sql) - 6个用户数据 (管理员 + 5个摄影师) - 9个分类数据 (风景、人像、建筑、街拍、艺术、宠物、食物、旅行、黑白) - 35张照片数据 (涵盖所有分类,均衡分布) - 自动化执行脚本 (run_seed_data.sh) - 数据质量测试脚本 (test_seed_data.sh) - Makefile 集成 (make seed, make test-seed, make db-status) - 完整的使用文档 (SEED_DATA_README.md) - 数据库备份机制,时间戳命名 - 9项自动化测试全部通过,数据质量保证 任务12完成,项目完成率达到40%
This commit is contained in:
288
backend/test_seed_data.sh
Executable file
288
backend/test_seed_data.sh
Executable file
@ -0,0 +1,288 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 种子数据验证脚本
|
||||
# 用于验证种子数据的完整性和正确性
|
||||
|
||||
set -e
|
||||
|
||||
# 配置
|
||||
DB_PATH="./data/photography.db"
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 日志函数
|
||||
log_info() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# 检查数据库是否存在
|
||||
check_database() {
|
||||
if [ ! -f "$DB_PATH" ]; then
|
||||
log_error "数据库文件不存在: $DB_PATH"
|
||||
exit 1
|
||||
fi
|
||||
log_info "数据库文件存在"
|
||||
}
|
||||
|
||||
# 测试基础数据统计
|
||||
test_basic_stats() {
|
||||
log_info "测试基础数据统计..."
|
||||
|
||||
local user_count=$(sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM user;")
|
||||
local category_count=$(sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM category;")
|
||||
local photo_count=$(sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM photo;")
|
||||
|
||||
echo "用户数量: $user_count (期望: 6)"
|
||||
echo "分类数量: $category_count (期望: 9)"
|
||||
echo "照片数量: $photo_count (期望: 30)"
|
||||
|
||||
# 验证数据量
|
||||
if [ "$user_count" -eq 6 ] && [ "$category_count" -eq 9 ] && [ "$photo_count" -ge 30 ]; then
|
||||
log_success "基础数据统计正确"
|
||||
else
|
||||
log_error "基础数据统计不正确"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 测试分类ID连续性
|
||||
test_category_ids() {
|
||||
log_info "测试分类ID连续性..."
|
||||
|
||||
local missing_ids=$(sqlite3 "$DB_PATH" "
|
||||
WITH RECURSIVE series(x) AS (
|
||||
SELECT 1
|
||||
UNION ALL
|
||||
SELECT x+1 FROM series WHERE x < 9
|
||||
)
|
||||
SELECT COUNT(*) FROM series
|
||||
WHERE x NOT IN (SELECT id FROM category);
|
||||
")
|
||||
|
||||
if [ "$missing_ids" -eq 0 ]; then
|
||||
log_success "分类ID连续性正确"
|
||||
else
|
||||
log_error "分类ID不连续,缺失 $missing_ids 个ID"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 测试用户数据完整性
|
||||
test_user_integrity() {
|
||||
log_info "测试用户数据完整性..."
|
||||
|
||||
# 检查管理员用户
|
||||
local admin_count=$(sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM user WHERE username='admin';")
|
||||
if [ "$admin_count" -eq 1 ]; then
|
||||
log_success "管理员用户存在"
|
||||
else
|
||||
log_error "管理员用户不存在或重复"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 检查用户名唯一性
|
||||
local duplicate_users=$(sqlite3 "$DB_PATH" "
|
||||
SELECT COUNT(*) FROM (
|
||||
SELECT username FROM user GROUP BY username HAVING COUNT(*) > 1
|
||||
);
|
||||
")
|
||||
|
||||
if [ "$duplicate_users" -eq 0 ]; then
|
||||
log_success "用户名唯一性正确"
|
||||
else
|
||||
log_error "存在重复用户名"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 测试照片数据完整性
|
||||
test_photo_integrity() {
|
||||
log_info "测试照片数据完整性..."
|
||||
|
||||
# 检查所有照片都有有效的用户ID
|
||||
local invalid_user_photos=$(sqlite3 "$DB_PATH" "
|
||||
SELECT COUNT(*) FROM photo
|
||||
WHERE user_id NOT IN (SELECT id FROM user);
|
||||
")
|
||||
|
||||
if [ "$invalid_user_photos" -eq 0 ]; then
|
||||
log_success "照片用户关联正确"
|
||||
else
|
||||
log_error "存在 $invalid_user_photos 张照片的用户ID无效"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 检查所有照片都有有效的分类ID
|
||||
local invalid_category_photos=$(sqlite3 "$DB_PATH" "
|
||||
SELECT COUNT(*) FROM photo
|
||||
WHERE category_id NOT IN (SELECT id FROM category);
|
||||
")
|
||||
|
||||
if [ "$invalid_category_photos" -eq 0 ]; then
|
||||
log_success "照片分类关联正确"
|
||||
else
|
||||
log_error "存在 $invalid_category_photos 张照片的分类ID无效"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 测试分类照片分布
|
||||
test_category_distribution() {
|
||||
log_info "测试分类照片分布..."
|
||||
|
||||
# 检查是否有分类没有照片
|
||||
local empty_categories=$(sqlite3 "$DB_PATH" "
|
||||
SELECT COUNT(*) FROM category
|
||||
WHERE id NOT IN (SELECT DISTINCT category_id FROM photo);
|
||||
")
|
||||
|
||||
if [ "$empty_categories" -eq 0 ]; then
|
||||
log_success "所有分类都有照片"
|
||||
else
|
||||
log_warning "有 $empty_categories 个分类没有照片"
|
||||
fi
|
||||
|
||||
# 显示各分类照片数量
|
||||
echo "各分类照片数量分布:"
|
||||
sqlite3 "$DB_PATH" "
|
||||
SELECT
|
||||
c.name || ': ' || COUNT(p.id) || '张' as distribution
|
||||
FROM category c
|
||||
LEFT JOIN photo p ON c.id = p.category_id
|
||||
GROUP BY c.id, c.name
|
||||
ORDER BY COUNT(p.id) DESC;
|
||||
"
|
||||
}
|
||||
|
||||
# 测试用户照片分布
|
||||
test_user_distribution() {
|
||||
log_info "测试用户照片分布..."
|
||||
|
||||
# 检查是否有用户没有照片
|
||||
local users_without_photos=$(sqlite3 "$DB_PATH" "
|
||||
SELECT COUNT(*) FROM user
|
||||
WHERE id NOT IN (SELECT DISTINCT user_id FROM photo);
|
||||
")
|
||||
|
||||
if [ "$users_without_photos" -eq 0 ]; then
|
||||
log_success "所有用户都有照片"
|
||||
else
|
||||
log_warning "有 $users_without_photos 个用户没有照片"
|
||||
fi
|
||||
|
||||
# 显示各用户照片数量
|
||||
echo "各用户照片数量分布:"
|
||||
sqlite3 "$DB_PATH" "
|
||||
SELECT
|
||||
u.username || ': ' || COUNT(p.id) || '张' as distribution
|
||||
FROM user u
|
||||
LEFT JOIN photo p ON u.id = p.user_id
|
||||
GROUP BY u.id, u.username
|
||||
ORDER BY COUNT(p.id) DESC;
|
||||
"
|
||||
}
|
||||
|
||||
# 测试数据时间合理性
|
||||
test_data_timestamps() {
|
||||
log_info "测试数据时间合理性..."
|
||||
|
||||
# 检查是否有未来时间的数据
|
||||
local future_photos=$(sqlite3 "$DB_PATH" "
|
||||
SELECT COUNT(*) FROM photo
|
||||
WHERE created_at > datetime('now');
|
||||
")
|
||||
|
||||
if [ "$future_photos" -eq 0 ]; then
|
||||
log_success "照片时间戳合理"
|
||||
else
|
||||
log_warning "有 $future_photos 张照片的时间戳在未来"
|
||||
fi
|
||||
}
|
||||
|
||||
# 性能测试
|
||||
test_performance() {
|
||||
log_info "测试基础查询性能..."
|
||||
|
||||
# 测试分类查询
|
||||
local start_time=$(date +%s)
|
||||
sqlite3 "$DB_PATH" "SELECT * FROM category;" > /dev/null
|
||||
local end_time=$(date +%s)
|
||||
local category_time=$((end_time - start_time))
|
||||
|
||||
# 测试照片查询
|
||||
start_time=$(date +%s)
|
||||
sqlite3 "$DB_PATH" "SELECT * FROM photo LIMIT 10;" > /dev/null
|
||||
end_time=$(date +%s)
|
||||
local photo_time=$((end_time - start_time))
|
||||
|
||||
echo "分类查询时间: ${category_time}s"
|
||||
echo "照片查询时间: ${photo_time}s"
|
||||
|
||||
if [ "$category_time" -lt 2 ] && [ "$photo_time" -lt 2 ]; then
|
||||
log_success "查询性能良好"
|
||||
else
|
||||
log_warning "查询性能可能需要优化"
|
||||
fi
|
||||
}
|
||||
|
||||
# 主函数
|
||||
main() {
|
||||
log_info "开始种子数据验证测试"
|
||||
echo "=================================================="
|
||||
|
||||
local test_count=0
|
||||
local passed_count=0
|
||||
|
||||
# 运行所有测试
|
||||
tests=(
|
||||
"check_database"
|
||||
"test_basic_stats"
|
||||
"test_category_ids"
|
||||
"test_user_integrity"
|
||||
"test_photo_integrity"
|
||||
"test_category_distribution"
|
||||
"test_user_distribution"
|
||||
"test_data_timestamps"
|
||||
"test_performance"
|
||||
)
|
||||
|
||||
for test in "${tests[@]}"; do
|
||||
test_count=$((test_count + 1))
|
||||
echo ""
|
||||
if $test; then
|
||||
passed_count=$((passed_count + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "=================================================="
|
||||
echo "测试完成: $passed_count/$test_count 通过"
|
||||
|
||||
if [ "$passed_count" -eq "$test_count" ]; then
|
||||
log_success "所有测试通过!种子数据质量良好"
|
||||
exit 0
|
||||
else
|
||||
log_warning "部分测试失败,请检查数据质量"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 脚本入口
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user