118 lines
6.2 KiB
SQL
118 lines
6.2 KiB
SQL
-- =========================================================================
|
||||
|
|
-- 存量升级: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 等旧列未被本脚本改写,
|
|||
|
|
-- 回退后旧代码可继续按单特征模型工作。
|
|||
|
|
-- =========================================================================
|