Como ahorro espacio en la base de datos?

Iniciado por Skeletron, 10 Febrero 2010, 23:36 PM

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

^Tifa^

SI jujub si ya se hablo de las posibles colisiones de CRC32  ;) despues de 4 billones de entradas  de ahi surgio las recomendaciones de funciones externas y links que le referi para descargarselas. Pero creo que Skeletrum le busco la vuelta ya a este dilema.

Si yo fuese Skeletrum, usase procedimientos almacenados para reemplazar valores por cosas fijas como http y www.

Skeletron

#31
Tifa, te respondo:
Ahora que me doy cuenta, tampoco es necesario hacerlo con otra tabla en la base de datos...
Con PHP puedo hacerlo.. con la funcoin REPLACE.
Digamos que, cuando la web quiera X link, en base a esos 3 hash, supongamos que la sentencia devuelve 2 links.
Antes de "imprimirlos" con el ECHO (php), paso al link a una variable, la cual le aplico todas las REGLAS DE PRODUCCION, pero de manera INVERSA a como se guardaron en la base de datos.

Por ejemplo, si uso las sigueintes reglas:
www. se transforma en ----> |1
.com ------> |2

En mi indexador, al encontrar el link: www.google.com, luego de aplicarle esas 2 reglas de produccion, quedaría:
|1google|2
..

Luego, cuando en la web, luego de una sentencia SELECT, me devuelve ese link: |1google|2, con la funcion reemplace de PHP, haría ésto:
$link=replace("|1","www.",$link);
$link=replace("|2",".com",$link);
LISTO, la varible $LINK, tendría el siguiente valor: www.google.com
Imprimo $link dentro de un campo de link:
<a href="$link" >link</a>
Y el link, queda perfecto..

Digamos que en Conclusión:
AUMENTO EL TIEMPO de procesamiento en CPU por el reemplazo.
DISMINUYO EL TIEMPO de espera de los resultados de la 2 sentencia(que me traería los valores para reemplazar)
DISMINUYO EL ESPACIO utilizado en la base de datos.

En cuanto a lo de las situaciones constantes Tifa, te digo que no estoy al tanto (es mas, SOY MUY EXTREMADAMENTE NOVATO EN ESTO).. Pero por tu ejemplo, debe ser mas de lo mismo que hablo yo.. simplemente que tu lo implementeas en la base de datos. y yo estoy creando como FILTROS desde PHP

Advertencia - mientras estabas escribiendo, una nueva respuesta fue publicada. Probablemente desees revisar tu mensaje.


PD.: Cuales creen que son las palabras mas utilizadas en links? las que seguro estaran escritas miles de veces en la base de datos...??

^Tifa^

datos constantes son datos fijos tu sabes, asi como puedo decir un campo de longitud constante es un campo que si defines su longitud 20 espacio ocupara esos 20 espacios aunque tu le insertes una informacion de 10 espacios  :xD

SI suponia que podia implementar todo eso del reemplazo en el codigo PHP, solo que yo te lo sugeri como procedimiento almacenado dentro del Motor MySQL, pero eso mismo que expones para PHP fue lo mismo que sugeria pero para un procedimiento almacenado  :xD  creo que es mas comodo de esta forma que crear varias tablas ciertamente.

Sobre eso de palabras repetidas y como se llaman, no hay un nombre... la longitud del campo que guarda este dato puede ser constante (CHAR por ejemplo) sin embargo quien condiciona si el dato se repite o no es si tu declaras este campo como una llave primaria o como un indice unique. Fuera de esto si declaras dicho campo como index o key seran indices pero podran repetirse.

Skeletron

#33
Vuelvo a joderlos: Creo que tengo la solucion

Que pasa si en vez de colocar en CODIGO, el resultado del MD5 del LINK, coloco: el resultado del CRC32 del link y el CRC32 de la concatenacion de los numeros que hay en la columna HASH1, HASH2, y HASH3?



Lean ésto por favor:
Mi tabla, se llama: IMGS, que contiene los siguientes campos:
CODIGO << aqui se guardaba el crc32 o el md5
LINK << aca hay links SOLAMENTE DE IMAGENES.. SOLAMENTE!!
HASH1 << aca se guardala cantidad de color ROJO que tiene la imagen
HASH2 << aca se guarda la cantidad de color VERDE que tiene la imagen
HASH3 << aca se guarda la cantidad de color AZUL que tiene la imagen

Ahora bien.. Mi indexador, tiene en otra base de datos, LINKS de IMAGENES A PROCESAR.
Mi indexador toma de esa base de datos (que esta en mi PC) 1 link.
Descarga ese link, mira la cantidad de colores que tiene (analizando los pixeles) y hace al final:
INSERT INTO imgs (codigo, link, hash1, hash2, hash3) VALUES ('XXXXXXXX', 'www.google.com/logo.jpg', '123', '912', '465');

OK?? se entiende?

Bien.. El problema, es QUE GUARDAR EN CODIGO? ese fue nuestro problema desde que empezamos con ésta idea..
Pues bien, se me ocurrió algo genial!
Guardar ahí, en el campo CODIGO, el resultado de 2 crc32 concatenados.. para así aumentar a 2^64 la longitud de los resultados, y disminuir MUCHISIMO la posibilidad de coliciones.
Cuales serían los 2 CRC32 a calcular?
1º: el crc32 del LINK
2º, el CRC32 de HASH1HASH2HASH3

