Foros del Web » Programando para Internet » PHP »

se satura mysql?

Estas en el tema de se satura mysql? en el foro de PHP en Foros del Web. Hola a todos, tengo un pequeño problema con una consulta a una base de datos mysql con php. pasa lo siguiente tengo una tabla de ...
  #1 (permalink)  
Antiguo 11/12/2003, 19:59
 
Fecha de Ingreso: agosto-2003
Ubicación: Tampico Tamaulipas
Mensajes: 54
Antigüedad: 14 años, 4 meses
Puntos: 0
se satura mysql?

Hola a todos, tengo un pequeño problema con una consulta a una base de datos mysql con php.
pasa lo siguiente

tengo una tabla de datos con dos columnas (fecha y click)
la columna fecha es tipo "date" y la columna click es tipo "int"

hago una consulta a la base de datos para saber si existe un registro, en este caso para saber si existe la fecha actual, si no existe crea el registro con la fecha actual y le da el valor al campo click de "1", si ya existe entonces actualiza solo el campo click incrementandole una unidad, la condicion la hago con un "if" de php
el código es el siguiente
Código PHP:
// ESTO ES PARA SABER SI EXISTE UN REGISTRO CON LA FECHA ACTUAL
$resultados mysql_query("SELECT fecha FROM estadisticas WHERE fecha = CURDATE() ",$conexion);

