Grails数据库表版本控制

时间:2012-09-14 11:48:59

标签: database grails version-control

我刚刚启动了一个新的数据库项目来定价客户出价提案:

数据库中的某些表将包含定期更新的信息,例如定价表。

现在,新的出价应始终使用有关数据库的最新信息,但现有出价应继续使用开始时使用的数据,除非出价作者另有决定。

事项有些简化,因为出价在任何情况下都不会在不同版本之间使用价格,所以即使产品在旧版本的定价表中被淘汰并且可用,它也不适用于较新的项目。

为了实现这一点,我计划包含一个版本列,也许还包括一个链接版本控制表。我认为这就足够了。

然而,我觉得这必须是一个共同的数据库设计要求,因此必须有现有的“最佳实践”和技术来实现这一点,所以我宁愿建立在现有经验之上,而不是重新发明轮子。

有关如何解决此问题的任何建议?此外,我正在使用Grails平台,因此非常感谢任何Grails特定信息。

我不确定我是否正确解释了我的问题所以这是一个例子:

class Bid { // Each new customer bid is stored in this table
    String bidName
    static hasMany = [ item: ItemList ]
    static belongsTo = [ versionNumber: VersionControl]
}

class ItemList { // Products/Services are associated with a bid via this table

    String description
    static belongsTo = [ bid: Bid, item: Price ]
}

class Price { // The price of individual products and services the company offers
    String description
    Long value

    static belongsTo = [ versionNumber: VersionControl]
}

class VersionControl { 
/** So that when filling in the ItemList form for a bid, I can query for only 
*   prices with the correct version number 
*/

    String user
    Long versionNumber
    Date timestamp

    static hasMany = [ bid: Bid, productOrService: Price ]
}

此示例工作正常,并说明了我想要做的事情。我只是不知道这是解决问题的最佳方式以及它的扩展程度 - 我有大约20个包含不同参数的表,我需要跟踪它们的版本。

始终会为出价分配最新版本的定价列表,但用户必须能够选择其他版本。

我应该提一下,价格将使用会计部门提供的csv文件批量更新,而不是单独更新。每个csv代表一个新的谨慎的价格表版本,不仅仅是数据库,而是从内部管理的角度来看。

类似的理念会影响数据库中的其他表格,例如使用的汇率或公司运营的地理区域。

新版本发布的规律性也难以预测,这可能会导致确定endDate成为问题。

3 个答案:

答案 0 :(得分:2)

此目标没有特殊的Grails支持,这只是4th normal form。在您的情况下,它将是价格实体的标题表和具有限制的时间值表:

class Price {

    static hasMany = [ values: PriceValue ]

}

class PriceValue {

    Number amount
    Date validFrom
    Date validTo

    static belongsTo = [ price: Price ]

}

答案 1 :(得分:0)

我相信你不应该将Version提取到一个单独的实体中,而你的Price显然是Effectivity,并且具有严格的时间间隔(我假设)。

所以我提出以下设计:

class Product {
  // whatever
}

class ProductPrice {
  String description
  BigDecimal value
  DateTime startDate // or use JodaTime Interval
  DateTime endDate

  static belongsTo = Product
}

class Bid { // Each new customer bid is stored in this table
  String bidName
  DateTime bidDate // or use createdDate

  static hasMany = [products: Product]
  static belongsTo = [ Customer ]

  BigDecimal getProductPrice(Product p) {
    ProductPrice.where{ 
      product = p && startDate >= bidDate && endDate < bidDate 
    }.find()
  }

  // or even

  static transients = [ 'prices' ]

  List<ProductPrice> getPrices() {
    products.colect{ getProductPrice(it) }
    // or even...
    ProductPrice.where{ 
      product = p && 
        startDate >= bidDate && 
        endDate < bidDate 
    }.list()
  }

}

答案 2 :(得分:0)

我建议使用oracle数据库及其“工作区管理器”功能(我将它与grails一起使用,效果非常好)http://www.oracle.com/technetwork/database/enterprise-edition/index-087067.html

这将解决您列出的所有要求:如果您“版本启用”一个表,该表使您能够从您分支的父级创建当前数据快照的工作空间。所有这些工作空间可以彼此独立地进行更改,并在它们准备就绪时合并回主工作空间(并且oracle简化了它们之间的冲突解决方案)。但是,并非所有表都必须进行版本化,例如定价表,因此将定期管理它们。

还有许多其他有用的功能,但听起来它的基本功能适合您的账单。您唯一需要做的就是跟踪应用程序用户在UI上检出,合并和解决冲突时的工作空间及其状态。