-- ============================================================ -- 安全设备 Demo - 数据库初始化脚本 -- 库名: secure_device (与 application.properties 中配置一致) -- 说明: 存储照片元数据、设备、用户、用户照片索引 -- 密文本身落盘于 uploads/ 目录 -- 服务端永远不存明文照片和明文 DEK -- ============================================================ -- 1. 创建数据库(如已存在可跳过) CREATE DATABASE IF NOT EXISTS `secure_device` DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci; USE `secure_device`; -- 2. 加密照片表(对应 EncryptedPhoto 实体) CREATE TABLE IF NOT EXISTS `encrypted_photo` ( `photo_id` VARCHAR(64) NOT NULL COMMENT '照片唯一 ID (PK)', `device_id` VARCHAR(64) DEFAULT NULL COMMENT '来源设备 ID', `user_id` VARCHAR(64) DEFAULT NULL COMMENT '所属用户 ID', `file_path` VARCHAR(512) DEFAULT NULL COMMENT '密文文件落盘路径', `iv_base64` VARCHAR(256) DEFAULT NULL COMMENT 'GCM IV (Base64)', `encrypted_dek_base64` VARCHAR(1024) DEFAULT NULL COMMENT 'DEK 被 UK 加密后的密文 (Base64)', `metadata_signature` VARCHAR(1024) DEFAULT NULL COMMENT '设备私钥签名 (Base64)', `upload_time` BIGINT DEFAULT NULL COMMENT '上传时间戳 (ms)', PRIMARY KEY (`photo_id`), KEY `idx_user_id` (`user_id`), KEY `idx_device_id` (`device_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='加密照片元数据表'; -- 3. 设备表(对应 Device 实体) CREATE TABLE IF NOT EXISTS `device` ( `device_id` VARCHAR(64) NOT NULL COMMENT '设备唯一 ID (UUID, PK)', `sn` VARCHAR(64) NOT NULL COMMENT '设备序列号 (唯一)', `user_id` VARCHAR(64) DEFAULT NULL COMMENT '绑定的用户 ID', `public_key_base64` TEXT DEFAULT NULL COMMENT '设备 TEE 公钥 (Base64)', `bind_time` BIGINT DEFAULT NULL COMMENT '绑定时间戳 (ms)', `last_recovery_time` BIGINT DEFAULT NULL COMMENT '最近一次恢复时间戳 (ms)', `active` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否激活 (1 激活 / 0 停用)', PRIMARY KEY (`device_id`), KEY `idx_device_sn` (`sn`), KEY `idx_device_user` (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='设备注册与绑定状态表(一个 SN 可有多条历史记录,仅一条 active)'; -- 4. 用户表(对应 User 实体) CREATE TABLE IF NOT EXISTS `app_user` ( `user_id` VARCHAR(64) NOT NULL COMMENT '用户 ID (PK)', `phone` VARCHAR(32) DEFAULT NULL COMMENT '手机号(用于短信验证)', `uk_encrypted_base64` TEXT DEFAULT NULL COMMENT '用户主密钥 UK (Base64)', `password` VARCHAR(128) DEFAULT NULL COMMENT '登录密码 (Demo 明文,生产用 BCrypt)', `phone_verified` VARCHAR(8) DEFAULT NULL COMMENT '手机号是否已验证', PRIMARY KEY (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户与主密钥表'; -- 5. 用户-照片关联表(对应 UserPhoto 实体) CREATE TABLE IF NOT EXISTS `user_photo` ( `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '自增主键', `user_id` VARCHAR(64) NOT NULL COMMENT '用户 ID', `photo_id` VARCHAR(64) NOT NULL COMMENT '照片 ID', `created_time` BIGINT DEFAULT NULL COMMENT '创建时间戳 (ms)', PRIMARY KEY (`id`), KEY `idx_user_photo_user` (`user_id`), KEY `idx_user_photo_photo` (`photo_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户照片索引表'; -- ============================================================ -- 已有数据库迁移(仅当旧库的 device 表带 SN 唯一索引时手动执行) -- 说明:早期版本 device.sn 建为 UNIQUE 索引,导致「恢复出厂重新注册」时 -- 报 Duplicate entry。现将 SN 改为普通索引(一个 SN 可有多条历史设备记录, -- 仅一条 active)。spring.jpa.hibernate.ddl-auto=update 不会自动删除已存在 -- 的唯一索引,故需手动执行下面两句: -- ============================================================ -- ALTER TABLE `device` DROP INDEX `idx_device_sn`; -- ALTER TABLE `device` ADD INDEX `idx_device_sn` (`sn`);