数据模型与 Markdown 布局
逻辑模型
数据库使用 Collection 与 Record 作为统一逻辑模型:
- Collection 定义 Schema、索引、权限边界与存储布局;
- Record 是查询、事务、权限、版本和冲突的最小逻辑对象;
- File 是一个或多个 Record 的物理容器;
- Workspace Path 只是物理位置,不是主键;
- Body 是 Record 的特殊 Markdown 字段。
应用不需要知道 Record 位于独立文件、Table 行还是 YAML Records 中。
稳定身份
每条 Record 必须拥有全数据库唯一 UUID。默认使用 UUIDv7,由初始化、运行时写入或 Merge Plan 生成;用户提供 UUID 时必须检查格式和全局唯一性。
UUID 创建后不随 Collection、文件路径、标题、Slug、布局或分区改变。Slug 可以作为可读业务字段和唯一索引,但不能替代内部 UUID。
普通 Document Record 固定拥有非空字符串系统字段 title。title 不需要在严格 Schema 中重复声明;如果 Schema 显式声明它,类型必须是 string,并且仍然保持 required。没有显式 Document Schema 时,程序化 Insert 可以使用 UUID 作为缺省标题;内容应用应当提供有意义的标题。
缺少 UUID 的已有 Markdown 可以进入交互式 Init 或 Merge Plan。数据库展示将要生成的 UUID,获得确认后再修改 Workspace 和 Runtime Database。
Schema
Schema 是数据库正式数据模型,可以通过 Runtime API、Web UI 或 Workspace 修改。Schema 与受影响数据必须在同一个目标状态中检查,并可以在同一事务中原子提交。
Schema 至少表达:
- Collection 名称与 Markdown Layout;
- 字段名称、类型、required、nullable、default 和 unknown-field 策略;
- enum、数组元素与嵌套对象结构;
- 唯一索引、普通索引和全文索引;
- Reference 目标与删除策略;
- 分区策略与文件容量策略;
- Body 是否存在及其语义。
内置字段类型包括:
string integer number decimal
boolean date datetime uuid
enum array object reference
markdown asset-reference字段不存在、null、空字符串与空数组是不同状态。Collection 可以配置 strict 或 open;strict 拒绝未知字段,open 保存未知字段并在 Query API 中按动态值处理。默认采用 strict。
Schema 自身使用 Markdown Document 保存,结构定义位于 frontmatter,正文用于人类说明。例如:
---
mddb:
kind: schema
collection: projects
layout: document
strict: true
fields:
title:
type: string
required: true
status:
type: enum
values: [active, completed, archived]
owner:
type: reference
collection: people
onDelete: setNull
indexes:
- fields: [status]
---
Project 保存正在进行或已经完成的项目。Schema Markdown 可以进入 Workspace 并自由编辑。Runtime Database 只接受通过 Runtime Mutation 或合法 Merge Plan 提交的 Schema。
Reference 与删除策略
Record 通过 UUID Reference 建立关系。Reference 可以是单值或数组,并进入正向与反向关系索引。
Schema 为删除关系选择:
restrict:存在引用时拒绝删除;cascade:在同一事务中删除依赖 Record;setNull:将可空单值引用设为null;remove:从数组引用中移除目标 UUID。
Merge Plan 和运行时 Mutation 都必须在提交前展示或返回完整级联影响。
Markdown Layout
Document
一个文件保存一条 Record,是内容型 Collection 的默认布局,适合文章、知识、项目和正文型对象:
---
id: 0195d51a-7d87-7cd5-813c-3f1c26a87f21
collection: projects
title: Markdown DB Engine
status: active
---
这里是 Markdown Body。Properties 保存结构化字段,frontmatter 之后的内容保存 Body。运行时局部修改必须尽量保留未触及字段、注释、顺序、缩进和正文。
Document 的默认物理文件名来自安全规范化后的 title,例如上面的 Record 保存为 Markdown DB Engine.md。路径分隔符、控制字符和系统保留名会被安全转换,过长标题会按照 UTF-8 字节边界截断。普通 Document Collection 内的标题在完成文件名转换、Unicode 规范化和大小写折叠后必须保持唯一;发生冲突时提交会返回 RECORD_INVALID,Workspace Init 会报告 WORKSPACE_TITLE_CONFLICT,不会自动添加 UUID 后缀。修改标题会在同一事务中移动正式文件,但不会改变 UUID。不同 Collection 可以使用同名标题;table、records 与 _users 等内置系统 Collection 不使用标题文件名。
Table
一个 GFM Table 保存多条扁平 Record,只适合具有明确容量上限、以标量字段为主的小型辅助数据:
---
mddb:
collection: settings
layout: table
---
| id | key | value | enabled |
| --- | --- | --- | --- |
| 0195...721 | theme | dark | true |
| 0195...722 | language | zh-CN | true |Table 字段类型由 Schema 决定。嵌套对象、多行正文和复杂数组不能使用 Table Layout。Schema 必须声明每个文件的最大 Record 数和最大字节数,超过任一上限时创建新分区。
Records
一个 YAML fenced block 保存多条结构化 Record,适合具有明确容量上限的小型数组和嵌套对象集合:
---
mddb:
collection: products
layout: records
---
```yaml
- id: 0195...721
title: Markdown DB Engine
tags:
- database
- markdown
```Records Layout 不为每条 Record 提供独立 Body;需要正文时使用 Document Layout。Schema 必须声明每个文件的最大 Record 数和最大字节数,超过任一上限时创建新分区。
布局选择不变量
- 有 Markdown Body 或需要独立审阅、寻址、移动的 Record 使用 Document;
- Table 与 Records 只用于小型辅助数据,不能作为数千条 Record 的单文件容器;
- Collection 总量可以较大,但每个文件必须是人和 Agent 可以在有界上下文中理解和修改的编辑单元;
- Runtime 可以为了查询与事务采用不同的内部索引和分区,Workspace 也可以重新投影布局,但两者共享同一逻辑 UUID、Record 和 Schema。
Codec
Codec 是 Markdown Layout 与逻辑 Record 之间的转换边界。每个 Codec 必须提供确定性的:
- parse:从文件得到 Record、位置与诊断;
- render:从 Record 创建合法 Markdown;
- diff:识别 Record 与字段变化;
- patch:局部修改并保留无关格式;
- validate:检查布局限制和 Schema;
- locate:把 Record UUID 映射到文件字节范围。
内置 Codec 是 Document、Table 和 Records。其他布局只能通过明确扩展加入,不能依靠模糊推断改变已有文件语义。
分区
同一 Collection 可以跨多个 Markdown 文件保存。分区方式包括:
- 按字段,例如年份、分类或租户;
- 按文件最大 Record 数;
- 按文件最大字节数;
- 明确的用户路径规则。
数据库可以根据 Schema 创建新分区,但不能静默重新组织用户已有文件。重新分区是一项可审查的 Changeset。Query、Reference 和事务不暴露分区差异。
容量分区对于 Table 与 Records 是强制要求。Document Collection 也可以按照年份、分类、租户或目录容量分区,使文件发现和任务上下文保持有界。
二进制资产
图片、音频、视频和附件不直接成为 Markdown Record 内容。数据库保存 Asset Reference,包括路径、URL、媒体类型、摘要和可选校验值。资产存储与传输由外部系统负责。