Timelinize数据库模式详解:核心表结构与关系设计
概述
Timelinize是一款用于整合多源数据的开源工具,其数据库设计遵循关系型数据模型,通过精心设计的表结构实现数据的一致性存储和高效查询。本文将详细解析timeline/schema.sql中定义的核心表结构及其关系,帮助开发者理解数据流转逻辑。
核心表结构设计
1. 数据来源管理
data_sources表
用于标准化管理数据来源(如社交媒体、云存储服务),确保数据引用一致性:
CREATE TABLE IF NOT EXISTS "data_sources" (
"id" INTEGER PRIMARY KEY,
"name" TEXT NOT NULL UNIQUE -- 程序内部标识,如"google_photos"
) STRICT;
- 关键作用:为所有数据项提供统一的数据源标识,避免直接使用字符串名称导致的冗余和不一致
- 关联场景:与items表的data_source_id字段关联,标识每条数据的原始来源
2. 数据实体模型
entities表
存储人物、地点等实体信息,支持多数据源实体识别与合并:
CREATE TABLE IF NOT EXISTS "entities" (
"id" INTEGER PRIMARY KEY,
"type_id" INTEGER NOT NULL,
"name" TEXT COLLATE NOCASE,
"picture_file" TEXT,
"hidden" INTEGER, -- 隐藏标志
"deleted" INTEGER -- 删除时间戳
FOREIGN KEY ("type_id") REFERENCES "entity_types"("id")
) STRICT;
- 实体类型:通过entity_types表定义(人员、组织、地点等)
- 数据治理:支持实体隐藏/删除,解决数据隐私需求
attributes表
存储实体属性(如联系方式、ID标识),实现灵活的实体描述:
CREATE TABLE IF NOT EXISTS "attributes" (
"id" INTEGER PRIMARY KEY,
"name" TEXT NOT NULL,
"value" ANY NOT NULL COLLATE NOCASE,
"alt_value" TEXT, -- 显示用替代值
UNIQUE ("name", "value")
) STRICT;
- 多值支持:通过entity_attributes关联表实现实体-属性的多对多关系
- 空间属性:内置经纬度字段,支持地理位置属性存储
3. 核心数据项存储
items表
存储所有导入的数据项(消息、照片、位置记录等),是系统的核心表:
CREATE TABLE IF NOT EXISTS "items" (
"id" INTEGER PRIMARY KEY,
"data_source_id" INTEGER,
"job_id" INTEGER, -- 导入任务ID
"original_id" TEXT, -- 数据源原始ID
"timestamp" INTEGER, -- 创建时间戳(毫秒)
"classification_id" INTEGER, -- 数据类型
"data_text" TEXT, -- 文本内容
"data_file" TEXT, -- 文件路径
"longitude" REAL,
"latitude" REAL,
UNIQUE ("data_source_id", "original_id")
) STRICT;
- 数据分类:通过classification_id关联classifications表,区分消息、照片等类型
- 时空特性:内置时间戳和经纬度字段,支持时间线和地图视图展示
- 去重机制:通过数据源+原始ID唯一约束防止重复导入
4. 关系与关联
relationships表
记录实体与数据项之间的复杂关系:
CREATE TABLE IF NOT EXISTS "relationships" (
"id" INTEGER PRIMARY KEY,
"relation_id" INTEGER NOT NULL, -- 关系类型
"from_item_id" INTEGER,
"to_item_id" INTEGER,
"from_attribute_id" INTEGER,
"to_attribute_id" INTEGER,
"start" INTEGER, -- 关系开始时间
"end" INTEGER -- 关系结束时间
) STRICT;
- 关系类型:通过relations表定义(如"回复"、"包含"、"拍摄于"等)
- 灵活关联:支持item-item、attribute-attribute等多维度关联
表关系架构
核心关系图
关键关联说明
-
数据导入链路:
jobs→items
每个数据项关联到创建它的导入任务,支持任务追踪和数据溯源 -
实体-属性关联:
entities←entity_attributes→attributes
多对多关系设计,允许一个实体拥有多个属性,一个属性关联多个实体 -
内容关联网络:
items←relationships→items
通过有向关系构建内容网络,支持回复链、引用关系等复杂结构
高级特性设计
1. 机器学习集成
embeddings虚拟表
基于sqlite-vec模块实现向量存储,支持语义搜索:
CREATE VIRTUAL TABLE IF NOT EXISTS embeddings USING vec0(
id INTEGER PRIMARY KEY,
embedding float[768] -- 768维向量
);
- 自动清理:通过触发器实现与items表的联动删除
CREATE TRIGGER IF NOT EXISTS clean_up_embeddings
AFTER DELETE ON items BEGIN
DELETE FROM embeddings WHERE id = old.embedding_id;
END;
2. 任务管理系统
jobs表
完整的任务生命周期管理:
CREATE TABLE IF NOT EXISTS "jobs" (
"id" INTEGER PRIMARY KEY,
"name" TEXT NOT NULL, -- 任务名称
"state" TEXT NOT NULL DEFAULT 'queued', -- 任务状态
"created" INTEGER NOT NULL DEFAULT (unixepoch()),
"start" INTEGER, -- 开始时间
"ended" INTEGER, -- 结束时间
"total" INTEGER, -- 总任务量
"progress" INTEGER -- 当前进度
) STRICT;
- 状态机:支持queued/started/paused/succeeded等状态流转
- 进度追踪:通过total/progress字段实现任务进度可视化
3. 数据治理机制
数据生命周期管理
通过hidden/deleted字段实现软删除,保留数据恢复能力:
- items表:支持基于时间戳的自动清理
- entities表:支持实体隐藏与恢复
- 触发器保障:自动清理无关联属性
优化设计
索引策略
关键查询路径优化:
CREATE INDEX IF NOT EXISTS "idx_items_timestamp" ON "items"("timestamp");
CREATE INDEX IF NOT EXISTS "idx_relationships_from_item_id" ON "relationships"("from_item_id");
视图设计
extended_items视图
预计算常用统计维度:
CREATE VIEW IF NOT EXISTS "extended_items" AS
SELECT
items.*,
data_sources.name AS data_source_name,
classifications.name AS classification_name,
cast(strftime('%j', date(round(timestamp/1000), 'unixepoch')) AS INTEGER) AS day_of_year
FROM items
LEFT JOIN data_sources ON data_sources.id = items.data_source_id
LEFT JOIN classifications ON classifications.id = items.classification_id;
总结
Timelinize数据库模式通过模块化设计实现了多源数据的统一管理,其核心特点包括:
- 灵活性:属性-实体分离设计支持任意实体扩展
- 关联性:关系表结构构建复杂内容网络
- 扩展性:机器学习向量存储支持智能应用
- 可靠性:完整的任务和数据生命周期管理
开发者可通过timeline/schema.sql获取完整定义,结合timeline/db.go中的数据访问层代码深入理解实现细节。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



