From b2c215996705ca9e8f23adf7e034069012541439 Mon Sep 17 00:00:00 2001 From: 16337 <1633794139@qq.com> Date: Fri, 13 Feb 2026 13:30:58 +0800 Subject: [PATCH] =?UTF-8?q?docs(aiot):=20=E6=B7=BB=E5=8A=A0=E4=B8=BA?= =?UTF-8?q?=E7=8E=B0=E6=9C=89=E6=91=84=E5=83=8F=E5=A4=B4=E7=94=9F=E6=88=90?= =?UTF-8?q?camera=5Fcode=E7=9A=84=E6=89=A7=E8=A1=8C=E6=8C=87=E5=8D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 详细的SQL执行步骤和验证方法 - 常见问题解答和回滚方案 - 确保旧摄像头数据兼容性 --- .../aiot/执行指南-为现有摄像头生成camera_code.md | 266 ++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 数据库/aiot/执行指南-为现有摄像头生成camera_code.md diff --git a/数据库/aiot/执行指南-为现有摄像头生成camera_code.md b/数据库/aiot/执行指南-为现有摄像头生成camera_code.md new file mode 100644 index 000000000..c3d14ab3f --- /dev/null +++ b/数据库/aiot/执行指南-为现有摄像头生成camera_code.md @@ -0,0 +1,266 @@ +# 为现有摄像头生成 camera_code - 执行指南 + +**目的**: 为数据库中已存在的摄像头生成唯一的 camera_code 标识符 + +**执行时间**: 2026-02-13 + +**重要性**: ⚠️ 必须执行!否则旧摄像头的 camera_code 为空,前端将无法正常使用 + +--- + +## 🚀 快速执行(推荐) + +### 方法一:MySQL 命令行执行 + +```bash +# 1. 进入 MySQL +mysql -u root -p wvp_aiot + +# 2. 执行迁移脚本 +source C:/workspace/wvp-platform/数据库/aiot/迁移-添加camera_code字段.sql + +# 3. 查看执行结果 +# 脚本会自动显示验证结果和样本数据 +``` + +### 方法二:直接复制SQL执行 + +如果 `source` 命令不可用,请复制以下SQL直接在MySQL客户端执行: + +```sql +-- 1. 新增 camera_code 列(如果不存在) +ALTER TABLE wvp_stream_proxy + ADD COLUMN IF NOT EXISTS camera_code VARCHAR(64) NULL COMMENT '摄像头全局唯一编码(格式:cam_xxxxxxxxxxxx)'; + +-- 2. 为现有数据生成 camera_code(基于 ID 生成12位哈希) +UPDATE wvp_stream_proxy + SET camera_code = CONCAT('cam_', SUBSTRING(MD5(CAST(id AS CHAR)), 1, 12)) + WHERE camera_code IS NULL OR camera_code = ''; + +-- 3. 将 camera_code 设为 NOT NULL 并添加唯一索引(如果不存在) +ALTER TABLE wvp_stream_proxy + MODIFY COLUMN camera_code VARCHAR(64) NOT NULL; + +-- 添加唯一索引(如果不存在,忽略错误) +ALTER TABLE wvp_stream_proxy + ADD UNIQUE KEY uk_camera_code (camera_code); + +-- 4. 验证数据完整性 - 检查重复 +SELECT '检查重复的 camera_code' AS check_name, COUNT(*) AS issue_count +FROM ( + SELECT camera_code, COUNT(*) AS cnt + FROM wvp_stream_proxy + GROUP BY camera_code + HAVING cnt > 1 +) AS duplicates; + +-- 5. 验证格式 +SELECT '检查格式错误的 camera_code' AS check_name, COUNT(*) AS issue_count +FROM wvp_stream_proxy +WHERE camera_code NOT REGEXP '^cam_[a-f0-9]{12}$'; + +-- 6. 更新 ROI 表中的 camera_id(从 app/stream 格式改为 camera_code) +UPDATE wvp_ai_roi r + INNER JOIN wvp_stream_proxy sp ON r.camera_id = CONCAT(sp.app, '/', sp.stream) + SET r.camera_id = sp.camera_code; + +-- 7. 验证 ROI 更新结果 +SELECT '检查未匹配的 ROI' AS check_name, COUNT(*) AS issue_count +FROM wvp_ai_roi r +LEFT JOIN wvp_stream_proxy sp ON r.camera_id = sp.camera_code +WHERE sp.camera_code IS NULL; + +-- 8. 显示迁移后的样本数据 +SELECT id, camera_code, app, stream, name +FROM wvp_stream_proxy +LIMIT 5; + +SELECT roi_id, camera_id, name +FROM wvp_ai_roi +LIMIT 5; +``` + +--- + +## ✅ 验证执行结果 + +执行完成后,应该看到以下输出: + +### 1. 重复检查 +``` +check_name | issue_count +------------------------------------------- +检查重复的 camera_code | 0 +``` +✅ `issue_count = 0` 表示无重复 + +### 2. 格式检查 +``` +check_name | issue_count +------------------------------------------------ +检查格式错误的 camera_code | 0 +``` +✅ `issue_count = 0` 表示格式正确 + +### 3. ROI 匹配检查 +``` +check_name | issue_count +--------------------------------------- +检查未匹配的 ROI | 0 +``` +✅ `issue_count = 0` 表示 ROI 关联正确 + +### 4. 样本数据示例 +```sql +-- wvp_stream_proxy 样本 ++----+------------------+------+----------+--------+ +| id | camera_code | app | stream | name | ++----+------------------+------+----------+--------+ +| 1 | cam_c4ca4238a0b9 | live | camera01 | 大堂 | +| 2 | cam_c81e728d9d4c | live | camera02 | 停车场 | ++----+------------------+------+----------+--------+ + +-- wvp_ai_roi 样本 ++--------+------------------+----------+ +| roi_id | camera_id | name | ++--------+------------------+----------+ +| 1 | cam_c4ca4238a0b9 | ROI区域1 | +| 2 | cam_c81e728d9d4c | ROI区域2 | ++--------+------------------+----------+ +``` + +✅ camera_code 格式为 `cam_xxxxxxxxxxxx`(12位十六进制) + +--- + +## 🔍 手动验证(可选) + +如果需要手动检查,执行以下SQL: + +```sql +-- 1. 检查所有摄像头是否都有 camera_code +SELECT COUNT(*) AS total_cameras, + COUNT(camera_code) AS with_code, + COUNT(*) - COUNT(camera_code) AS missing_code +FROM wvp_stream_proxy; +``` + +**期望结果**: `missing_code = 0` + +```sql +-- 2. 检查 camera_code 唯一性 +SELECT COUNT(DISTINCT camera_code) AS unique_codes, + COUNT(*) AS total_rows +FROM wvp_stream_proxy; +``` + +**期望结果**: `unique_codes = total_rows` + +```sql +-- 3. 检查 ROI 表是否正确关联 +SELECT COUNT(*) AS total_rois, + COUNT(sp.camera_code) AS matched_rois, + COUNT(*) - COUNT(sp.camera_code) AS unmatched_rois +FROM wvp_ai_roi r +LEFT JOIN wvp_stream_proxy sp ON r.camera_id = sp.camera_code; +``` + +**期望结果**: `unmatched_rois = 0` + +--- + +## ⚠️ 常见问题 + +### Q1: 执行时报错 "Duplicate key name 'uk_camera_code'" + +**原因**: 索引已存在(可能之前执行过) + +**解决**: 忽略此错误,继续执行后续步骤 + +### Q2: ROI 更新显示 0 rows affected + +**原因**: +- 情况1: 没有 ROI 数据(正常) +- 情况2: camera_id 格式已经是 camera_code(已迁移过) + +**验证**: 执行验证SQL检查 `unmatched_rois` 是否为 0 + +### Q3: 某些摄像头的 camera_code 仍然为空 + +**原因**: UPDATE 语句条件过滤了这些记录 + +**解决**: 手动为这些记录生成 camera_code +```sql +UPDATE wvp_stream_proxy +SET camera_code = CONCAT('cam_', SUBSTRING(MD5(CONCAT('manual_', id, '_', NOW())), 1, 12)) +WHERE camera_code IS NULL OR camera_code = ''; +``` + +--- + +## 📊 迁移前后对比 + +### 迁移前 +``` +wvp_stream_proxy: + - app: "live" + - stream: "camera01" + - camera_code: NULL ❌ + +wvp_ai_roi: + - camera_id: "live/camera01" ❌ (拼接格式,不稳定) +``` + +### 迁移后 +``` +wvp_stream_proxy: + - app: "live" + - stream: "camera01" + - camera_code: "cam_c4ca4238a0b9" ✅ + +wvp_ai_roi: + - camera_id: "cam_c4ca4238a0b9" ✅ (唯一标识符,稳定) +``` + +--- + +## 🔄 回滚(如果需要) + +如果迁移出现问题,可以执行回滚: + +```sql +-- 1. 恢复 ROI 表的 camera_id(需要在迁移前备份原始值) +-- 注意:此步骤需要提前备份! +UPDATE wvp_ai_roi r +INNER JOIN wvp_stream_proxy sp ON r.camera_id = sp.camera_code +SET r.camera_id = CONCAT(sp.app, '/', sp.stream); + +-- 2. 删除 camera_code 列 +ALTER TABLE wvp_stream_proxy DROP COLUMN camera_code; +``` + +⚠️ **重要**: 建议在执行迁移前先备份数据库! + +```bash +# 备份数据库 +mysqldump -u root -p wvp_aiot > wvp_aiot_backup_20260213.sql +``` + +--- + +## ✅ 执行完成标志 + +当您看到以下结果时,表示迁移成功: + +- [x] 所有验证查询的 `issue_count` 都为 0 +- [x] 样本数据中的 camera_code 格式为 `cam_xxxxxxxxxxxx` +- [x] wvp_ai_roi 表的 camera_id 已更新为 camera_code +- [x] 前端摄像头管理页面能正常显示"应用名"列 +- [x] 新增摄像头时自动生成 camera_code + +--- + +**执行人**: _______________ +**执行时间**: _______________ +**验证结果**: ☐ 通过 ☐ 失败 +**备注**: _______________