Ver Mensaje Individual
  #1 (permalink)  
Antiguo 03/11/2009, 21:22
Vehemente
 
Fecha de Ingreso: noviembre-2009
Mensajes: 5
Antigüedad: 14 años, 6 meses
Puntos: 0
Paginacion de noticias PHP/MySQL con ranking de registros

Hola! soy nuevo por acá y aunque en ocaciones el foro me ayudó a descubrir consultas o dudas sobre ciertos detalles de php o mysql, nunca había posteado porque no me había topado con ningún gran dilema... hasta hoy!

No se cuan avanzado o dificil será mi planteo, pero bueno, planteo la situación y a ver si alguno me ayuda con este embrollo!

Mis dilemas serían 2, aunque creo que podrían llegar a tener misma solución.

En una base de datos MySQL tengo determinada cantidad de registros (mas de 2000). Hasta ahora nada complejo.
Dichos registros son noticias que tienen un determinado orden para mostrarse, es decir, si bien todas las noticias tienen un campo ID, no son ordenadas por este valor, sino que cada una tiene grado de importancia y una posición particular (Imaginen un portal de noticias donde haya un cuadro principal que se muestran las noticias mas "destacadas" -posicion- y que a su vez esas noticias tienen un orden de acuerdo al interes del autor de la noticia de cual mostrar primera o segunda -importancia-). Esto lo aclaro principalmente para dejar en claro que la ID de los registros es usada solo para llamar a determinada noticia, pero nada tiene que ver con su orden de ingreso (La última noticia ingresada NO TIENE PORQUE ser la más importante o la que se quiera mostrar primero).
Hasta acá, nuevamente, viene todo en orden.

En el momento que hago la paginación, es el mismo orden sistemático que lo antes explicado, dicha paginación debe ordenarlas por posicion (de la 1 a la 5, donde la posicion 1 es mas importante y la 5 menos), por importancia (a,b,o c, mismo sentido que lo anterior) y al mismo tiempo por fecha y hora ingresadas (en el caso que dos noticias tengan misma importancia y posición, la mas nueva va primero... hablando en orden descendente). La paginación sería mas o menos con la siguiente estructura:

<< Primera Noticia | < Noticia Anterior | 1 - 2 - 3 - 4 - 5 | Siguiente Noticia > | Ultima Noticia >>

Y acá es donde empiezan a insultarse mis propias neuronas entre si.

Para obtener el link a la primera noticia no es tan grave: Hago una consulta SELECT que me traiga la primera noticia bajo un orden determinado y termino la consulta ahi mismo, sería algo como:

SELECT * FROM `noticias` ORDER BY `posicion`,`importancia`,`fecha_y_hora` DESC LIMIT 1

Al tener un campo que guarda la fecha y la hora, y al ser que los valores mínimos (por ejemplo, 1 - a) de "importancia" y "posicion" son los que me interesan primero, me resulta sencillo obtener el primer registro (o noticia) mas importante sabiendo tambien la ultima fecha y hora de ingreso. Luego el valor de la ID lo uso para crear el link.

El problema es con "ULTIMA NOTICIA", ya que si bien podria hacer un WHILE de la misma consulta de arriba (quitando el LIMIT), el loop terminaría dándome el último registro con su correspondiente ID, pero el problema serían los recursos, ya que si ya tengo 2000 registros (y cada vez son más), esa consulta podría ser terriblemente lenta para obtener esa última noticia.
En definitiva lo que pensé es la posibilidad que con MySQL se le pueda poner, un numero de "posicion" por asi decirlo, pudiendo obtener la última posición de acuerdo al ORDER BY que le indico, más allá de la ID que tengan cada una. Y por supuesto, obtener la ID de esa úlima posición.

