我们已经有了一个健康的辩论本周在办公室继续。 我们要创建一个DB存储代理的信息,我们的模式制定,除了我们应该如何存储IP地址的大部分。 一个阵营希望利用4个smallints,每一个字节,其他想要使用1个大INT,INET_ATON。
这些表都将是巨大的所以性能是关键。 我在中间这里我通常在我的世界里使用MS SQL和4个个小整数。 我没有这种类型的存储容量的IP地址足够的经验。
我们将使用Perl和Python脚本来访问数据库,以进一步规范数据到其他几个表顶级健谈,有趣交通等
我相信有一些在这里已经做了simular以我们正在做的社会,我听到他们的经验很感兴趣,并且路线是最好的,1个大int或4个个小整数的IP地址。
编辑 -一个值得关注的地方是空间,这个数据库将是巨大的像5亿记录的日子。 因此,我们正试图与性能问题一起权衡空间的问题。
编辑2的一些谈话已经上交的数据,我们将存储卷......这不是我的问题。 问题是,这是存储的IP地址以及为什么可取的方法。 就像我在我的意见已经说过了,我们的一大笔财富50强公司工作。 我们的日志文件中包含从我们的用户使用数据。 这些数据反过来将安全上下文中可以用来驱动一些指标和推动了一些安全工具。
我建议在看着你将要运行什么类型的查询来决定你采用哪一种格式。
只有当你需要拔出或比较各个八位字节,你会怎么考虑它们拆分成单独的领域。
否则,将其存储为一个4字节的整数。 这也有让您使用内置的MySQL的奖金INET_ATON()
和INET_NTOA()
函数。
性能与空间
存储:
如果你只打算支持IPv4地址,那么你在MySQL数据类型可以是UNSIGNED INT
只使用4个字节的存储空间。
要存储单个八位字节你只需要使用UNSIGNED TINYINT
数据类型,不SMALLINTS
,这会占用每1个字节存储空间。
这两种方法都将使用类似的存储与可能稍微多为一些开销不同的领域。
更多信息:
- 数值类型概述
- 整型(精确值) - INTEGER,INT,SMALLINT,TINYINT,MEDIUMINT,BIGINT
性能:
使用单场将产生更好的性能,这是比较单一的,而不是4.你提到你将只能运行针对整个IP地址查询,所以应该没有必要继续八位位组分开。 使用INET_*
MySQL的功能将用于比较做一次文字和整数表示之间的转换。
甲BIGINT
是8
以字节为单位MySQL
。
为了储存IPv4
地址,一个UNSINGED INT
是不够的,我认为这是你使用768,16什么。
我无法想象这样一个场景, 4
个字节会比单一获得更多的性能INT
,而后者是方便多了。
还要注意的是,如果你要发出这样的疑问:
SELECT *
FROM ips
WHERE ? BETWEEN start_ip AND end_ip
其中start_ip
和end_ip
是你的表列,性能会很差。
这些查询使用,以找出是否一个给定的IP
是一个子网范围(通常禁止它)内。
为了使这些查询效率,应该在整个范围内存储为LineString
与对象SPATIAL
上的索引和查询是这样的:
SELECT *
FROM ips
WHERE MBRContains(?, ip_range)
见我的博客这个条目就如何做到这一点更详细:
使用PostgreSQL,有一个本地数据类型为。
更为严重的是,我会陷入“一个32位整数”阵营。 一个IP地址才有意义,当所有四个八位字节一起考虑,所以没有理由在单独的列八位字节存储在数据库中。 你会使用存储三个(或更多)不同领域的电话号码?
拥有独立的领域不健全,特别懂事,我 - 就像一个分裂邮编段或电话号码。
如果你想在部分特定的信息,但我没有看到真正的理由不使用32位的int可能是有用的。
知识产权的高效转化为int和int到IP(可能是对你有用):(PERL)
sub ip2dec {
my @octs = split /\./,shift;
return ($octs[0] << 24) + ($octs[1] << 16) + ($octs[2] << 8) + $octs[3];
}
sub dec2ip {
my $number = shift;
my $first_oct = $number >> 24;
my $reverse_1_ = $number - ($first_oct << 24);
my $secon_oct = $reverse_1_ >> 16;
my $reverse_2_ = $reverse_1_ - ($secon_oct << 16);
my $third_oct = $reverse_2_ >> 8;
my $fourt_oct = $reverse_2_ - ($third_oct << 8);
return "$first_oct.$secon_oct.$third_oct.$fourt_oct";
}