// SI EXISTE ACTUALIZA
if(mysql_num_rows($resultados) > 0){
    
mysql_query("UPDATE estadisticas SET click = click + 1 WHERE fecha = CURDATE() ",$conexion);
}
else{ 
// SI NO EXISTE LO CREA
    
mysql_query("INSERT INTO estadisticas (fecha,click) VALUES (CURDATE(),1)",$conexion);

Trabaja correctamene, pero hay días que me duplica regsistros, es decir, como si no encontrara un registro aunque este exista.

He llegado a pensar que probablemente se sature el motor de base de datos y mientras está atendiendo alguno el otro que hace la petición no lo encuentra por estar ocupado y duplica el registro, en fin, solo es una teoría mía

Alguien me podría orientar en este caso


Saludos.


Nota: Es un contador de visitas sencillo

Última edición por matcruz; 11/12/2003 a las 20:02
  #2 (permalink)  
Antiguo 12/12/2003, 06:39
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 15 años, 11 meses
Puntos: 126
Lo más optimo para hacer una consulta a tu BD para ver si X condición se cumple (ej. exite el registro bajo la condición que usas WHERE ....) es usar COUNT() de Mysql para que -sólo- te entrege Msyql el resultado en un único campo el total de coincidencias de tu condicional " .. WHERE ..." de tu consulta SQL.

La función mysql_num_rows() de PHP .. "cuenta" el total de registros de una consulta dada .. pero con la consulta hecha .. así que esto es útil cuando muestras esos datos y -ademas- quieres contar el total. Pero, sólo para saber el total es más óptimo hacerlo por SQL directamente con COUNT() ya que sólo generas un "recordset" con ese dato del total .. La cuenta en sí de registros se la trabaja Mysql integramente.

En tu caso ..sería algo así:

Código PHP:
$resultados mysql_query("SELECT COUNT(*) FROM estadisticas WHERE fecha = CURDATE() ",$conexion);

// SI EXISTE ACTUALIZA
if(mysql_result($resultados,0) > 0){
//etc ... 
Por el tema de los problemas "aleatorios" que tienes .. no sé que decirte. Tendrías que estudiar "que" datos son los que se repiten por si hay problemas tal vez con los tipos de campo .. Supongo que si usas CURDATE() será por qué usas un campo tipo fecha "DATE" (no datetime)?

Un saludo,
__________________
Por motivos personales ya no puedo estar con Uds. Fue grato haber compartido todos estos años. Igualmente los seguiré leyendo.
  #3 (permalink)  
Antiguo 12/12/2003, 07:00
Ex Colaborador
 
Fecha de Ingreso: junio-2002
Mensajes: 9.091
Antigüedad: 15 años, 5 meses
Puntos: 16
Hola,

Esos problemas de "duplicidad" lo podrias solucionar poniendo el campo fecha como clave primaria o indice unico, para no permitir duplicados.

Posiblemente tu problema ahora es que entre el momento que realizas el SELECT hasta el momento que haces el INSERT, otro script ha realizado el INSERT, con lo que estas haciendo 2 INSERT. Graficamente:

script1 hace el SELECT
script1 recibe que no hay registros
script2 hace el SELECT
script2 recibe que no hay registros
script1 hace INSERT
script2 hace INSERT

La ejecucion de una consulta si es atomica, pero no se garantiza que no se ejecuten otras consultas entre dos consultas del mismo script. Podrias bloquear la tabla con LOCK antes del SELECT.

Pero yo creo que la mejor forma es sin realizar el conteo previo. Realizas directamente el INSERT. Si la fecha (que es calve primaria o indice unico) existe, mysql_query() devolvera error de "clave duplicada". En ese caso realizas el UPDATE. El ejemplo anterior quedaria:

script1 hace el INSERT correctamente
script2 hace el INSERT, pero devuelve error
script2 hace el UPDATE

Como cada consulta es atomica, solo se ejecutara correctamente el primer INSERT que llege, el resto fallara. Y al fallar ejecutarian el UPDATE.

Esto en MySQL 4.1 se puede hacer esto en una sola SQL (INSERT ... ON DUPLICATE KEY ...) (http://www.mysql.com/doc/en/INSERT.html), pero para versiones anteriores seria algo asi:
Código PHP:
$el_error_de_clave_duplicada=123// no es este. Habria que buscar en el manual
$result=mysql_query("INSERT .... ");
if (!
$result && $el_error_de_clave_duplicada==mysql_errno()) {
  
// si el error es calve duplicada
  
mysql_query("UPDATE ....");
} else {
  
// el error no es clave duplicada
  
echo "error";

Espero haber sido de ayuda.

Suerte.
__________________
Josemi

Aprendiz de mucho, maestro de poco.
  #4 (permalink)  
Antiguo 12/12/2003, 21:00
 
Fecha de Ingreso: agosto-2003
Ubicación: Tampico Tamaulipas
Mensajes: 54
Antigüedad: 14 años, 4 meses
Puntos: 0
Hola Cluster y josemi, gracias por contestar y por su ayuda

Primero optimizé la consulta como me lo indico cluster, haciendo un solo recorset con la funcion COUNT() de mysql para ver si era mas rápido el proceso, pero no me fué de mucha utilidad, y pues respondiendo a lo que me preguntabas sobre el campo si era tipo "date" para utilizar la función CURRENT() pues sí, es tipo "date"

bueno pues al final de cuentas opté por utilizar el método que me indicó josemi y lo tengo a prueba actualmente, y es haciendo el campo UNICO y asi evitar duplicados y actualizando el registro existente
Código PHP:
//QUEDO DE ESTA FORMA PORQUE EL MYSQL ES VERSION 4.0
if(!mysql_query("INSERT INTO estadisticas (fecha,click) VALUES (CURDATE(),1)",$conexion))
    
mysql_query("UPDATE estadisticas SET click = click + 1 WHERE fecha = CURDATE() ",$conexion); 

Bueno, Gracias a los dos por su tiempo


Saludos
  #5 (permalink)  
Antiguo 13/12/2003, 23:07
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 15 años, 11 meses
Puntos: 126
En Mysql 4.0 e inferiores puedes "bloquear" una tabla para una secuencia de INSERT o SELECT y UPDATES o más INSERT's entre otras cosas. De esta forma generas lo que llaman una "Transacción" .. que significa que .. hasta que no se ha completado la última instrucción SQL que tienes en tu "transacción" .. no se libera tu tabla para hacer más INSERT o SELECT incluso (depende de que nivel ve bloqueo hagas).

http://www.mysql.com/doc/en/ANSI_diff_Transactions.html
http://www.mysql.com/doc/en/LOCK_TABLES.html

Un saludo,
__________________
Por motivos personales ya no puedo estar con Uds. Fue grato haber compartido todos estos años. Igualmente los seguiré leyendo.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 07:21.