我目前正在开发一个数据库广告轮播系统,其中一些广告比其他广告具有更高的印象(或排名),应该更频繁地展示。
在保持“随机”广告外观的同时计算展示排名的最佳方式是什么?数据库的表结构是什么样的?计算应该在数据库中还是在代码中完成?
答案 0 :(得分:2)
这是一个很好的解决方案,允许加权,它的coldfusion但sql也在那里 article
DECLARE @girl TABLE (
id INT IDENTITY( 1, 1 ),
name VARCHAR( 50 ),
weight INT
);
INSERT INTO @girl
(
name,
weight
)(
SELECT 'Sarah', 100 UNION ALL
SELECT 'Libby', 30 UNION ALL
SELECT 'Lisa', 30 UNION ALL
SELECT 'Molly', 250 UNION ALL
SELECT 'Kit', 50
);
SELECT
g.id,
g.name,
g.weight
FROM
@girl g
INNER JOIN
(
--
--In this inner query, we need to select a random,
--weighted ID. We are doing this in the inner query
--rather than in the outter query so that our
--intermediary table doesn't need to contain so
--much information (just the ID).
--->
SELECT TOP 1
g.id
FROM
@girl g
INNER JOIN
pivot1000 p
ON
(
-- Use the weights. --->
g.weight >= p.id
--Use any additional filtering that is required by the business logic of the query criteria.
AND
g.name != 'Lisa'
)
ORDER BY
-- Select random row. --->
NEWID() ASC
) AS temp_id
ON
g.id = temp_id.id
答案 1 :(得分:1)
一些可能有用的相关问题:
答案 2 :(得分:0)
我们已经为我们的开源广告服务器AdServerBeans MyAds(http://www.adserverbeans.com)编写了一个MySQL函数,该函数随机选择了一个考虑流量份额的横幅:
DELIMITER ;;
DROP FUNCTION if exists get_random_banner_by_traffic_share;
CREATE FUNCTION get_random_banner_by_traffic_share(valid_banners TEXT, total_traffic_share INTEGER)
RETURNS INTEGER
NOT DETERMINISTIC
BEGIN
DECLARE pos INTEGER DEFAULT 1;
DECLARE rnd INTEGER DEFAULT 0;
DECLARE current_traffic_share INTEGER DEFAULT 0;
DECLARE banner_id INTEGER;
DECLARE banner_traffic_share INTEGER;
SET rnd = RAND()*(total_traffic_share-1)+1;
WHILE pos < LENGTH(valid_banners) DO
SET pos = POSITION(';' IN valid_banners);
SET banner_id = CONVERT(SUBSTR(valid_banners,1,pos-1),SIGNED);
SET valid_banners=SUBSTRING(valid_banners FROM pos+1);
SET pos = POSITION(';' IN valid_banners);
SET banner_traffic_share = CONVERT(SUBSTR(valid_banners,1,pos-1),SIGNED);
SET valid_banners=SUBSTRING(valid_banners FROM pos+1);
if(current_traffic_share < rnd and rnd <= (banner_traffic_share+current_traffic_share)) THEN
RETURN banner_id;
END IF;
SET current_traffic_share=current_traffic_share+banner_traffic_share;
END WHILE;
END;
;;
delimiter ;
MySQL存储过程/函数不支持数组/列表。所以我们必须使用带分隔符的字符串。 在此功能中注意以下几行:
SET rnd = RAND()*(total_traffic_share-1)+1;
随机选择1到100之间的值。 然后,我们寻找该范围内的横幅。 请注意,此算法可能适用于针对同一广告位置的少量广告。你可能有不同的故事。