Y ahora lo mas complejo, a mi entender (que no niego que sea escaso! :P), sería ese mismo posicionamiento en caso que no me encuentre ni en la primera ni en la ultima posición, ya que como indiqué arriba en la estructira de los links de paginación, tengo los números (1 - 2 - 3 - 4 - 5) que me indican el número de noticia (repito, orden de acuerdo al ORDER BY, no a la ID) y que si estoy en la noticia 3, debo saber cuales son las noticias 1, 2, 4 y 5 también, ya que debo generar un link que me lleve hasta ellas.

Nuevamente el problema es el mismo, los recursos del server, ya que estuve realizando pruebas y logro conseguir la posición con una funcion PHP, pero no logro como hacer para no tener que recorrer absolutamente toda la base para descubrir las ID de cada una para generar los links.
Asi sería como hice las pruebas:

function nums($id_nota) { // inicio funcion
$cuenta = 1;
$sql = mysql_query("SELECT * FROM `noticias` ORDER BY `posicion`,`importancia`,`fecha_y_hora` DESC");
while ($row = mysql_fetch_assoc($sql)) {
$idnota[$cuenta] = $row[id];
$cuenta++;
}

// Aca yo se que tengo mi primer error, ya que estoy armando un "ranking" pero estoy recorriendo toda la base (la variable $id viene de un llamado a funcion asi: nums($id); a la cual le envío la id de noticia que estoy, para saber (o intentar hacerlo) que posición tiene ESA ID y que ID's son las dos anteriores y las dos siguientes).
Luego hice un FOR mas o menos asi:

for ($count=1;$count<=count($idnota);$count++) {
if ($idnota[$count] == $id_nota) {
$count2 = $count - 2;
$count3 = $count - 1;
$count4 = $count + 1;
$count5 = $count + 2;
}
}

// A este FOR le faltan lineas que no vienen al caso para determinar si estoy en la noticia 1,2, 3 o en la que sea, donde en ese momento (si estoy en la noticia 4, por ejemplo), en lugar de querer saber las dos anteriores o las dos siguientes, serían las 3 anteriores y solo una siguiente (se entiende?)

$paginacion = '<a href="?id='.$idnota[$count2].'">1</a> | <a href="?id='.$idnota[$count3].'">2</a> | <strong>3</strong> | <a href="?id='.$idnota[$count4].'">4</a> | <a href="?id='.$idnota[$count5].'">5</a>';

// Acá les muestro la variable que devuelve el codigo html para armar esa numeración. Acá pueden ver porque resto y sumo valores a la variable "$count" para moverle la posicion a ese puntero y asi traer los valores de las ID guardadas en el arreglo "$idnota", y solo pongo en negrita el numero de la noticia que se esta viendo (ya que este ejemplo que presento, es en el caso que se vea la noticia 3... que en realidad puede ser la 546... pero bueno, creo que resolviendolo con esto ya esta solucionado el resto)

return $paginacion;

} // fin funcion


Puse todo esto para poder explicar a grandes rasgos el funcionamiento y como habia empezado a hacerlo, y es mas, esto FUNCIONA, el gran problema es el consumo de recursos del server, ya que como ven en el WHILE, recorro toda la base para darles las "posiciones de ranking" a las noticias y de ahi determinar cual posición estoy viendo y cuales debo guardar para armar los links.

Cerrando todo esto (wow, creo que por no haber posteado me guarde todo para esto!), mi consulta apunta a alguna forma, sentencia o funcion MySQL que me ayude con el tema de los recursos respetando el orden que le doy a la consulta sql, para armar esa especie de "ranking" que necesito para poder armar la paginación de las noticias. O tal vez alguna concatenación de querys, que no se me está ocurriendo.

Por favor, si lo que acabo de explicar es inentendible, aclarenmeló y trataré de explicarlo mejor, a ver si puedo conseguir alguna alma caritativa que me de una mano con esto o simplemente alguien con ganas de asumir el desafio y dolor de cabeza que esto representó para mi! :(

Desde ya, muchisimas gracias!!

Última edición por Vehemente; 03/11/2009 a las 21:50