buscar en una gran cantidad de datos (php/txt)

Iniciado por nat_chan07, 11 Enero 2010, 20:47 PM

0 Miembros y 1 Visitante están viendo este tema.

nat_chan07

hola
ojalá me puedan ayudar con mi problemita

Lo que pasa es que estoy haciendo un programa que lee unos datos en un archivo de texto y funciona todo perfecto al probarlo con un documento de 4000 lineas del txt (como 700kb) (el cual entero tiene más de 4 millones de lineas y pesa 500mb aprox).

El problema es que cada vez que realizo una busqueda el programa lee todo el txt y da una respuesta y no puedo estar cargando el archivo de 500mb cada vez que quiero buscar 1 numero.

necesito que el documento de texto quede guardado en el buffer o algo y poder realizar busquedas en ese mismo txt varias veces hasta que lo desee cambiar o terminé la "session".

N4X

no se si entendí... pero lo guardas en una variable de session y fin del asunto  :o

~ Yoya ~

Ps, creo que no hay otra alternativa, leerá siempre el texto o si tu le especificas una linea para leer solo cuya linea, de lo contrario primero leerá todo y luego hará la búsqueda. Es como un buscador, primero almacena todo y luego devuelve los resultados que coinciden.
Mi madre me dijo que estoy destinado a ser pobre toda la vida.
Engineering is the art of balancing the benefits and drawbacks of any approach.

[u]nsigned

Podes usar fgets y leer linea por linea hasta encontrar lo que necesitas extraer de dicho archivo. Pero si este 'scritp' tuyo lo vas a usar en un servidor web.. :P

Yo mejor te diria que busques la forma de pasar tu monstruoso .txt a una BB.DD  :)

Saludos

No hay atajo ante la duda, el misterio se hace aquí...
Se hace carne en cada uno, el misterio es existir!

Nakp

si no quieres depender de un servidor para la BBDD usa sqlite que es mas rápido inclusive... u ordena el archivo y usa algún algoritmo de búsqueda como la binaria (solo funciona con un número estático de datos y ordenados, es la mas rápida)
Ojo por ojo, y el mundo acabará ciego.

WHK

Cuando dices cargar el texto a memoria y esas cosas se me viene a la mente que quieres hacer una especie de caché y cargar una sola ves el texto para no tener que andarlo abriendo a cada rato.
En ese caso puedes almacenar el .txt en un .php donde cada linea es $linea[] = ''; después si quieres buscar algo le haces un foreach y esperar hasta el 2012 para que te resuelva lo que necesitas o inicie el script.

Por defecto en un servidor no puedes cargar todo un archivo de golpe a memoria o a una variable debido a que php tiene una configuración con el limite de memoria permitido para ejecutarse y generalmente no supera los 2mb asi que cuando quieres cargar tu super archivo el loop que vas a hacer con la busqueda te lo va a mandar al carajo.

Lo que tu necesitas es una base de datos como toda la gente que hace trabajos normales, las bases de datos en access y txt son para datos pequeños, mysql, sqlite son para trabajos normales como los que tu quieres.

^Tifa^

Pasalo todo a una base de datos, ya que la base de datos posee su propio Buffer cache para manipular data y indices(dependiendo el motor de almacenamiento) el cual puedes manipular su tamanio. Ademas de otras ventajas que haran menos forzosas tantas entradas y salidas del disco de un archivo TXT.

Si tu archivo TXT tiene por ejemplo datos de este estilo:

marian, rodriguez
pedro, gomez
mario, perez
juana, mejia
coco, channel
pepe, lopez

Y tu quieres transportar todo a MySQL por ejemplo, sencillamente creas una tabla para acaparar la informacion anterior, que son nombres y apellidos:

CREATE TABLE ejemplo ( nombres CHAR(15), apellidos CHAR(15))

Y luego a importar :D

Código (sql) [Seleccionar]


mysql> select * from ejemplo;
Empty set (0.00 sec)

mysql> load data local infile '/home/marian/archivo.txt' into table ejemplo fields terminated by ',';
Query OK, 6 rows affected (0.00 sec)
Records: 6  Deleted: 0  Skipped: 0  Warnings: 0

mysql> select * from ejemplo;
+---------+-----------+
| nombres | apellidos |
+---------+-----------+
| marian  |  sanchez  |
| pedro   |  gomez    |
| mario   |  perez    |
| juana   |  mejia    |
| coco    |  channel  |
| pepe    |  lopez    |
+---------+-----------+
6 rows in set (0.00 sec)



Donde FIELDS TERMINATED BY indica donde vas a especificar que se corte la data para pasar la subsiguiente al proximo campo  ;)

Ademas con una DB y datos pasados, podras crear indices , relacionarlos, etc, etc...

WHK

CitarCREATE TABLE ejemplo ( nombres CHAR(15), apellidos CHAR(15))

Y si tiene un usuario o cliente que se llame
María De las mercedes ozas Riquelme
xDDDD son 20 carácteres, por eso siempre ese tipo de campos para evitar errores y dar mas flexibilidad las declaro de tipo text.

^Tifa^

Que crimen... un tipo TEXT para un nombre...  :rolleyes:  pobre optimizador del motor.

Bueno fijate, puede ocurrir eso que especificas, pero si previamente uno conoce la longitud de algo (nombres, apellidos, telefono, etc) datos alfanumericos, con esto previamente uno puede decidir que tipo de datos utilizar, CHAR solo ocupa 1 byte en memoria por caracter, VARCHAR ocupa 2 bytes por caracter ademas de que este ultimo desfragmenta mucho, TEXT por el otro lado me parece haber leido que es un tipo de dato constante como CHAR (No lo afirmo pero me parece que vi que era asi, lo confirmo manana) Y si esto realmente es asi... eso quiere decir que ya que TEXT soporta 65,400 mas o menos de bytes (cantidad de caracteres maximo en total) y recuerda que TEXT no se le puede indicar hasta que longitud almacenar ya que por defecto el almacena hasta su maxima cantidad (En este caso 65,400 mas o menos) esto quiere decir, que si tu insertas 1 nombre de 20 caracteres.. el te ocupara los bytes restantes (65,380) de ceros (Justo como hace CHAR) que son datos constantes, y si esto realmente es asi, asumo no tendras problemas en que tu datafile crezca masivamente con inserciones simples  :xD (Espero que tengas mucha capacidad de disco duro para este impacto)

Por mas largo que sea un nombre, no superaria los 50 o 60 bytes (nombre no apellido). Me fio de CHAR por ser constante, por no desfragmentarse, y para datas alfanumericas menores que 255 va de lujo. Pero TEXT es un crimen usar TEXT para esos tipos de registros.

Nakp

Cita de: ^TiFa^ en 13 Enero 2010, 05:35 AM
Bueno fijate, puede ocurrir eso que especificas, pero si previamente uno conoce la longitud de algo (nombres, apellidos, telefono, etc) datos alfanumericos

no es la primera vez que lo mencionas xD pero me pregunto como sabes la longitud de un nombre u apellido para generalizar?

si defines char(15) por defecto se usarán los 15 bytes aunque ingrese 'a' y varchar usaría la cantidad de letras + 1 byte siempre que la columna no sobrepase los 255 caractéres, así que si usa char(50) o varchar(50) y se introduzca un nombre de 25 caracteres queda mejor parado varchar pues usaría 26 bytes en cambio char usaría los 50
Ojo por ojo, y el mundo acabará ciego.