关系如下:userId关联多个TopicId(userTopic表),每个topicId对应多个dataId(datatopic表),每个dataId对应一条唯一的数据(data表),现在需要通过userId随机取出5条数据的详细内容,问一下怎么写效率高?原因是oder by rand效率很差,不敢用。
dataId是自增,但里面的数据并不一定连续,例如是1,2、3、4、7、9、12、54这样的。
表结构如下:
dataId是自增,但里面的数据并不一定连续,例如是1,2、3、4、7、9、12、54这样的。
表结构如下:
CREATE TABLE `userTopic` ( `userTopicId` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT "表主键", `userId` BIGINT(20) NOT NULL COMMENT "用户id,与users表主键相同", `topicId` BIGINT(20) NOT NULL COMMENT "主题id,与topic表主键相同", PRIMARY KEY (`userTopicId`) )
CREATE TABLE `datatopic` ( `datatopicId` BIGINT(20) NOT NULL AUTO_INCREMENT, `dataId` BIGINT(20) NULL DEFAULT NULL, `topicId` BIGINT(20) NULL DEFAULT NULL, PRIMARY KEY (`datatopicId`) )
CREATE TABLE `data` ( `dataId` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT "数据编号", `dataName` VARCHAR(30) NOT NULL COMMENT "数据名称", `dataIntro` VARCHAR(200) NOT NULL COMMENT "数据简介", `keyword` VARCHAR(20) NOT NULL COMMENT "数据关键字", `pubDate` DATE NOT NULL COMMENT "数据发布日期", `updateDate` DATE NULL DEFAULT NULL COMMENT "数据更新日期", `pubState` INT(11) NOT NULL DEFAULT "0" COMMENT "发布状态:0:未审核,1:审核已通过,2:审核未通过", `userId` BIGINT(20) NOT NULL COMMENT "用户编号", `orgCode` VARCHAR(30) NOT NULL COMMENT "组织机构编号", `dataFormat` VARCHAR(100) NOT NULL COMMENT "数据格式,用于全文检索", `orgName` VARCHAR(30) NOT NULL COMMENT "组织机构名称", `dataTopic` VARCHAR(200) NOT NULL COMMENT "所述主题分类,用于全文检索", `recommend` INT(1) NOT NULL DEFAULT "0" COMMENT "推荐页面前面显示", `isDeleted` INT(1) NOT NULL DEFAULT "0" COMMENT "删除标记,0未删除1已删除", `c_date` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT "数据更新时间戳,无需处理", `downCount` INT(11) NOT NULL DEFAULT "0" COMMENT "下载次数", `evaluateCount` INT(11) NOT NULL DEFAULT "0" COMMENT "评论条数", PRIMARY KEY (`dataId`) )
解决方案
5
需要通过userId随机取出5条数据的详细内容
你有相应的语句吗,先贴出来,然后再想 怎么样实现随机的5条数据
你有相应的语句吗,先贴出来,然后再想 怎么样实现随机的5条数据
15
关于rand()优化,请参考文章:http://blog.csdn.net/tianlianchao1982/article/details/43528669
10
SET @mid = (SELECT d.dataId, d.dataName, d.orgName FROM `data` d INNER JOIN datatopic dt ON d.dataId=dt.dataId INNER JOIN userTopic u ON u.topicId=dt.topicId WHERE u.userId=1234); -- 找出userid = 1234 的纪录数量 SELECT d.dataId, d.dataName, d.orgName, FLOOR(1 + RAND() * @mid) AS rid FROM `data` d INNER JOIN datatopic dt ON d.dataId=dt.dataId INNER JOIN userTopic u ON u.topicId=dt.topicId WHERE u.userId=1234 ORDER BY rid LIMIT 0, 5
11
这么写, 不用排序了,应该还会快点,但是没法保证在生成的十个随机数中,能有5个是不重复的。假如纪录条数比较少,例如少于20条,这个时候,10个随机数,少于5个不重复的情况会很常见了。
SET @mid = (SELECT d.dataId, d.dataName, d.orgName FROM `data` d INNER JOIN datatopic dt ON d.dataId=dt.dataId INNER JOIN userTopic u ON u.topicId=dt.topicId WHERE u.userId=1234); -- 找出userid = 1234 的纪录数量 SET @cnt = 0; SELECT t.dataId, t.dataName, t.orgName FROM ( SELECT d.dataId, d.dataName, d.orgName, (@cnt := @cnt + 1) AS rid FROM `data` d INNER JOIN datatopic dt ON d.dataId=dt.dataId INNER JOIN userTopic u ON u.topicId=dt.topicId WHERE u.userId=1234 ) AS t WHERE rid IN ( FLOOR(1 + RAND() * @mid), FLOOR(1 + RAND() * @mid), FLOOR(1 + RAND() * @mid), FLOOR(1 + RAND() * @mid), FLOOR(1 + RAND() * @mid), FLOOR(1 + RAND() * @mid), FLOOR(1 + RAND() * @mid), FLOOR(1 + RAND() * @mid), FLOOR(1 + RAND() * @mid), FLOOR(1 + RAND() * @mid) ) LIMIT 0, 5