2013-08-03 76 views
0

我在MySQL中有一个GeoIP表。 IP范围用BINARY(16)定义。 当我仰望的IP地址与查询:MySQL截断不正确的DOUBLE值?

SELECT `countries_countryID` FROM `geoIP` WHERE INET_ATON("84.224.199.84") BETWEEN `geoIP`.`ipFrom` AND `geoIP`.`ipTo` LIMIT 1; 

我得到的警告消息(20-30000),他说:"Truncated incorrect DOUBLE value: '17498112\x00\x00\x00\x00\x00\x00\x00\x00'"

表:

DROP TABLE IF EXISTS `geoIP` ; 

CREATE TABLE IF NOT EXISTS `geoIP` (
    `geoIPID` INT NOT NULL AUTO_INCREMENT , 
    `IPFrom` BINARY(16) NOT NULL , 
    `IPTo` BINARY(16) NOT NULL , 
    `countries_countryID` INT NOT NULL , 
    PRIMARY KEY (`geoIPID`) , 
    INDEX `fk_geoIP_countries1_idx` (`countries_countryID` ASC) , 
    INDEX `IPTo_INDEX` (`IPTo` ASC) , 
    INDEX `IPFrom_INDEX` (`IPFrom` ASC) , 
    CONSTRAINT `fk_geoIP_countries1` 
    FOREIGN KEY (`countries_countryID`) 
    REFERENCES `countries` (`countryID`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION) 
ENGINE = InnoDB; 

的结果是正确的,国家代码被正确地返回,但是有这些警告消息。哪里不对?

+1

为什么使用'二进制'的IP地址?对于IPv6? –

+0

它使用较少的空间,后来我也会实现IPv6,这需要BINARY(16)。 –

+0

Inet_aton返回一个int,然后您在两个二进制文件之间使用它。令人惊讶的是,即使说实话,我也会期待它吹大块。看起来你需要做一些IPFrom和To的转换 –

回答

0

如果你打算将IPv6和IPv4存储在同一个字段中,那么你应该在表定义中使用VARBINARY(16)而不是BINARY(16)。这将删除警告。

在MySQL的BINARY字段(很像CHAR字段)是固定的宽度,并且是正确填充的。您可以在警告中看到填充。比较结果在DOUBLE(IP)和1/2(BINARY)(16)之间进行比较,截取右半部分。这就是为什么你会收到警告。

http://dev.mysql.com/doc/refman/5.0/en/binary-varbinary.html

相关问题