Detecting an IPv6 address in PHP and storing it properly in MySQL. How?

后端 未结 2 606
无人及你
无人及你 2021-01-06 07:30

I read a few of the questions already asked, and i found this to be useful, although i have no tried it Working with IPv6 Addresses in PHP

Still, say i have a \'bans

相关标签:
2条回答
  • 2021-01-06 08:03

    I was searching for the best data type in mysql to use for storing an ipv6 address recently. I have found no good reason to use a VARCHAR(), only good reasons NOT to.

    I did some performance testing with the BINARY(16), two BIGINT UNSIGNED, and DECIMAL data types.

    I've created the following tables, populated with 2,000,000 random ip address from 100 random networks.

    CREATE TABLE ipv6_address_binary (
        id SERIAL NOT NULL AUTO_INCREMENT PRIMARY KEY,
        addr BINARY(16) NOT NULL UNIQUE
    );
    
    CREATE TABLE ipv6_address_twobigints (
        id SERIAL NOT NULL AUTO_INCREMENT PRIMARY KEY,
        haddr BIGINT UNSIGNED NOT NULL,
        laddr BIGINT UNSIGNED NOT NULL,
        UNIQUE uidx (haddr, laddr)
    );
    
    CREATE TABLE ipv6_address_decimal (
        id SERIAL NOT NULL AUTO_INCREMENT PRIMARY KEY,
        addr DECIMAL(39,0) NOT NULL UNIQUE
    );
    

    Then I SELECT all ip addresses for each network and record the response time. Average response time on the twobigints table is about 1 second while on the binary table it is about one-hundredth of a second.

    Here are the queries.

    Note:

    X_[HIGH/LOW] is the most/least significant 64-bits of X

    when NETMASK_LOW is 0 the AND condition is omitted as it always yields true. doesn't affect performance very much.

    SELECT COUNT(*) FROM ipv6_address_twobigints
    WHERE haddr & NETMASK_HIGH = NETWORK_HIGH
    AND laddr & NETMASK_LOW = NETWORK_LOW
    
    SELECT COUNT(*) FROM ipv6_address_binary
    WHERE addr >= NETWORK
    AND addr <= BROADCAST
    
    SELECT COUNT(*) FROM ipv6_address_decimal
    WHERE addr >= NETWORK
    AND addr <= BROADCAST
    

    Average response times:

    Average response times

    BINARY_InnoDB  0.0119529819489
    BINARY_MyISAM  0.0139244818687
    DECIMAL_InnoDB 0.017379629612
    DECIMAL_MyISAM 0.0179929423332
    BIGINT_InnoDB  0.782350552082
    BIGINT_MyISAM  1.07809265852
    
    0 讨论(0)
  • 2021-01-06 08:06

    Still, say i have a 'bans' table in MySQL. How would i go about storing the IPv6 address?

    You can store it in a simple column of VARCHAR(40).
    Considering a sample IPv6 max is 40 byte:

    2001:0DB8:0000:0000:0000:0000:1428:57ab 
    

    That coulmn will be able to contain IPv4 too

    0 讨论(0)
提交回复
热议问题