避免在SQL语言中对数据进行与在域

时间:2017-11-08 11:49:14

标签: mysql sql postgresql scala eventual-consistency

想象一下,class Purchasable

中的scala看起来像这样
case class Purchasable(product: ProductData,store: StoreData,seller: UserData){
  require {
    //seller is active &&
    //seller has defined personal info &&
    //seller has defined means of accepting payment
    //product contains a price in seller's current currency
    //product has defined shipping policies for atleast on of the store's locations
    //product is not past expiration date
    //product is either new or has uploaded images
    //and so on!
  }
}

object Purchasable {
  def validate(p: ProductData,s: StoreData,u: UserData): Either[String,Purchasable] = {
    Try(Purchasable(p,s,u)).toOption.toRight("unpurchasable.product")
  }
}

类型ProductDataStoreDataUserData来自3个数据库表的所有重复行。

当买家想要购买产品或将其添加到购物车时,必须从这三个获取的行中获取成功的Purchasable实例。

但是,在买家将此商品添加到购物车之前,她必须首先查询我们的数据库,以获取可购买产品的列表。

很明显,查询这些可购买产品会导致SQL中的一个非常复杂的condiotinal子句(这不是我的主要关注点)。我主要担心的是必须用两个完全不同的语言编写的重复逻辑所以我想做的是创建另一个名为purchasables的表,其中包含所有通过可购买标准的产品ID ;我从db流式传输三行,在scala中使用Purchasable.validate验证它们并将它们插入到新表中。所以现在我有两个好处:

  • 我的查询变得如此简单:
select * from products p 
join stores s on p.storeId = s.id 
join users u on s.userId = u.id
join purchasables pur on pur.productId = p.id
  • 没有重复的逻辑和可维护性问题。如果业务需求发生变化,我只需要在代码中更改一个位置。

我看到的缺点是我的可购买产品现在拥有他们所谓的“强烈”最终一致性而不是立即。因为purchasables表只是定期刷新,即使它是每2分钟一次。

我的问题:我在这里所做的是既定的做法?我在互联网上搜索它,所有关于最终一致性的谈话和技术都针对分布式系统问题。我还没有找到关于讨论选择的单篇文章或stackoverflow问题。在这样的情况下,我觉得我完全偏离了轨道而且没有任何关于我正在做什么的线索。

1 个答案:

答案 0 :(得分:0)

我可能错过了一些东西,但我认为你的第一种方法更简单,更正常。

你说你需要用两种语言复制逻辑,但我不明白为什么会这样。

根据我的理解,验证产品是否可购买,并找到所有可购买的产品实际上是相同的。它是find all purchasables in this source table,源表可以与单个元素表一样小,也可以与完整项表一样大。所以你应该有一个函数,相同的代码将处理这两个用例。

例如,如果您使用光滑,则可能具有类似

的功能
def findPurchasablesIn(table: Query[ProductTable, ProductRow, Seq])

并用不同的源表调用它?