基于RedwoodJS+Prisma的SQLite动态自定义字段帖子存储方案设计
表结构设计思路
放弃JSON存储的核心原因是无法实现单个文本块的独立关联引用,且局部更新、索引查询效率低。采用拆分的关系型表结构,总共5张表即可覆盖所有需求:
- Post表:存储帖子基础元数据
- PostColumnConfig表:存储用户自定义的文本块列配置,支持动态调整列数、列名
- PostRow表:存储每行数据的基础信息,支持动态增删行
- PostCell表:存储每个独立文本块的内容,每条记录对应一个单元格,有唯一主键可直接关联引用
- PostCustomAttribute表:存储帖子的动态短文本自定义属性,键值对结构支持任意数量扩展
Prisma Schema 实现
model Post { id Int @id @default(autoincrement()) title String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt columns PostColumnConfig[] rows PostRow[] attributes PostCustomAttribute[] } model PostColumnConfig { id Int @id @default(autoincrement()) postId Int post Post @relation(fields: [postId], references: [id], onDelete: Cascade) name String // 列展示名,例如“前置条件”“执行步骤” sortOrder Int @default(0) // 列的展示排序权重 cells PostCell[] } model PostRow { id Int @id @default(autoincrement()) postId Int post Post @relation(fields: [postId], references: [id], onDelete: Cascade) sortOrder Int @default(0) // 行的展示排序权重 cells PostCell[] } model PostCell { id Int @id @default(autoincrement()) postId Int post Post @relation(fields: [postId], references: [id], onDelete: Cascade) columnId Int column PostColumnConfig @relation(fields: [columnId], references: [id], onDelete: Cascade) rowId Int row PostRow @relation(fields: [rowId], references: [id], onDelete: Cascade) content String // 文本块实际内容 } model PostCustomAttribute { id Int @id @default(autoincrement()) postId Int post Post @relation(fields: [postId], references: [id], onDelete: Cascade) key String // 属性键,例如“标签”“优先级” value String // 属性值,短文本内容 @@unique([postId, key]) // 避免同一个帖子下重复的属性键 }
设计优势
- 每个文本块对应独立的PostCell记录,有唯一主键,可直接关联其他业务表,满足单独引用、单独展示的需求
- 列配置、行数据都可以动态增删改,无需修改数据库表结构,适配用户自定义配置的需求
- 局部更新效率高,修改单个文本块只需要更新对应PostCell记录,不需要操作整段JSON
- 自定义属性支持索引查询,查找特定属性的帖子效率远高于JSON字段提取
- 全部结构兼容SQLite特性,不需要额外配置即可在RedwoodJS项目中直接使用
内容的提问来源于stack exchange,提问作者Kazian
相关产品推荐
相关产品推荐

