2009-09-15 10 views
1

Je travaille actuellement sur un système de rotation de la base de données où certaines annonces ont une plus forte impression (ou rang) que d'autres et devraient être montrées plus souvent. Quelle est la meilleure façon de calculer le classement des impressions tout en conservant l'apparence des publicités "aléatoires"? À quoi ressemblerait la structure de la table pour la base de données? Le calcul doit-il être effectué dans la base de données ou dans le code?Calcul du classement de l'impression d'annonces

+0

Rien, dessinant encore sur le papier. Mais je suis coincé à travailler sur la façon de calculer le rang. – janhartmann

Répondre

2

ici est une excellente solution qui permet de pondération, son coldfusion mais le sql est là aussi 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 
0

Nous avons écrit une fonction MySQL pour notre serveur publicitaire open source AdServerBeans MyAds (http://www.adserverbeans.com) qui sélectionne une bannière prenant au hasard en actions de trafic de compte:

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 procédures/fonctions stockées ne supporte pas les tableaux/listes. Nous avons donc dû utiliser une chaîne avec des délimiteurs. Dans cette fonction faites attention à la ligne:

SET rnd = RAND()*(total_traffic_share-1)+1; 

qui sélectionne au hasard une valeur de 1 à 100. Nous examinons ensuite la bannière qui se trouve dans cette fourchette. Notez que cet algorithme est probablement correct pour une petite quantité d'annonces ciblant le même emplacement d'annonce. Vous pourriez avoir une histoire différente.