Sal*_*ali 13 ip-address mongodb
目前为了保存IP地址,我将其转换为数字并将其存储在集合中.基本上我这样做是为了记录日志.这意味着我尽可能快地存储信息并且空间最小.
我很少用它来查询.
我的想法
尽管如此,我认为这是一个适当的方法,但是有一个更好的方法吗?
Mar*_*ase 11
绝对将IP地址保存为数字,如果你不介意它需要额外的工作,特别是如果你需要对地址进行查询并且你有大型表/集合.
原因如下:
存储
对于字符,这是7-15个字节,如果您使用的是可变长度字符串类型,则会增加2-3个字节,这取决于您正在使用的数据库.如果您有可用的固定长度字符串表示,则必须使用15个字符的固定宽度字段.
磁盘存储很便宜,因此在大多数用例中并不是一个因素.但是,内存并不便宜,如果你有一个大型表/集合并且想要快速查询,那么你需要一个索引.字符串编码的2-3x存储代价大大减少了您可以索引的记录数量,同时仍保持索引驻留在内存中.
在低端,循环地址(:: 1)是3个字节加上可变长度字符串开销.在高端,一个地址2002:4559:1FE2:1FE2:4559:1FE2:4559:1FE2使用39个字节加上可变长度的字符串开销.
与IPv4不同,假设平均IPv6字符串长度为6和42的平均值是不安全的,因为具有大量连续零的地址数量只占整个IPv6地址空间的很小一部分.只有一些特殊地址(如loopback和autoconf地址)可能以这种方式可压缩.
同样,对于字符串编码与整数编码,这是一个> 2x的存储损失.
网络数学
您认为路由器将IP地址存储为字符串吗?当然他们没有.
如果您需要对IP地址进行网络数学运算,则字符串表示很麻烦.例如,如果要编写一个搜索特定子网上所有地址的查询("返回IP地址在10.7.200.104/27中的所有记录"),则可以通过使用整数子网掩码屏蔽整数地址来轻松完成此操作. (Mongo不支持这个特定的查询,但是大多数RDBMS都这样做.)如果你将地址存储为字符串,那么你的查询需要将每一行转换为一个整数,然后屏蔽它,这要慢几个数量级.(按位)使用2个寄存器可以在几个CPU周期内完成对IPv4地址的屏蔽.将字符串转换为整数需要在字符串上循环.)
类似地,使用整数地址的范围查询("返回所有记录在192.168.1.50和192.168.50.100之间的所有记录")将能够使用索引,而字符串地址上的范围查询则不能.
底线
它需要更多的工作,但不多(有一百万aton()和ntoa()函数在那里),但如果你正在构建一些严肃而坚实的东西,并且你希望将来证明它符合未来的要求和大数据集的可能性,您应该将IP地址存储为整数,而不是字符串.
如果你正在做一些快速和肮脏的事情,并且不介意将来重塑的可能性,那么使用字符串.
对于OP的目的,如果您正在优化速度和空间并且您认为不想经常查询它,那么为什么要使用数据库呢?只需将IP地址打印到文件即可.这比将其存储在数据库中具有更快且更高的存储效率(具有相关的API和存储开销).
| 归档时间: |
|
| 查看次数: |
8612 次 |
| 最近记录: |