Files
sentinel-home-ai/scripts/ddl.sql

214 lines
11 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- ============================================================
-- Sentinel Home AI - 数据库 DDL
-- 版本: v1.0
-- 日期: 2026-08-19
-- 数据库: MariaDB (MySQL 兼容)
-- ============================================================
-- 创建数据库(如不存在)
CREATE DATABASE IF NOT EXISTS sentinel_home_ai
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
USE sentinel_home_ai;
-- ============================================================
-- 1. 任务表 process_tasks
-- ============================================================
CREATE TABLE IF NOT EXISTS process_tasks (
task_id INT AUTO_INCREMENT PRIMARY KEY,
video_path VARCHAR(500) NOT NULL COMMENT '视频在 NAS 上的绝对路径',
video_url VARCHAR(500) NOT NULL COMMENT 'Video-Server 提供的下载 URL',
status ENUM('PENDING','PROCESSING','SUCCESS','FAILED') DEFAULT 'PENDING',
retry_count INT DEFAULT 0,
max_retries INT DEFAULT 3,
next_retry_at DATETIME NULL COMMENT '下次重试时间(退避策略)',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
error_message TEXT NULL,
failure_stage ENUM('download','extract','vlm_visual','vlm_fusion','callback','process') NULL COMMENT '失败阶段process=Edge 消费者处理异常)',
heartbeat_at DATETIME NULL COMMENT '心跳时间戳(首期预留,不写入)',
INDEX idx_status (status),
INDEX idx_created (created_at),
INDEX idx_next_retry (next_retry_at)
) ENGINE=InnoDB COMMENT='视频分析任务表';
-- ============================================================
-- 2. 事件表 monitor_events
-- ============================================================
CREATE TABLE IF NOT EXISTS monitor_events (
event_id INT AUTO_INCREMENT PRIMARY KEY,
task_id INT NOT NULL,
event_start_time DATETIME NOT NULL COMMENT '事件开始时间',
event_end_time DATETIME NOT NULL COMMENT '事件结束时间',
camera_name VARCHAR(50) COMMENT '摄像头名称/位置',
global_summary TEXT COMMENT 'VLM 生成的整体摘要',
entities_json JSON NOT NULL COMMENT '实体列表 JSON 数组',
compute_provider JSON NOT NULL COMMENT '模型来源数组,如 ["ollama","gemini"]',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_event_start (event_start_time),
INDEX idx_compute_provider (compute_provider),
FOREIGN KEY (task_id) REFERENCES process_tasks(task_id) ON DELETE CASCADE
) ENGINE=InnoDB COMMENT='监控事件聚合表';
-- ============================================================
-- 3. 每日摘要表 daily_summaries预留
-- ============================================================
CREATE TABLE IF NOT EXISTS daily_summaries (
id INT AUTO_INCREMENT PRIMARY KEY,
target_date DATE NOT NULL UNIQUE COMMENT '目标日期',
summary_text TEXT COMMENT '当日摘要文本',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB COMMENT='每日摘要表(首期预留)';
-- ============================================================
-- 4. 事件明细表 event_details
-- 每关键帧一条,由 VLM 输出 frame_details 拆分落库
-- ============================================================
CREATE TABLE IF NOT EXISTS event_details (
detail_id INT AUTO_INCREMENT PRIMARY KEY,
event_id INT NOT NULL COMMENT '关联 monitor_events.event_id',
task_id INT NOT NULL COMMENT '冗余,便于查询',
frame_index INT NOT NULL COMMENT '关键帧序号1-8',
frame_timestamp DATETIME NOT NULL COMMENT '该帧对应的绝对时间点',
camera_name VARCHAR(50) COMMENT '摄像头位置(如"客厅"',
person VARCHAR(50) NOT NULL COMMENT '成员名或"人物A/B/C"或"未知访客"',
action VARCHAR(200) NOT NULL COMMENT '动作描述AI 自由生成,无枚举)',
clothing VARCHAR(100) COMMENT '衣着描述',
is_attention_event BOOLEAN DEFAULT FALSE COMMENT 'AI 自行判断是否为关注事件',
source_providers JSON NOT NULL COMMENT '识别到该明细的模型来源数组',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_event_id (event_id),
INDEX idx_frame_timestamp (frame_timestamp),
INDEX idx_person (person),
INDEX idx_queried_date (frame_timestamp),
FOREIGN KEY (event_id) REFERENCES monitor_events(event_id) ON DELETE CASCADE
) ENGINE=InnoDB COMMENT='事件明细表(每关键帧一条)';
-- ============================================================
-- 5. 对话记录表 chat_history
-- ============================================================
CREATE TABLE IF NOT EXISTS chat_history (
chat_id INT AUTO_INCREMENT PRIMARY KEY,
user_question TEXT NOT NULL COMMENT '用户问题',
ai_answer TEXT NOT NULL COMMENT 'AI 回答',
context_summary TEXT COMMENT '问答时使用的上下文摘要',
queried_date DATE COMMENT '查询的日期范围',
queried_person VARCHAR(50) COMMENT '查询的人物',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_created (created_at),
INDEX idx_queried_date (queried_date),
INDEX idx_queried_person (queried_person)
) ENGINE=InnoDB COMMENT='用户与 AI 问答记录表';
-- ============================================================
-- 6. 家庭成员表 family_members
-- 交互式命名VLM 自动按特征提取"人物A/B/C",用户命名为真实名字
-- ============================================================
CREATE TABLE IF NOT EXISTS family_members (
member_id INT AUTO_INCREMENT PRIMARY KEY,
abstract_label VARCHAR(20) NOT NULL UNIQUE COMMENT 'VLM 首次提取的抽象标识,如"人物A"',
real_name VARCHAR(50) COMMENT '用户命名的真实名字,如"汤圆"NULL 表示未命名',
feature_description TEXT COMMENT 'VLM 提取的特征描述',
first_seen_at DATETIME COMMENT '首次被提取的时间',
named_at DATETIME NULL COMMENT '用户命名的时间',
named_by VARCHAR(50) COMMENT '命名人',
is_active BOOLEAN DEFAULT TRUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_real_name (real_name),
INDEX idx_abstract_label (abstract_label),
INDEX idx_is_active (is_active)
) ENGINE=InnoDB COMMENT='家庭成员表(交互式命名)';
-- ============================================================
-- 7. 甲骨文同步镜像表(新架构 v22026-08-21
-- NAS 每 30 分钟从甲骨文 FAM-Edge 拉增量,镜像到本地,仅作展示
-- 字段对齐 Oracle 端 SQLite 库oracle_db.py
-- ============================================================
-- 7.1 视频会话表Oracle videos 镜像)
CREATE TABLE IF NOT EXISTS sync_videos (
id INT PRIMARY KEY COMMENT 'Oracle videos.id',
drive_file_id VARCHAR(255) COMMENT 'Google 硬盘文件 ID',
filename VARCHAR(500) NOT NULL UNIQUE COMMENT '视频文件名(唯一)',
camera_name VARCHAR(50) COMMENT '摄像头名称/位置',
duration_sec DOUBLE DEFAULT 0 COMMENT '视频时长(秒)',
event_start_time VARCHAR(32) COMMENT '视频开始时间(文本)',
status VARCHAR(20) DEFAULT 'pending' COMMENT 'pending/done/failed',
summary_json LONGTEXT COMMENT '全局摘要文本',
events_json LONGTEXT COMMENT '事件列表 JSON 数组(冗余,便于查询)',
people_json LONGTEXT COMMENT '人物列表 JSON 数组',
compute_provider VARCHAR(255) COMMENT '模型来源,如 gemini / nvidia',
created_at VARCHAR(32),
updated_at VARCHAR(32),
processed_at VARCHAR(32),
synced_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '最近一次同步写入时间',
INDEX idx_processed (processed_at),
INDEX idx_status (status)
) ENGINE=InnoDB COMMENT='甲骨文视频会话镜像表';
-- 7.2 事件明细表Oracle events 镜像)
CREATE TABLE IF NOT EXISTS sync_events (
id INT PRIMARY KEY COMMENT 'Oracle events.id',
video_id INT NOT NULL COMMENT '关联 sync_videos.id',
ts VARCHAR(32) COMMENT '事件时间点(文本)',
description TEXT COMMENT '事件描述',
person_list_json LONGTEXT COMMENT '涉及人物 JSON 数组(字符串或标签)',
person_appearances_json LONGTEXT COMMENT '该时刻人物结构化特征 JSON[{uid,features,action}]',
is_attention_event TINYINT(1) DEFAULT 0 COMMENT 'AI 判断是否为关注事件',
updated_at VARCHAR(32),
synced_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_video (video_id),
INDEX idx_ts (ts)
) ENGINE=InnoDB COMMENT='甲骨文事件镜像表';
-- 7.3 人物规范表Oracle people 镜像)
CREATE TABLE IF NOT EXISTS sync_people (
id INT PRIMARY KEY COMMENT 'Oracle people.id',
label VARCHAR(100) NOT NULL UNIQUE COMMENT '抽象标识,如"人物A"',
canonical_name VARCHAR(100) COMMENT '规范名(用户命名或 LLM 合并NULL 表示未命名',
first_seen VARCHAR(32) COMMENT '首次出现时间',
appearances INT DEFAULT 0 COMMENT '出现次数',
source VARCHAR(20) DEFAULT 'llm' COMMENT 'llm / manualmanual 优先不被覆盖)',
features_json LONGTEXT COMMENT '人物结构化特征 JSON性别/年龄/身形/发型/衣着/面部/辨识)',
display_uid VARCHAR(100) COMMENT '大模型给的人物 UID与 label 一致时冗余)',
updated_at VARCHAR(32),
synced_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_label (label),
INDEX idx_canonical (canonical_name)
) ENGINE=InnoDB COMMENT='甲骨文人物规范镜像表';
-- 7.4 同步游标表
CREATE TABLE IF NOT EXISTS sync_cursor (
`key` VARCHAR(50) PRIMARY KEY,
`value` VARCHAR(64) COMMENT '上次成功拉取到的 server_timeISO 文本)'
) ENGINE=InnoDB COMMENT='同步游标表';
-- 8.1 云端模型调用统计镜像表Oracle model_calls 镜像)
CREATE TABLE IF NOT EXISTS sync_model_calls (
id INT PRIMARY KEY COMMENT 'Oracle model_calls.id',
provider VARCHAR(50) COMMENT 'gemini / nvidia',
model VARCHAR(100) COMMENT '具体模型名(如 gemini-flash-latest',
video_id INT COMMENT '关联视频 id',
filename VARCHAR(500) COMMENT '视频文件名',
started_at VARCHAR(32) COMMENT '请求开始时间',
duration_sec DOUBLE COMMENT '请求耗时(秒)',
success TINYINT(1) DEFAULT 0 COMMENT '1=成功 0=失败',
error VARCHAR(500) COMMENT '失败原因429_quota/timeout/http_xxx 等)',
created_at VARCHAR(32) COMMENT '记录入库时间',
synced_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_provider (provider),
INDEX idx_created (created_at),
INDEX idx_success (success)
) ENGINE=InnoDB COMMENT='云端模型调用统计镜像表';
-- ============================================================
-- 验证
-- ============================================================
SELECT 'DDL 执行完成' AS message;
SELECT TABLE_NAME, TABLE_COMMENT
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'sentinel_home_ai'
ORDER BY TABLE_NAME;