Ver Mensaje Individual
  #4 (permalink)  
Antiguo 03/06/2011, 11:29
leif_sk8er
 
Fecha de Ingreso: junio-2009
Mensajes: 309
Antigüedad: 14 años, 10 meses
Puntos: 5
Respuesta: IPV6 y IPV4 en campo INT

He hecho una prueba de ver cuanto ocupan 50 millones de registros en la estructura del primer mensaje de este hilo, usando el campo IP como varchar (128). El resultado es que ocupa 4,9 Gb.

Por otro lado acabo de hacer una prueba con una posible solucion que he encontrado. Consiste en que el campo IP sea decimal (39,0) unsigned. La misma cantidad de registros (50 millones) ocupan 2.6 Gb, es decir, practicamente la mitad....

Como he pasado una IP4 o IP6 a decimal? He usado un par de funciones que he encontrado, tb pongo la que devuelve de nuevo a la cadena IP original:

Código PHP:
Ver original
  1. function inet_ptod($ip_address)
  2. {
  3.     // IPv4 address
  4.     if (strpos($ip_address, ':') === false && strpos($ip_address, '.') !== false) {
  5.     $ip_address = '::' . $ip_address;
  6.     }
  7.     // IPv6 address
  8.     if (strpos($ip_address, ':') !== false) {
  9.     $network = inet_pton($ip_address);
  10.     $parts = unpack('N*', $network);
  11.     foreach ($parts as &$part) {
  12.     if ($part < 0) {
  13.     $part = bcadd((string) $part, '4294967296');
  14.     }
  15.     if (!is_string($part)) {
  16.     $part = (string) $part;
  17.     }
  18.     }
  19.     $decimal = $parts[4];
  20.     $decimal = bcadd($decimal, bcmul($parts[3], '4294967296'));
  21.     $decimal = bcadd($decimal, bcmul($parts[2], '18446744073709551616'));
  22.     $decimal = bcadd($decimal, bcmul($parts[1], '79228162514264337593543950336'));
  23.     return $decimal;
  24.     }
  25.     // Decimal address
  26.     return $ip_address;
  27. }
  28. /**
  29.  * Convert an IP address from decimal format to presentation format
  30.  *
  31.  * @param string $decimal An IP address in IPv4, IPv6 or decimal notation
  32.  * @return string The IP address in presentation format
  33.  */
  34. function inet_dtop($decimal)
  35. {
  36.     // IPv4 or IPv6 format
  37.     if (strpos($decimal, ':') !== false || strpos($decimal, '.') !== false) {
  38.     return $decimal;
  39.     }
  40.     // Decimal format
  41.     $parts = array();
  42.     $parts[1] = bcdiv($decimal, '79228162514264337593543950336', 0);
  43.     $decimal = bcsub($decimal, bcmul($parts[1], '79228162514264337593543950336'));
  44.     $parts[2] = bcdiv($decimal, '18446744073709551616', 0);
  45.     $decimal = bcsub($decimal, bcmul($parts[2], '18446744073709551616'));
  46.     $parts[3] = bcdiv($decimal, '4294967296', 0);
  47.     $decimal = bcsub($decimal, bcmul($parts[3], '4294967296'));
  48.     $parts[4] = $decimal;
  49.     foreach ($parts as &$part) {
  50.     if (bccomp($part, '2147483647') == 1) {
  51.     $part = bcsub($part, '4294967296');
  52.     }
  53.     $part = (int) $part;
  54.     }
  55.     $network = pack('N4', $parts[1], $parts[2], $parts[3], $parts[4]);
  56.     $ip_address = inet_ntop($network);
  57.     // Turn IPv6 to IPv4 if it's IPv4
  58.     if (preg_match('/^::\d+.\d+.\d+.\d+$/', $ip_address)) {
  59.     return substr($ip_address, 2);
  60.     }
  61.     return $ip_address;
  62. }


Bueno, eso ahorra la mitad.... Es un buen paso no?, se podrá ahorrar todabia mas?? Parece mentira como un solo campo en solo 50 millones hace que algo ocupe el doble...