2011-01-21 11 views
35

Y por mejor que significan más eficiente, en este momento de colocar esto en mi archivo post.php es lo único que se me ocurre:¿Cuál es la mejor manera de contar vistas de página en PHP/MySQL?

$query = mysql_query(" UPDATE posts SET views + 1 WHERE id = '$id' "); 

hay una manera mejor, un método que consumiría menos recursos del servidor . Pregunto porque si se tratara de una aplicación pequeña no tendría ningún problema con lo anterior, pero estoy tratando de construir algo que sea utilizado por muchas personas y quiero ser lo más consciente posible de la consulta.

+0

Podría omitir PHP/MySQL y use archivos en su lugar. –

Respuesta

56

Si usted está interesado en la conservación de los recursos y dejar de utilizar SQL para la presentación de informes, y precisa # No importa, usted podría tratar de muestreo como esto (modificar la frecuencia de muestreo para adaptarse a su escala):

$sample_rate = 100; 
if(mt_rand(1,$sample_rate) == 1) { 
    $query = mysql_query(" UPDATE posts SET views = views + {$sample_rate} WHERE id = '{$id}' "); 
    // execute query, etc 
} 
+0

Dependiendo de qué tan grande sea "un montón de usuarios", puede ser beneficioso evitar MySQL en cualquier tabla que pueda ser larga. Una buena regla general es esta: * Si cualquier colección (tabla) puede superar los 10 millones de registros durante la vida útil de su aplicación, probablemente no deba almacenar esa colección en MySQL *. ¡Recomiendo investigar MongoDB y Membase antes de que sea demasiado tarde! –

+0

@dorkitude, ¿tiene más información/referencia para esta regla? Tenemos tablas en las decenas de miles de millones de filas sin problema. No digo que MongoDB/memcached no sea un buen recurso, solo me pregunto dónde podemos encontrar más información. – jasonbar

+0

Decenas de ** miles de millones ** en una tabla mysql? ¿Estas seguro de eso? –

2

Podrías mantener una matriz de contador en la memoria caché (como APC o Memcache) y aumentar el contador para ciertas publicaciones en eso. Luego, almacene las actualizaciones de vez en cuando. Puede perder algunas vistas si se produce un restablecimiento de caché

Otra solución sería mantener una tabla separada para visitas solamente (Campo: postid, visitas). Ese es el ayuno que puedes obtener de mysql. Intenta usar el motor InnoDB, ¡ya que proporciona un bloqueo de nivel de fila!

17

Si Memcache es una opción en el entorno de servidor, aquí hay otra manera fresca de la muestra, sino también mantenerse al día con el número preciso (a diferencia de mi otra respuesta):

function recordPostPageView($page_id) { 
    $memcache = new Memcached(); // you could also pull this instance from somewhere else, if you want a bit more efficiency* 

    $key = "Counter for Post {$page_id}"; 

    if(!$memcache->get($key)) { 
     $memcache->set($key, 0); 
    } 

    $new_count = $memcache->increment($key); 

    // you could uncomment the following if you still want to notify mysql of the value occasionally 
    /* 
    $notify_mysql_interval = 100; 
    if($new_count % $notify_mysql_interval == 0) { 
     $query = mysql_query("UPDATE posts SET views = {$new_count} WHERE id = '{$page_id}' "); 
     // execute query, etc 
    } 
    */ 

    return $new_count; 
} 
  • y no les importa puristas que gritan cosas desagradables sobre Singletons. O bien, podría pasarlo a esta función, si usted es más purista de lo pragmático :)
+0

configurando memcached y la confusión entre memcache y memcached a un lado, esta fue una solución extremadamente elegante y los resultados de la evaluación comparativa son muy felices también. Gracias por la increíble información. – Suyash

+0

Esto funciona perfectamente, como una mejora pasa el valor de recuento de la base de datos a la función como una variable adicional, luego use este valor para establecer la clave de Memcache. De esta forma, su contador permanece sincronizado (más o menos su valor de intervalo) si se reinicia Memcache. – paj

+0

@paj O simplemente podría descargar su Memcache en cada cronjob y comenzar de nuevo, solo sumando el conteo en el db usando count = count + memcache (getkey) – Suyash

6

mi humilde opinión, la mejor solución es tener views_count almacenado dentro de la memoria (memcached, lo que sea), y hacer cambios en la memoria. (Por supuesto, las actualizaciones deben estar sincronizadas)

Luego puede usar la secuencia de comandos cron que enviará esos valores a db. (después de un tiempo - segundos, minutos, lo que sea.)

3

también puede verificar estas líneas de código. Creo que será útil porque puedes lograr tu objetivo con solo un archivo tect. No requiere ninguna actividad de base de datos.

<?php 
 
session_start(); 
 
$counter_name = "counter.txt"; 
 
// Check if a text file exists. If not create one and initialize it to zero. 
 
if (!file_exists($counter_name)) { 
 
    $f = fopen($counter_name, "w"); 
 
    fwrite($f,"0"); 
 
    fclose($f); 
 
} 
 
// Read the current value of our counter file 
 
$f = fopen($counter_name,"r"); 
 
$counterVal = fread($f, filesize($counter_name)); 
 
fclose($f); 
 
// Has visitor been counted in this session? 
 
// If not, increase counter value by one 
 
if(!isset($_SESSION['hasVisited'])){ 
 
    $_SESSION['hasVisited']="yes"; 
 
    $counterVal++; 
 
    $f = fopen($counter_name, "w"); 
 
    fwrite($f, $counterVal); 
 
    fclose($f); 
 
} 
 
echo "You are visitor number $counterVal to this site";

2

en la base de datos no es sólo una columna ip con la clave primaria definida y luego tienda de IP en la base de datos utilizando el código PHP a continuación:

archivo de conexión:

<?php 
$conn = mysqli_connect("localhost","root",""); 
if (!$conn) { 
    die("Connection failed: " . mysqli_connect_error()); 
} 
$db=mysqli_select_db($conn,"DB_NAME"); 
if(!$db) 
{ 
    echo "Connection failed"; 
} 
?> 

Archivo PHP:

<?php 
$ip=$_SERVER['REMOTE_ADDR']; 
$insert="INSERT INTO `id928751_photography`.`ip` (`ip`)VALUES ('$ip');"; 
$result = mysqli_query($conn,$insert); 
?> 

espectáculo cuenta:

<?php 
$select="SELECT COUNT(ip) as count from ip;"; 
$run= mysqli_query($conn,$select); 
$res=mysqli_fetch_array($run); 
echo $res['count']; 
?> 

el uso de este método en la tienda de base de datos de todos los servidores IP

NOTA: sólo el ip del servidor puede almacenar o no contar IP del dispositivo

Cuestiones relacionadas