Skip to content

数据库设计 (Database Design)

YunStack-IoT 使用 PostgreSQL 作为核心业务数据库,利用其强大的关系查询能力和对 JSONB 的良好支持。

1. ER 关系图

2. Prisma Schema 定义

2.1 用户表 (User)

存储平台用户的基础信息。

prisma
model User {
  id        String   @id @default(uuid())
  username  String   @unique @db.VarChar(50)
  password  String   @db.VarChar(255)
  email     String?  @unique
  avatar    String?
  role      String   @default("user") // admin, user
  createdAt DateTime @default(now()) @map("created_at")
  updatedAt DateTime @updatedAt @map("updated_at")

  devices   Device[] // 一对多关联
  
  @@map("users")
}

2.2 产品表 (Product)

定义一类设备,包含物模型和鉴权密钥。

prisma
model Product {
  id          String   @id // ProductKey, e.g., "p_relay_4ch"
  name        String   @db.VarChar(64)
  description String?  @db.Text
  thingModel  Json     @map("thing_model") // 物模型定义 (JSONB)
  transport   String   @default("MQTT") // MQTT, HTTP, CoAP
  secret      String   @default(uuid()) // ProductSecret
  createdAt   DateTime @default(now()) @map("created_at")
  
  devices     Device[]

  @@map("products")
}

2.3 设备表 (Device)

存储具体的设备实例,关联产品和用户。

prisma
model Device {
  id           String    @id @default(uuid()) // 逻辑 ID
  productId    String    @map("product_id")
  name         String    @db.VarChar(64)
  physicalId   String    @map("physical_id") // MAC/SN
  secret       String    @default(uuid()) // DeviceSecret
  ownerId      String?   @map("owner_id")
  
  // 状态字段 (非持久化业务状态可能存在 Redis,此处仅作持久化备份)
  isOnline     Boolean   @default(false) @map("is_online")
  lastOnlineAt DateTime? @map("last_online_at")
  shadow       Json      @default("{}") // 设备影子 (JSONB)
  
  createdAt    DateTime  @default(now()) @map("created_at")
  updatedAt    DateTime  @updatedAt @map("updated_at")

  // 关联关系
  product      Product   @relation(fields: [productId], references: [id])
  owner        User?     @relation(fields: [ownerId], references: [id])
  logs         DeviceLog[]

  @@unique([productId, physicalId]) // 联合唯一索引
  @@map("devices")
}

2.4 设备日志表 (DeviceLog)

记录设备的关键行为(报警、上下线、关键操作)。

prisma
model DeviceLog {
  id        BigInt   @id @default(autoincrement())
  deviceId  String   @map("device_id")
  type      String   @db.VarChar(20) // online, offline, alert, ota
  content   Json?    // 日志详情 (JSONB)
  createdAt DateTime @default(now()) @map("created_at")

  device    Device   @relation(fields: [deviceId], references: [id])

  @@index([deviceId, createdAt(sort: Desc)])
  @@map("device_logs")
}

3. 索引策略

  • devices:
    • idx_devices_physical_id: (product_id, physical_id) 联合唯一索引,用于设备认证。
    • idx_devices_owner: owner_id,用于查询用户绑定的设备列表。
  • device_logs:
    • idx_logs_device_time: (device_id, created_at DESC),用于查询某设备的历史日志。

4. 时序数据 (InfluxDB)

虽然不是 PostgreSQL,但也在此统一规划。

  • Measurement: device_telemetry
  • Tags:
    • product_id
    • device_id
  • Fields:
    • 根据物模型动态变化 (如 temp, humi, voltage, relay_1)。