关于#java#的问题:mysql新增数据

mysql新增数据

我从java新增数据,b字段是一个通过字符串拼接的数据 类型+当前日期+连续自增, 我可以拿到 类型(语文/数学),日期,现在主要是后面的连续自增的,还有个要求,当天新增的都是从0001开始,比如 语文-20220817-0001,当天新增的话是 语文-20220817-0002
另一天新增的话就是 语文-20220818-0001

img

查询最大值+1,如果没有则等于0001

1、使用redis自增序列,类型+当前日期作为redis的key,具体命令incrby key increment,返回的数字不满4位时,前面补零;
2、如果项目里面没有使用redis,那就利用数据库写一个自增功能;
这两种方案,您都得保证同时只有一个线程请求获取序列号,多节点服务的话,得使用分布式锁,单节点的话,简单粗暴一点,可以用同步锁,仅供参考。


完全符合你的需求

题主 是自己练习吗?

可以从如下几种方案考虑:

  • (推荐)Redis管理:科目_日期,给key设置有效期。判断key是否存在,存在+1;不存在直接新增;因为过期key自动从Redis中清除;
  • (推荐)MySQL表管理:参考以下SQL思路,转换为JAVA逻辑(不清楚可以回复);
  • (不推荐)取最大值+1:需要拆分字段,且数据量少低并发时可以,否则会出现重复,但不是最优;

如果没有使用Redis,又想灵活扩展,以下思路供参考:

CREATE TABLE sys_primary_key_t (
    `id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '行ID',
    `table_name` VARCHAR(64) NULL DEFAULT NULL COMMENT '表名',
    `key_name` VARCHAR(64) NULL DEFAULT NULL COMMENT '键名',
    `key_value` INT NULL COMMENT '键值',
    `ext_code` VARCHAR(32) NULL DEFAULT NULL COMMENT '扩展码(预留列)',
    PRIMARY KEY (`id`)
)
COMMENT='自增长主键表'
COLLATE='utf8_general_ci'
;


-- 第1步:根据 表名 + 键名 查询 当前键值
SELECT id, table_name, key_name, key_value, ext_code
-- SELECT id, table_name, key_name, LPAD(key_value, 3, '0'), ext_code
  FROM sys_primary_key_t a
 WHERE a.table_name = 'job_school_timetable_t' -- 数据库表名
   AND a.key_name = '语文' -- 键名/列名
;

-- 第2步:如果 表名 + 键名 不存在,则新增一条
INSERT INTO sys_primary_key_t
    (table_name, key_name, key_value, ext_code)
VALUES
    ('job_school_timetable_t', '语文', 10, '20220817');

-- 第3步:如果 表名 + 键名 存在,则判断 当前日期 是否与 ext_code 相等:
-- 1、相等,更新 键值+1
UPDATE sys_primary_key_t
   SET key_value = key_value + 1
 WHERE id = 1 -- 查询到的ID
--  AND table_name = 'job_school_timetable_t'
--  AND key_name = '语文'
--  AND ext_code = '20220817'
;
-- 2、不等,则更新 ext_code 为当前值(最新日期),同时初始化 key_value
UPDATE sys_primary_key_t
   SET ext_code  = '20220817', -- 当前的日期
       key_value = 1
 WHERE id = 1 -- 查询到的ID
--  AND table_name = 'job_school_timetable_t'
--  AND key_name = '语文'
;