fix(mining-admin): use Prisma relationMode=prisma for CDC sync tables
Switch to Prisma's "prisma" relation mode to handle CDC event ordering issues. This mode emulates foreign key relations at the Prisma Client layer instead of creating database-level FK constraints, which is the recommended approach for CDC scenarios where event arrival order cannot be guaranteed. Reference: https://www.prisma.io/docs/orm/prisma-schema/data-model/relations/relation-mode Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
ea789f7fec
commit
01ff873264
|
|
@ -1,7 +1,9 @@
|
|||
-- =============================================================================
|
||||
-- 移除 CDC 同步表的外键约束
|
||||
-- 切换到 Prisma relationMode = "prisma"
|
||||
-- 移除数据库层的外键约束,改由 Prisma Client 在应用层模拟外键关系
|
||||
--
|
||||
-- 原因:CDC 事件异步到达,顺序不可控,子表记录可能在父表记录之前到达
|
||||
-- 参考:https://estuary.dev/blog/cdc-done-correctly/
|
||||
-- 参考:https://www.prisma.io/docs/orm/prisma-schema/data-model/relations/relation-mode
|
||||
-- =============================================================================
|
||||
|
||||
-- 移除 synced_contribution_accounts 表的外键约束
|
||||
|
|
@ -19,3 +21,16 @@ DROP CONSTRAINT IF EXISTS "synced_mining_accounts_accountSequence_fkey";
|
|||
-- 移除 synced_trading_accounts 表的外键约束
|
||||
ALTER TABLE "synced_trading_accounts"
|
||||
DROP CONSTRAINT IF EXISTS "synced_trading_accounts_accountSequence_fkey";
|
||||
|
||||
-- 为 accountSequence 字段添加索引以优化 JOIN 性能(如果不存在)
|
||||
CREATE INDEX IF NOT EXISTS "synced_contribution_accounts_accountSequence_idx"
|
||||
ON "synced_contribution_accounts"("accountSequence");
|
||||
|
||||
CREATE INDEX IF NOT EXISTS "synced_referrals_accountSequence_idx"
|
||||
ON "synced_referrals"("accountSequence");
|
||||
|
||||
CREATE INDEX IF NOT EXISTS "synced_mining_accounts_accountSequence_idx"
|
||||
ON "synced_mining_accounts"("accountSequence");
|
||||
|
||||
CREATE INDEX IF NOT EXISTS "synced_trading_accounts_accountSequence_idx"
|
||||
ON "synced_trading_accounts"("accountSequence");
|
||||
|
|
@ -5,6 +5,7 @@ generator client {
|
|||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
relationMode = "prisma" // CDC场景:Prisma层模拟外键关系,数据库不创建FK约束
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
|
@ -163,8 +164,11 @@ model SyncedUser {
|
|||
syncedAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// CDC 同步表不设置外键约束,因为事件到达顺序不可控
|
||||
// 使用 accountSequence 作为逻辑关联键,查询时用 LEFT JOIN
|
||||
// 关联同步表
|
||||
contributionAccount SyncedContributionAccount?
|
||||
miningAccount SyncedMiningAccount?
|
||||
tradingAccount SyncedTradingAccount?
|
||||
referral SyncedReferral?
|
||||
|
||||
@@index([phone])
|
||||
@@index([status])
|
||||
|
|
@ -179,7 +183,7 @@ model SyncedUser {
|
|||
|
||||
model SyncedContributionAccount {
|
||||
id String @id @default(uuid())
|
||||
accountSequence String @unique // 逻辑关联 SyncedUser.accountSequence,无外键约束
|
||||
accountSequence String @unique
|
||||
personalContribution Decimal @db.Decimal(30, 8) @default(0)
|
||||
teamLevelContribution Decimal @db.Decimal(30, 8) @default(0)
|
||||
teamBonusContribution Decimal @db.Decimal(30, 8) @default(0)
|
||||
|
|
@ -192,6 +196,8 @@ model SyncedContributionAccount {
|
|||
syncedAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
user SyncedUser @relation(fields: [accountSequence], references: [accountSequence])
|
||||
|
||||
@@map("synced_contribution_accounts")
|
||||
}
|
||||
|
||||
|
|
@ -201,7 +207,7 @@ model SyncedContributionAccount {
|
|||
|
||||
model SyncedReferral {
|
||||
id String @id @default(uuid())
|
||||
accountSequence String @unique // 逻辑关联 SyncedUser.accountSequence,无外键约束
|
||||
accountSequence String @unique
|
||||
referrerAccountSequence String? // 推荐人账户序列号
|
||||
referrerUserId BigInt? // 1.0 的 referrer_id
|
||||
originalUserId BigInt? // 1.0 的 user_id
|
||||
|
|
@ -210,6 +216,8 @@ model SyncedReferral {
|
|||
syncedAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
user SyncedUser @relation(fields: [accountSequence], references: [accountSequence])
|
||||
|
||||
@@index([referrerAccountSequence])
|
||||
@@index([depth])
|
||||
@@map("synced_referrals")
|
||||
|
|
@ -301,7 +309,7 @@ model SyncedNetworkProgress {
|
|||
|
||||
model SyncedMiningAccount {
|
||||
id String @id @default(uuid())
|
||||
accountSequence String @unique // 逻辑关联 SyncedUser.accountSequence,无外键约束
|
||||
accountSequence String @unique
|
||||
totalMined Decimal @db.Decimal(30, 8) @default(0)
|
||||
availableBalance Decimal @db.Decimal(30, 8) @default(0)
|
||||
frozenBalance Decimal @db.Decimal(30, 8) @default(0)
|
||||
|
|
@ -309,6 +317,8 @@ model SyncedMiningAccount {
|
|||
syncedAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
user SyncedUser @relation(fields: [accountSequence], references: [accountSequence])
|
||||
|
||||
@@map("synced_mining_accounts")
|
||||
}
|
||||
|
||||
|
|
@ -318,7 +328,7 @@ model SyncedMiningAccount {
|
|||
|
||||
model SyncedTradingAccount {
|
||||
id String @id @default(uuid())
|
||||
accountSequence String @unique // 逻辑关联 SyncedUser.accountSequence,无外键约束
|
||||
accountSequence String @unique
|
||||
shareBalance Decimal @db.Decimal(30, 8) @default(0)
|
||||
cashBalance Decimal @db.Decimal(30, 8) @default(0)
|
||||
frozenShares Decimal @db.Decimal(30, 8) @default(0)
|
||||
|
|
@ -328,6 +338,8 @@ model SyncedTradingAccount {
|
|||
syncedAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
user SyncedUser @relation(fields: [accountSequence], references: [accountSequence])
|
||||
|
||||
@@map("synced_trading_accounts")
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue