0

我刚刚开始了一个新的数据库项目来为客户投标报价定价:

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

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

事情在某种程度上被简化了,因为投标在任何情况下都不会使用跨版本的价格,因此即使产品被搁置并且在旧版本的定价表中可用,它也不会用于新项目。

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

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

有关如何解决此问题的任何建议?此外,我正在使用 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 成为一个问题。

4

3 回答 3

2

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

class Price {

    static hasMany = [ values: PriceValue ]

}

class PriceValue {

    Number amount
    Date validFrom
    Date validTo

    static belongsTo = [ price: Price ]

}
于 2012-09-14T12:03:01.077 回答
0

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

所以我提出以下设计:

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()
  }

}
于 2012-09-14T13:55:47.167 回答
0

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

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

还有很多其他有用的功能,但听起来它的基本功能很适合你。您唯一需要做的就是跟踪工作区及其状态,因为应用程序用户在您的 UI 上签出、合并和解决冲突。

于 2012-09-14T14:14:08.430 回答