我刚刚启动了一个新的数据库项目来定价客户出价提案:
数据库中的某些表将包含定期更新的信息,例如定价表。
现在,新的出价应始终使用有关数据库的最新信息,但现有出价应继续使用开始时使用的数据,除非出价作者另有决定。
事项有些简化,因为出价在任何情况下都不会在不同版本之间使用价格,所以即使产品在旧版本的定价表中被淘汰并且可用,它也不适用于较新的项目。
为了实现这一点,我计划包含一个版本列,也许还包括一个链接版本控制表。我认为这就足够了。
然而,我觉得这必须是一个共同的数据库设计要求,因此必须有现有的“最佳实践”和技术来实现这一点,所以我宁愿建立在现有经验之上,而不是重新发明轮子。
有关如何解决此问题的任何建议?此外,我正在使用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成为问题。
答案 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上检出,合并和解决冲突时的工作空间及其状态。