在设计商品模块的时候,有一个需求是某一些商品是不能参加活动的。这个时候设计商品模型的时候就又两种选择:
将限购这个属性放到商品模型上,归商品模块维护
商品模块不管这个限购属性,由活动模块记录限购,维护一份限购商品Id表
个人觉得这两种方式都可以,但是如果把限购这个属性放到商品模型上得话,以后这种特殊属性越来越多的话,会导致商品模型无限膨胀。所以如果由促销来管理这个关系的话,商品模型上就只有一些简单的属性,这个基础服务就会更加的干净。
请问有没有一些经验或者准则可以参考一下?
一般情况下,建议采用商品和活动分表记录,然后通过一张关系表来建立联系,这样不管从商品找活动还是从活动找商品都会比较方便。对于近期活动需要快速读取的情况,甚至可以针对活动单独建立缓存数据,以提高读取效率。
商品,活动,限购都是需要记录的事实。关键问题是“限购”应该怎样表示。
由于限购本身还可能包含其他属性,比如限购日期等等,所以不是单单一个关联表(多对多关系)就能解决的。
有两种方法可以记录限购:1)记录不限购的商品、活动2)记录限购的商品活动
如果限购的商品活动数量相对较小,方法2)更合适。
Product (ProductId, ...)
Activity (ActivityId, ...)
PurchaseRestriction (ProductId, ActivityId, StartDate, EndDate,...)
你的疑问:
PurchaseRestriction 既跟Product相关,又跟Activity相关。不是简单的“谁的属性”。
很多人设计class时使用循环引用,比如,Product 拥有 RestrictedActivities 集合,Activity 拥有 RestrictedProducts 集合。
你心里也有类似的疑问,一方面觉得限购是一个事实,只应该放在一个地方;另一方面,感觉限购既是Product的属性,又是Activity的属性。
我觉得,这是面向对象的一个缺点,“对象拥有属性,属性必须属于某个对象”这个思想的根源是认为所有东西都是树状结构的。
这跟树形数据库犯了同样的错误,后来出现网络数据库。网络数据库可以表达复杂的结构,但是过于复杂。
关系数据库的出现,解决了树形数据库和网络数据库的问题。关系数据库是基于集合论和一阶谓词逻辑的模型,可以完美地表达各种结构。
"模块化"当然很好,合理的模块化减少了程序各模块之间的耦合。
但是,一个系统最大的耦合往往是程序和数据的耦合。数据的结构变了,程序必须跟着变。
因此,规范的数据库设计比应用程序的模块化更重要。
你把商品和活动分到不同的模块,一方面提高了抽象级别,模块化,另一方面割裂了它们的联系。虽然模块多了,但模块间的交互更复杂了。
你的问题没有完美的答案,有3个解决方案:
a) 商品模块去维护
b) 活动模块去维护
c) 单独的模块去维护。
在程序里,也许有某个类,它有一个属性 CanTakePartInActivity. 但是数据库不能这样设计。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。