我正在开发一个电子商务网站,用户可以对可用产品表现出兴趣,我们将其存储在mysql表中。此Leads
表由数百万条记录组成,每秒增长8条记录。表结构如下:
LeadId | ProductId | UserId | RequestDate(DateTime)
表架构:
`id` int(11) NOT NULL AUTO_INCREMENT,
`ProductId` int(11) DEFAULT NULL,
`UserID` int(11) NOT NULL,
`RequestDateTime` datetime(3) NOT NULL,
PRIMARY KEY (`id`),
KEY `ix_leads_requestdatetime` (`RequestDateTime`) USING BTREE,
KEY `ix_leads_productid` (`ProductId`) USING BTREE,
KEY `ix_leads_userid` (`UserID`) USING BTREE
现在,要求允许一个用户在一天内最多提供10个潜在客户。我有以下方法来实现这个:
选择查询以计算Leads
表中当天的记录数,并检查<插入前20。
维护一个DailyLeadCount
表,其中包含特定日期的每个userId
的潜在客户数。表结构:
UserId | Date | Count
表架构:
`RequestDate` date NOT NULL,
`UserId` int(11) NOT NULL,
`LeadCount` smallint(6) NOT NULL,
PRIMARY KEY (`RequestDate`,`UserId`)
我会在插入Leads
表之前检查此表中的计数,并在插入后更新此计数。此外,由于此表中只有一天数据有用,我将创建一个作业以便每天存档。
哪种方法更好?是否在Leads
表上运行select查询以获得比插入/更新更重的计数并在DailyLeadCount
表上选择查询?
是否值得每天维护和存档一张桌子?
还有其他方法可以解决这个问题吗?
答案 0 :(得分:0)
更改
KEY `ix_leads_userid` (`UserID`) USING BTREE
到
INDEX(UserID, RequestDateTime)
然后在
时向用户吐口水( SELECT COUNT(*) FROM Leads WHERE UserID = 1234
AND RequestDateTime > NOW() - INTERVAL 24 HOUR
) >= 10
查询将足够快,可以实时完成。
计数是在昨天和现在这段时间之间 - 这可能不是你想要的。相反,如果您希望时钟今天早上午夜开始:
AND RequestDateTime > CURDATE()
如果“从昨天午夜开始”:
AND RequestDateTime > CURDATE() - INTERVAL 1 DAY
如果你想在午夜使用他的时区,那就太麻烦了。
潜在问题:如果他可以以某种方式批量他的线索,他可以在同一毫秒内插入多个线索。 (我注意到DATETIME(3)
。)
如果你需要检查“昨天”,你对“汇总表”的想法最有效,对于“最后86400000毫秒”则不太好。