2023-04-25 07:30:00
要利用MySQL的唯一索引限制用户在特定时间段内只能插入一条数据,需结合其他机制(如Redis或数据库锁)实现,因为唯一索引无法直接关联时间段。以下是具体方案及步骤:
方案一:Redis分布式锁(高并发场景)获取Redis锁
在插入数据前,尝试获取Redis分布式锁,锁的键可设计为hourly_insert_lock:YYYY-MM-DD-HH(如hourly_insert_lock:2024-10-27-10),表示当前小时的唯一标识。
使用Redis的SETNX或Redlock算法实现锁的获取,确保同一时间仅一个请求能获取锁。
检查时间段
获取锁成功后,查询MySQL数据库中当前小时内最后一条记录的时间戳(如通过WHERE create_time BETWEEN '2024-10-27 10:00:00' AND '2024-10-27 10:59:59')。
若存在记录且时间戳在同一小时内,则拒绝插入并返回错误。
插入数据
若无记录或时间戳不在同一小时内,执行插入操作,并记录当前时间戳。
释放Redis锁
插入成功后,释放Redis锁(如通过DEL命令删除锁键),允许其他请求处理。
优点:Redis高性能,适合高并发场景,避免数据库锁竞争。缺点:需引入Redis,增加系统复杂度。
方案二:数据库锁(低并发场景)获取数据库锁
使用MySQL事务和行级锁(如SELECT ... FOR UPDATE)锁定相关表或行,防止并发修改。
示例:START TRANSACTION;SELECT * FROM target_table WHERE user_id = 123 FOR UPDATE; -- 锁定用户相关行
检查时间段
查询当前小时内该用户的最后一条记录时间戳(如WHERE user_id = 123 AND create_time >= DATE_FORMAT(NOW(), '%Y-%m-%d %H:00:00'))。
若存在记录且时间戳在同一小时内,则回滚事务并拒绝插入。
插入数据
若无记录或时间戳不在同一小时内,执行插入操作。
提交事务
插入成功后,提交事务并释放锁(自动释放)。
优点:无需额外组件,实现简单。缺点:高并发下数据库锁会阻塞请求,影响性能。
唯一索引的辅助作用局限性:唯一索引无法单独解决并发问题,需结合锁机制确保数据一致性。
方案选择建议通过上述方法,可有效限制用户在特定时间段内仅插入一条数据,确保数据完整性。