软件代码设计-小优化(五)

产品需求:

        按照天统计策略信收信人数和收信次数。以前策略信只有发送是没有收集的,现在要数据咋办,得收集啊。

设计方案:

        因为策略信的发送是在一个单独的工程里,没有连接数据库。于是收集策略信放到了redis的list里,其中redis的key按照当天日期标识,因为还要统计收策略信的次数,所以允许重复,选择了redis的list。

        然后在管理后台的工程里,通过定时任务取redis的数据,存到表里。

        数据统计,直接查询表数据。

 结果:

        数据是正确的,没问题。但是跑了一段时间后,发现这个表的数据太大了。。。。。。

重新设计方案:

        删除历史数据,仅保留最近3个月的。但是这个表定时插入、定时查询、定时删除,可能会把数据库搞垮了。

        那就搞个新的表, 执行定时插入和定时查询,老的表执行定时删除。问题来了:搞一个新的表,跑一段时间,不还是会数据太大吗?弄一个分表,10天1张表。

1. 先看mybatis如何创建表

    <select id="existTable" parameterType="String" resultType="Integer">
        select count(*)
        from information_schema.TABLES
        where table_name = #{tableName}
    </select>
    <!-- 删除指定的表-->
    <update id="dropTable">
        DROP TABLE IF EXISTS ${tableName}
    </update>
    <!-- 创建新的日志表-->
    <update id="createTable" parameterType="String">
        CREATE TABLE ${tableName}
        (
            `id` bigint(20) NOT NULL AUTO_INCREMENT,
            `day` varchar(45) DEFAULT NULL COMMENT '日期',
            `userid` bigint(20) DEFAULT NULL COMMENT '用户id',
            `country` varchar(45) DEFAULT NULL COMMENT '国家',
            `channel` varchar(45) DEFAULT NULL COMMENT '渠道',
            `af_channel` varchar(64) DEFAULT NULL COMMENT '归因渠道',
            `user_regist_time` datetime DEFAULT NULL COMMENT '用户注册时间',
            `create_time` datetime DEFAULT NULL COMMENT '创建时间',
            PRIMARY KEY (`id`)
        ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT;
    </update>

2. 如何做到10天分表

String tableCacheKey = "day:strategy:buried:tablename";
        String tableName = "day_strategy_buried_";
        DateTime todayDateTime = DateTime.now();
        String tableDateNumber = todayDateTime.toString("yyyyMMdd");

        if(!redisUtil.hasKey(tableCacheKey)) { //redis里没有,就用当天日期
            tableName += tableDateNumber;

            redisUtil.set(tableCacheKey,todayDateTime.toString("yyyy-MM-dd"),30, TimeUnit.DAYS);
        } else {
            Object tableDateFromRedis = redisUtil.get(tableCacheKey);
            DateTime redisDateTime = DateTime.parse(tableDateFromRedis.toString());

            int daysBetween = Days.daysBetween(redisDateTime,todayDateTime).getDays();
            if (daysBetween % 10 != 0) {//不够10天就用上一次存的日期,
                tableDateNumber = redisDateTime.toString("yyyyMMdd");
            } else {//够10天就用新的日期
                redisUtil.set(tableCacheKey,todayDateTime.toString("yyyy-MM-dd"),30, TimeUnit.DAYS);
            }
            tableName += tableDateNumber;
        }

        log.info("tableName................{}",tableName);

        //判断表是否存在
        int exist = strategyBuriedMapper.existTable(tableName);
        if (exist > 0) return tableName;

        //不存在,则创建
        strategyBuriedMapper.createTable(tableName);

运行几天,看看啥效果。

有好的方案,欢迎赐教。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值