【问题标题】:Best way to implement [user — subscriptions/subscribers] relation in database在数据库中实现 [user — subscriptions/subscribers] 关系的最佳方式
【发布时间】:2017-11-20 20:53:33
【问题描述】:

我正在使用 Swift 4 + Vapor 框架、Fluent ORM 和 PostgreSQL 作为驱动程序编写服务器。我有一个用户模型,它应该有订阅者和订阅(这也是用户模型)。我在这里有两个选择:1. 存储具有唯一订阅/订阅者 ID 的数组,或者 2. 建立一对多的用户-用户关系。您认为哪一个更好,我该如何实施?

【问题讨论】:

    标签: swift postgresql orm vapor


    【解决方案1】:

    存储数组不是最优的。查询您的数据库以查找用户的所有订阅者将需要解析每个用户的订阅数组并查找包含目标用户 ID 的那些。关系是一个更好的主意。

    Fluent 使用Pivot 类来模拟多对多关系。因为它是一种自引用关系,所以为了避免 ID 键冲突,您可能会发现创建自己的“通过”模型最容易。

    import FluentProvider
    import Vapor
    
    final class Subscription: Model, PivotProtocol {
    
      typealias Left = User
      typealias Right = User
    
      var subscriberId: Identifier
      var subscribedId: Identifier
    
      init(
        subscriberId: Identifier,
        subscribedId: Identifier
      ) {
        self.subscriberId = subscriberId
        self.subscribedId = subscribedId
      }
    
      let storage = Storage()
    
      static let leftIdKey = "subscriber_id"
      static let rightIdKey = "subscribed_id"
    
      init(row: Row) throws {
        subscriberId = try row.get("subscriber_id")
        subscribedId = try row.get("subscribed_id")
      }
    
      func makeRow() throws -> Row {
        var row = Row()
        try row.set("subscriber_id", subscriberId)
        try row.set("subscribed_id", subscribedId)
        return row
      }
    
    }
    
    extension User {
      var subscribers: Siblings<User, User, Subscription> {
        return siblings(localIdKey: "subscriber_id", foreignIdKey: "subscribed_id")
      }
      var subscribed: Siblings<User, User, Subscription> {
        return siblings(localIdKey: "subscribed_id", foreignIdKey: "subscriber_id")
      }
    }
    

    【讨论】:

    • 感谢您的详细解答!我认为这是一个很好的起点^‿^
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-30
    • 2016-08-08
    • 2011-04-17
    相关资源
    最近更新 更多