Как сохранить IP в MySQL

Обычно существует два типа хеш-таблиц: откройтесь и закрытый.

В открытой хеш-таблице Вы находите правильный блок на основе хеша, и затем создаете список объектов, зависающих от того блока.

В закрытой хеш-таблице Вы находите начальный блок с помощью значения хэш-функции, и если это занято, Вы зондируете для следующего значения. В упрощенном случае можно сделать это путем поиска следующего свободного блока, или можно создать второе значение хэш-функции из объекта и ступить тем (хотя необходимо удостовериться, что это главное по модулю размер хэш-таблиц, таким образом, Вы посетите все блоки).

открытая хеш-таблица обычно не изменяется. Вы устанавливаете начальный размер, чтобы быть тем, что Вы чувствуете, разумно для проблемы. Поскольку другие указали, что Вы могли изменить размеры на открытой хеш-таблице, но обоснование о производительности этой структуры данных теперь становится очень трудным. Если Вы изменяете размеры, когда длина данного блока является L тогда, Вы могли бы заканчивать тем, что изменили размеры на просто L объекты в целой хеш-таблице, которая очень неэффективна.

А закрылся, хеш-таблица изменена когда коэффициент загрузки (нет. из объектов в хеш-таблице / нет. из блоков), поражает некоторое предопределенное значение. Я склонен использовать 80%, но точное значение вряд ли будет слишком очень важно.

преимущество закрытой хеш-таблицы - то, что амортизировал , стоимость вставки объекта всегда O (1) (принятие хорошей хеш-функции). Вставка конкретного объекта могла бы быть O (N) из-за стоимости изменения размеров, но это делается очень нечасто.

24
задан BoltClock 27 February 2011 в 13:57
поделиться

5 ответов

Я бы посоветовал посмотреть, какие типы запросов вы будете выполнять, чтобы решить, какой формат вы выберете.

Только если вам нужно вытащить или сравните отдельные октеты, если бы вам пришлось рассмотреть возможность их разделения на отдельные поля.

В противном случае сохраните его как 4-байтовое целое число. Это также дает возможность использовать встроенные в MySQL функции INET_ATON () и INET_NTOA () .

Производительность vs. пространство

Хранилище:

] Если вы собираетесь поддерживать только адреса IPv4, тогда вашим типом данных в MySQL может быть UNSIGNED INT , который использует только 4 байта памяти.

Для хранения отдельных октетов вам нужно будет использовать только ] UNSIGNED TINYINT типов данных, а не SMALLINTS , которые будут использовать по 1 байту каждого хранилища.

Оба метода будут использовать одинаковое хранилище, возможно, немного больше для отдельных полей для некоторых накладных расходов.

Дополнительная информация:

Производительность:

Использование одного поля даст гораздо лучшую производительность, это одно сравнение вместо 4. Вы упомянули, что вы будете выполнять запросы только для всего IP-адреса, поэтому необходимости в этом не должно быть. держите октеты отдельно. Использование функций MySQL INET _ * выполнит преобразование между текстовым и целочисленным представлениями один раз для сравнения.

MEDIUMINT, BIGINT

Производительность:

Использование одного поля даст гораздо лучшую производительность, это одно сравнение вместо 4. Вы упомянули, что вы будете выполнять запросы только для всего IP-адреса, поэтому необходимости в этом не должно быть. держите октеты отдельно. Использование функций MySQL INET _ * выполнит преобразование между текстовым и целочисленным представлениями один раз для сравнения.

MEDIUMINT, BIGINT

Производительность:

Использование одного поля даст гораздо лучшую производительность, это одно сравнение вместо 4. Вы упомянули, что вы будете выполнять запросы только для всего IP-адреса, поэтому необходимости в этом не должно быть. держите октеты отдельно. Использование функций MySQL INET _ * выполнит преобразование между текстовым и целочисленным представлениями один раз для сравнения.

24
ответ дан 28 November 2019 в 23:34
поделиться

Мне кажется, что отдельные поля не имеют особого смысла - во многом как разделение почтового индекса на разделы или телефонный номер.

Может быть полезно, если вам нужна конкретная информация по разделам, но Я не вижу реальной причины не использовать 32-битное int.

1
ответ дан 28 November 2019 в 23:34
поделиться

A BIGINT - это 8 байтов в MySQL .

Для хранения IPv4 адресов, UNSINGED INT достаточно, и я думаю, это то, что вы должны использовать.

Я не могу представить сценарий, в котором 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)

См. эту запись в моем блоге для получения более подробной информации о том, как это сделать:

14
ответ дан 28 November 2019 в 23:34
поделиться

Используйте PostgreSQL, для этого есть собственный тип данных .

Более серьезно, я бы попадают в лагерь "одного 32-битного целого". IP-адрес имеет смысл только тогда, когда все четыре октета рассматриваются вместе, поэтому нет причин хранить октеты в отдельных столбцах в базе данных. Вы бы сохранили номер телефона, используя три (или более) разных поля?

3
ответ дан 28 November 2019 в 23:34
поделиться

Эффективное преобразование ip в 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";
}
0
ответ дан 28 November 2019 в 23:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: