开发者社区> 问答> 正文

怎么定义某些字段的归属模块?

在设计商品模块的时候,有一个需求是某一些商品是不能参加活动的。这个时候设计商品模型的时候就又两种选择:
将限购这个属性放到商品模型上,归商品模块维护
商品模块不管这个限购属性,由活动模块记录限购,维护一份限购商品Id表
个人觉得这两种方式都可以,但是如果把限购这个属性放到商品模型上得话,以后这种特殊属性越来越多的话,会导致商品模型无限膨胀。所以如果由促销来管理这个关系的话,商品模型上就只有一些简单的属性,这个基础服务就会更加的干净。

请问有没有一些经验或者准则可以参考一下?

展开
收起
蛮大人123 2016-03-10 15:41:04 2224 0
1 条回答
写回答
取消 提交回答
  • 我说我不帅他们就打我,还说我虚伪

    一般情况下,建议采用商品和活动分表记录,然后通过一张关系表来建立联系,这样不管从商品找活动还是从活动找商品都会比较方便。对于近期活动需要快速读取的情况,甚至可以针对活动单独建立缓存数据,以提高读取效率。
    商品,活动,限购都是需要记录的事实。关键问题是“限购”应该怎样表示。
    由于限购本身还可能包含其他属性,比如限购日期等等,所以不是单单一个关联表(多对多关系)就能解决的。
    有两种方法可以记录限购:1)记录不限购的商品、活动2)记录限购的商品活动
    如果限购的商品活动数量相对较小,方法2)更合适。
    Product (ProductId, ...)
    Activity (ActivityId, ...)
    PurchaseRestriction (ProductId, ActivityId, StartDate, EndDate,...)
    你的疑问:

    1. 这张映射表,属于哪个模块去维护
      商品、活动不是相互独立的,PurchaseRestriction 恰恰表示了它们之间的联系。

    PurchaseRestriction 既跟Product相关,又跟Activity相关。不是简单的“谁的属性”。
    很多人设计class时使用循环引用,比如,Product 拥有 RestrictedActivities 集合,Activity 拥有 RestrictedProducts 集合。
    你心里也有类似的疑问,一方面觉得限购是一个事实,只应该放在一个地方;另一方面,感觉限购既是Product的属性,又是Activity的属性。
    我觉得,这是面向对象的一个缺点,“对象拥有属性,属性必须属于某个对象”这个思想的根源是认为所有东西都是树状结构的。
    这跟树形数据库犯了同样的错误,后来出现网络数据库。网络数据库可以表达复杂的结构,但是过于复杂。
    关系数据库的出现,解决了树形数据库和网络数据库的问题。关系数据库是基于集合论和一阶谓词逻辑的模型,可以完美地表达各种结构。
    "模块化"当然很好,合理的模块化减少了程序各模块之间的耦合。
    但是,一个系统最大的耦合往往是程序和数据的耦合。数据的结构变了,程序必须跟着变。
    因此,规范的数据库设计比应用程序的模块化更重要。
    你把商品和活动分到不同的模块,一方面提高了抽象级别,模块化,另一方面割裂了它们的联系。虽然模块多了,但模块间的交互更复杂了。
    你的问题没有完美的答案,有3个解决方案:
    a) 商品模块去维护
    b) 活动模块去维护
    c) 单独的模块去维护。

    1. 上面提到的(商品是否能参加活动,商品限购属性),我觉得第一个是可以归为商品固有属性,第二个可能通过一张映射表来记录(因为限购商品毕竟是少数)
      "商品是否能参加活动"可以由PurchaseRestriction推导出,不需要这样的属性。

    在程序里,也许有某个类,它有一个属性 CanTakePartInActivity. 但是数据库不能这样设计。

    2019-07-17 18:57:47
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载