最近刚完成一个商用模块开发,业务描述是这样的:客户要求开发这样的一个互联网平台,客户公司有很多的服务提供商为其提供业务,该平台负责展示这些业务,但遵循这样一个排序规则:业务点击量高的排序靠前(就像百度的Mp3排名一样),但我负责开发的管理台用户还可以手动指定某条业务的排名,若手动指定了排名,就不用按照点击量去排了,没有手动干扰过的就统一按照点击量由高到低的排名;业务在使用过程中点击量会不断增加;在设计时,使用了两张表:一张表(service)存储所有的业务;一张表(recommend)存储管理员手动干扰过的业务,两张表通过serviceId关联;大家能说说自己的设计思路吗?我这种设计有什么问题吗?谢谢了!

解决方案 »

  1.   

    下面是以上模块的核心代码,面对测试人员犀利的测试没少修改过,大家能给出一些优化和改进的建议吗?
     /**
         * 查询mostPopular业务列表 - 支持分页显示
         * @param language - 系统语言
         * @param type - service类型 -- mostPopular业务类型统一设值为2
         * @param flag - service手动标示
         * @param curPage
         * @param pageSize
         * @return PageControl
         */
        public PageControl getTotalServiceList(LanguageInfo language,int type,Map<String, Boolean> flag, int curPage, int pageSize)throws PortalONEException{
         int maxSize = ConfigUtil.getConfig().sysCfg.getMostPopularMaxSize();              //系统配置项,标示前台需要展现多少条popular业务(运行后可改变)
            this.deleteRecommendService(maxSize, type);                                       //删除排名大于maxSize的业务(手动干扰排名业务存储在手动干扰实体表recommend中)
            int num = getRecommendServiceNum(type);                                           //查询recommend中记录数
            int popnum = this.getPopularServiceNum(language);                                 //查询service表(存储所有业务)中记录数
            PageControl pageControl = null;                                                   //用于分页
            LinkedList<ServiceDetail> totallist = new LinkedList<ServiceDetail>();
            if(num == 0){
                if(popnum == 0)return null;
               if(popnum > maxSize)
                   popnum = maxSize;
               List<ServiceDetail> popservices = null;
            try
            {
                popservices = (List<ServiceDetail>) getPopularServiceList(language, 0, popnum).getSubList();
                pageControl = new PageControl(popservices, curPage, pageSize);
            }
            catch (RuntimeException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
               return pageControl;
            }else if(num <= maxSize){
                int remain = maxSize - num;
                List<ServiceDetail> popservices = (List<ServiceDetail>) getRemainPopularServiceList(type, language, 0, remain);
                totallist.addAll(popservices);
                int size = totallist.size();
                while(remain - size > 0){
                 totallist.offer(null);
                 size ++;
                }
                List<RecommendDetail> recommendlist = getRecommendList(type, 0, num);
                int leng = recommendlist.size();
                for (int i = 0; i < leng; i++) {
                       RecommendDetail recommend = recommendlist.get(i);
                       int index = recommend.getSequence()-1;
                       flag.put(recommend.getServiceId(), true);
                       ServiceDetail service = getPopularService(language, recommend.getServiceId());
                       try {
        totallist.add(index, service);
        } catch (IndexOutOfBoundsException e) {
        e.printStackTrace();
        this.deleteRecommendService(type);
                 return getTotalServiceList(language, type, flag, curPage, pageSize);
        }
                }
                while(totallist.remove(null));
                pageControl = new PageControl(totallist, curPage, pageSize);
                return pageControl;
            }else{
             this.deleteRecommendService(type);
             return getTotalServiceList(language, type, flag, curPage, pageSize);
            }
        }
      

  2.   

    我晕,不愧是模仿百度,人为干预排名赚钱,大哥,不厚道啊。算了,不是你的错,给你个思路吧。1.  人工干预的那张 Table 加个列,用来表示人工干预。正常排序时,将例外单独拿出,然后按你自己的需求,把它放前面,还是放后面都随你便咯。2.  这个新增的列,里面放数字型,不用流水号,但是插入的时候,一般按照递增的规则。或则,谁给的钱多,就把谁的值插大点。插入前,将最大的流水号取出。
      

  3.   

    呵呵!我开发的是欧洲的项目,完全没必要模仿百度!
    不过你说的很有道理,最初的系统设计方案就是你说的这种,但要是在service表加个列,各个子系统就要重新设计了,这是不可能的(虽然后来我一再向项目经理要求使用这种方案)!
      

  4.   

    如果是我做我只用一张表,在你那张service表中加字段区分就好。该字段的作用很简单,有排序过的就按照排序进行,没有操作过的都清空,然后再按照点击率排序。