Files
doorcontrol/base/RuoYi-Vue-master/sql/upgrade_d9_face_feature.sql
T

118 lines
6.2 KiB
SQL
Raw Normal View History

2026-11-01 19:44:40 +08:00
-- =========================================================================
-- 存量升级:D9 人脸特征多算法版本(v1.2 → v1.3)
--
-- 背景:v1.2 的 lock_face 只有一组 feature_data/feature_algo_version,
-- 同一人员按算法 v1 提取后再按 v2 提取会覆盖旧值,算法版本为 v1 的门锁
-- 随即失去可用特征。D9 新增 lock_face_feature:
-- 一个 (face_id, algo_version) 一行,一人多版本共存;
-- 下发时按目标门锁 lock_device.face_algo_version 选对应版本;
-- lock_face 保留图片与「最近一次成功提取」的镜像,旧接口不受影响。
--
-- 执行前置:
-- 1) 停止应用(至少停止授权下发与人脸提取);
-- 2) 备份 lock_face;
-- 3) 先执行本脚本,再发布包含 D9 代码的版本。旧代码不认识新表,可继续
-- 运行(仍读写 lock_face 旧列),但新代码在匹配不到特征时会阻断下发。
--
-- 可重复执行:建表用 if not exists,回填只补缺失行,不覆盖运行期新数据。
-- =========================================================================
set names utf8mb4;
-- =========================================================================
-- 1、人脸特征-算法版本表
-- =========================================================================
create table if not exists lock_face_feature (
feature_id bigint(20) not null auto_increment comment '特征ID',
face_id bigint(20) not null comment '人脸ID(lock_face.face_id)',
person_id bigint(20) not null comment '人员ID(lock_person.person_id)',
person_no varchar(32) not null comment '人员编号(冗余协议键,与 lock_face.person_no 一致)',
algo_version varchar(32) not null comment '算法版本(提取时使用的 algorithm_version,来自 lock_device.face_algo_version)',
feature_data mediumtext comment '人脸特征值(base64编码)',
feature_md5 varchar(32) default null comment '特征指纹(变更检测与幂等下发用)',
feature_size int(11) default 0 comment '特征字节数',
extract_status char(1) default '0' comment '特征提取状态(0未提取 1成功 2失败)',
extract_time datetime comment '特征提取时间',
extract_msg varchar(512) default null comment '特征提取失败原因',
create_by varchar(64) default '' comment '创建者',
create_time datetime comment '创建时间',
update_by varchar(64) default '' comment '更新者',
update_time datetime comment '更新时间',
remark varchar(500) default null comment '备注',
primary key (feature_id),
unique key uk_lock_face_feature_algo (face_id, algo_version),
key idx_lock_face_feature_person (person_no, algo_version),
key idx_lock_face_feature_person_id (person_id)
) engine=innodb comment = '人脸特征-算法版本表';
-- =========================================================================
-- 2、回填:lock_face 最近一次成功提取的特征转成对应版本的一行
-- - 只回填有特征值且有算法版本的记录;无版本的旧数据无法归位,
-- 由人脸管理页按门锁版本重新提取(下发前会阻断并提示)。
-- - 只插入缺失行,重复执行不会覆盖运行期已提取的更优数据。
-- =========================================================================
insert into lock_face_feature (
face_id, person_id, person_no, algo_version, feature_data, feature_md5,
feature_size, extract_status, extract_time, extract_msg,
create_by, create_time, update_by, update_time, remark
)
select f.face_id,
f.person_id,
f.person_no,
trim(f.feature_algo_version),
f.feature_data,
f.feature_md5,
coalesce(f.feature_size, 0),
coalesce(f.extract_status, '1'),
f.extract_time,
f.extract_msg,
'migrate',
now(),
'migrate',
now(),
'D9 存量回填'
from lock_face f
where f.del_flag = '0'
and f.feature_data is not null
and trim(coalesce(f.feature_algo_version, '')) <> ''
and not exists (
select 1 from lock_face_feature x
where x.face_id = f.face_id
and x.algo_version = trim(f.feature_algo_version)
);
-- =========================================================================
-- 3、执行后核对(只读,按需执行)
-- =========================================================================
-- 3.1 回填条数:应与「有特征且有版本」的人脸数一致
-- select (select count(1) from lock_face_feature) as feature_cnt,
-- (select count(1) from lock_face
-- where del_flag = '0' and feature_data is not null
-- and trim(coalesce(feature_algo_version, '')) <> '') as migratable_cnt;
--
-- 3.2 仍未归位的旧特征(有特征值但无算法版本,需按门锁版本重新提取)
-- select face_id, person_no, extract_status, extract_time
-- from lock_face
-- where del_flag = '0' and feature_data is not null
-- and trim(coalesce(feature_algo_version, '')) = '';
--
-- 3.3 唯一约束自检:同一人脸同一版本不应多行
-- select face_id, algo_version, count(1) c
-- from lock_face_feature group by face_id, algo_version having c > 1;
--
-- 3.4 人员编号与主表是否一致(应返回空)
-- select ff.feature_id, ff.person_no, f.person_no as face_person_no
-- from lock_face_feature ff join lock_face f on f.face_id = ff.face_id
-- where ff.person_no <> f.person_no;
-- =========================================================================
-- 4、回滚
-- 先回退到不含 D9 的应用版本,再执行:
-- drop table if exists lock_face_feature;
-- lock_face 的 feature_data/feature_algo_version 等旧列未被本脚本改写,
-- 回退后旧代码可继续按单特征模型工作。
-- =========================================================================