Porque digo que sería bueno?
Supongamos que 2 link de imagenes, son TOTALMENTE DIFERENTES, ejemplo:
A = www.noel.com/foto.jpg
B = www.foro.com/foto.jpg
Pero, ambos links, aplicandole el CRC32, devuelven el mismo resultado (COLICION), el cual es: 123456789

Problema: Al querer agregar estos links, uno de los 2 no se agregará, ya que el que ingrese primero, no permitirá al 2º entrar, porque el campo CODIGO (que posee hasta el momento 1 solo CRC32 del LINK) tienen el MISMO VALOR DE CRC32.

PERO!, esas 2 imagenes, son TOTALMENTE DIFERENTES (obviamente), entonces sus valores de HASH1, HASH2, y HASH3, TAMBIEN!, ya que contienen diferentes cantidades de colores en cada pixel.

Supongamos:
A = www.noel.com/foto.jpg | HASH1=123 | HASH2=234 | HASH3=345
B = www.foro.com/foto.jpg | HASH1=567 | HASH2=678 | HASH3=789
En este caso, si en CODIGO, colocamos los 2 CRC32, de ésta manera:
CODIGO=CRC32='www.noel.com/foto.jpg'CRC32='123234345'

LA UNICA MANERA de dar la COLICION, sería que el CRC32 de los 2 links SEAN IGUALES, y el CRC32 de los valores CONCATENADOS que hay en HASH1, HASH2, y HASH3, TAMBIEN DEVUELVAN EL MISMO VALORRR!!!...
SERÍA EXTREMADAMENTE MUCHA CASUALIDAD!!!!!


Todo funcionaría perfectamente.. PORQUE?
Porque si es EL MISMO LINK, entonces, los valores de los 3 HASH, SERAN IGUALES TAMBIEN. ya que es la misma imagen, por ENDE, los valores serían iguales tanto en el resultado del CRC32 del link como el de CRC32 de los hash. Y NO SE INGRESARÍA EL LINK, por duplicidad en la KEY PRIMARIA.

Que pasa si 2 imagenes son iguales, COPIAS, pero estan guardadas en 2 webs diferentes.. entonces, tendrán el mismo CRC32 de sus HASHES, pero diferentes en el CRC32 de su link (a no ser que se de una colicion ahí, pero las probabilidades son casi nulas)


Que ventaja tiene ésto?
La Key sería SOLAMENTE de NUMEROS, de una longitud de 20, (si mal no recuerdo, CRC32 devuelve un numero de HASTA 10 sifras), y con esa longitud, no habrá casi coliciones. Disminuiré mucho el peso de la base de datos, ya que el MD5 tiene 32 caracteres de longitud. y el indice será solo de NUMEROS... :D

Habra muchas coliciones por los links, pero el 2º crc32, hará la diferencia :)

Y si 20 carateres, es poco para evitar coliciones, entonces, podria concatenar 3 crc32, por ejemplo, del LINK, del 1º y 2º HASH y del 3º HASH

QUE ME DICEN?

^Tifa^

Honestamente... aunque se lea cruel, yo poco te puedo ayudar en esta logica presentada  :xD  la razon? soy extremadamente mala, mediocre, pesima cuando se me presenta algun tema donde me hablen de numeros y funciones matematicas.

No quiero decirte una tonteria, y a lo mejor este equivocada (que tengo mas fe que si) pero... si sacas el CRC32 de los 3 indices y lo concatenas esto en que diferenciaria en que saques 1 solo CRC32 de 1 indice??  :huh:  o sea.. CRC32 su maximo seran 4 billones de entradas perfecto, que haras tu cuando concatenes 3 convertisiones CRC32 de 3 indices... si despues que pase de 4 billones habra colision???  :huh:  si hubiese algun bucle o algo que diga que despues de 4 billones de entradas pos se le sume un numero extra al final ya es otro asunto que podria ser valido y evitar colisiones....

Pero hay otro dilema  :-\  si se hace lo del bucle.. como se usaria el indice CRC32 si cuando digas traeme el link donde el hash1 = 'www.google.com'  por ejemplo.... el retornaria nada porque el valor de la ultima cifra fue generada por un contador  :-X

Repito puedo estar diciendo una tonteria.. los numeros efectivamente no se hicieron para mi  :D

Skeletron

#35
Pero TIFA!, CONCATENAR, significa poner al lado 2 numeros.. pegados...
serán 2 numeros de hasta 4 millones pegados al lado.. será un numero entonces desde 00 hasta 42949672964294967296

(CRC32 de LINK)   UNIDO/PEGADO A (CRC32 de (hash1 unido a hash2 unido a hash3))
Si (CRC32 de LINK) = 123456
y
CRC32 de (hash1 unido a hash2 unido a hash3) = 456456456
El numero a ingresar en CODIGO, será: 123456456456456

Ejemplo:

INSERT INTO imgs (codigo, link, hash1, hash2, hash3) VALUES (crc32='http://foto.com/foto.jpg'crc32='456123678';, 'http://foto.com/foto.jpg';, '456', '123', '678')
Da error porque no se como concatenar los resultados de los 2 crc32===== crc32='http://foto.com/foto.jpg'crc32='456123678'

Ejecuta esa sentencia

^Tifa^

Perdoname.... te decia que los calculos y los numeros me vuelven un ocho .... es como que me hablasen chino o japones...

Pero si estas seguro que funcionara.. puedes concatenar mas de 2 valores usando  ||

Algo asi como:

INSERT INTO TABLA VALUES(CRC32=campo1||CRC32=campo2||CRC32=campo3||'123'||'456');

:P