本文引用的文件
本文件聚焦于AI有声书生成平台中的“用户”模型与其相关业务实体之间的关联关系与数据模型设计,覆盖一对一、一对多、多对多关系的映射方式,并结合Prisma Schema与实际服务层实现,给出外键约束与级联删除策略的设计考量。同时提供常见查询场景的实现思路与最佳实践,帮助开发者快速理解与扩展用户侧的数据访问模式。
围绕用户关联关系的关键文件分布如下:
数据库迁移:外键约束与索引在迁移脚本中落地
graph TB
subgraph "数据模型(Prisma)"
U["User<br/>用户"]
C["Comment<br/>评论"]
D["Draft<br/>草稿"]
F["Favorite<br/>收藏"]
O["Order<br/>订单"]
PR["PlayRecord<br/>播放记录"]
PL["Playlist<br/>播放列表"]
PSI["PlaylistItem<br/>播放列表项"]
SR["SignRecord<br/>签到记录"]
SUB["Subscription<br/>订阅"]
TP["TokenBalance<br/>Token余额"]
TU["TokenUsage<br/>Token使用"]
UP["UserPreference<br/>用户偏好"]
end
U --- C
U --- D
U --- F
U --- O
U --- PR
U --- PL
U --- SR
U --- SUB
U --- TP
U --- TU
U --- UP
O --- TU
F --- B["Book<br/>书籍"]
PR --- BC["BookChapter<br/>章节"]
PL --- PSI
PSI --- BC
图表来源
章节来源
章节来源
用户关联关系在Prisma Schema中以relation字段声明,在数据库层面通过外键约束与索引保障一致性与查询效率。服务层通过Prisma Client进行查询与写入,控制器层负责鉴权与参数校验。
sequenceDiagram
participant Client as "客户端"
participant Ctrl as "控制器(示例)"
participant Svc as "服务层(示例)"
participant Prisma as "Prisma Client"
participant DB as "MySQL"
Client->>Ctrl : "发起请求"
Ctrl->>Svc : "调用业务方法(userId, ...)"
Svc->>Prisma : "执行查询/写入"
Prisma->>DB : "SQL执行"
DB-->>Prisma : "结果集"
Prisma-->>Svc : "对象/集合"
Svc-->>Ctrl : "组装数据"
Ctrl-->>Client : "响应"
图表来源
外键约束:迁移脚本中为 Order.user 与 PlayRecord.user 等建立了外键约束,体现一致的约束策略。
classDiagram
class User {
+id
+phone
+openid
+nickname
+avatar
+memberLevel
+memberExpireAt
+dailyUsage
+lastUsageDate
+usedAudioMinutes
+subscriptionResetDate
+comments
+drafts
+favorites
+orders
+playRecords
+playlists
+signRecords
+subscriptions
+tokenBalance
+tokenUsages
+preferences
}
class Comment {
+id
+userId
+chapterId
+content
+rating
+createdAt
}
User "1" <-- "many" Comment : "comments"
图表来源
章节来源
查询示例:按类型与更新时间倒序列出用户草稿;支持按ID查询单个草稿。
classDiagram
class User
class Draft {
+id
+userId
+type
+title
+content
+metadata
+autoSavedAt
+createdAt
+updatedAt
}
User "1" <-- "many" Draft : "drafts"
图表来源
章节来源
查询示例:获取用户收藏列表并包含书籍基本信息;添加/取消收藏;检查是否已收藏。
classDiagram
class User
class Favorite {
+id
+userId
+bookId
+createdAt
}
class Book {
+id
+title
+subtitle
+description
+coverUrl
+createdAt
}
User "1" <-- "many" Favorite : "favorites"
Favorite --> Book : "bookId -> Book.id (onDelete : Cascade)"
图表来源
章节来源
查询示例:获取用户订单列表与分页统计;订单与TokenUsage的关联便于成本归集。
classDiagram
class User
class Order {
+id
+userId
+orderNo
+planId
+productType
+amount
+status
+paymentMethod
+paymentId
+paidAt
+createdAt
+updatedAt
}
class SubscriptionPlan
class TokenUsage
User "1" <-- "many" Order : "orders"
Order --> SubscriptionPlan : "planId -> Plan.id"
Order --> TokenUsage : "tokenUsages"
图表来源
章节来源
查询示例:获取用户播放进度列表并包含章节信息;保存/更新播放进度;删除播放记录;获取最近播放记录。
classDiagram
class User
class PlayRecord {
+id
+userId
+chapterId
+progress
+duration
+createdAt
+updatedAt
}
class BookChapter
User "1" <-- "many" PlayRecord : "playRecords"
PlayRecord --> BookChapter : "chapterId -> Chapter.id"
图表来源
章节来源
查询示例:获取用户播放列表;获取播放列表详情并按顺序包含章节;添加/删除列表项;重新排序。
classDiagram
class User
class Playlist {
+id
+userId
+name
+description
+createdAt
+updatedAt
}
class PlaylistItem {
+id
+playlistId
+chapterId
+audioId
+order
}
class BookChapter
User "1" <-- "many" Playlist : "playlists"
Playlist "1" <-- "many" PlaylistItem : "items"
PlaylistItem --> BookChapter : "chapterId -> Chapter.id"
图表来源
章节来源
查询示例:检查当日签到状态与连续签到天数;执行签到并调整用户免费使用次数。
classDiagram
class User
class SignRecord {
+id
+userId
+createdAt
}
User "1" <-- "many" SignRecord : "signRecords"
图表来源
章节来源
查询示例:获取用户当前有效订阅;查询套餐列表与详情;初始化默认套餐。
classDiagram
class User
class Subscription {
+id
+userId
+planId
+startDate
+endDate
+status
+autoRenew
+createdAt
+updatedAt
}
class SubscriptionPlan
User "1" <-- "many" Subscription : "subscriptions"
Subscription --> SubscriptionPlan : "planId -> Plan.id"
图表来源
章节来源
查询示例:获取用户Token余额与使用明细;消耗Token并记录使用;检查配额。
classDiagram
class User
class TokenBalance {
+id
+userId
+totalTokens
+usedTokens
+resetDate
+createdAt
+updatedAt
}
class TokenUsage {
+id
+userId
+type
+amount
+contentLength
+orderId
+description
+createdAt
}
class Order
User "1" --> "1" TokenBalance : "tokenBalance"
User "1" <-- "many" TokenUsage : "tokenUsages"
TokenUsage --> Order : "orderId -> Order.id"
图表来源
章节来源
查询示例:读取/更新用户播放速度、音质、主题、默认音色、音量、自动播放等偏好设置。
classDiagram
class User
class UserPreference {
+id
+userId
+playSpeed
+quality
+theme
+defaultVoiceId
+defaultVolume
+autoPlayNext
+wifiOnlyDownload
+createdAt
+updatedAt
}
User "1" --> "1" UserPreference : "preferences"
图表来源
章节来源
服务层依赖
所有服务通过 models/index.ts 导出的 Prisma Client 实例进行数据库交互,确保连接复用与生命周期管理。
graph LR
U["User"] -- "RESTRICT" --> O["Order"]
U -- "RESTRICT" --> PR["PlayRecord"]
U -- "CASCADE" --> F["Favorite"]
F -- "CASCADE" --> B["Book"]
U -- "ONE-TO-ONE" --> TP["TokenBalance"]
U -- "ONE-TO-MANY" --> TU["TokenUsage"]
O --> TU
U -- "ONE-TO-ONE" --> UP["UserPreference"]
U -- "ONE-TO-MANY" --> PL["Playlist"]
PL -- "CASCADE" --> PSI["PlaylistItem"]
PSI -- "MANY-TO-ONE" --> BC["BookChapter"]
图表来源
章节来源
章节来源
本文基于Prisma Schema与服务层实现,系统梳理了User模型与评论、草稿、收藏、订单、播放记录、播放列表、签到记录、订阅、Token余额/使用、偏好等实体的关联关系与约束策略。通过明确的一对一/一对多/多对多映射、外键约束与索引设计,以及服务层的查询与业务逻辑封装,为用户侧数据访问提供了清晰、可扩展、高性能的实现路径。