1 Востаннє редагувалося Master_Sergius (30.03.2016 10:16:51)

Тема: Зберігання в базі та обробка IP адрес

Отже, поки пишу цей пост, може й прийде якась розумна думка, інколи варто таки гарно сформулювати і записати, а якщо щей намалювати малюнок, то задача розв'язана на 50%.
Суть задачі:
користувач через свій інтерфейс може додавати айпішки в базу, позначаючи їх якимось описом - порносайти, айпішки "ворожого району", азартні ігри і так далі. Для економії місця, та й для перфомансу айпішки зберігаю проміжками, тобто замість 255 окремих записів із одним і тим же описом, можна зберегти одним записом: ххх.ххх.ххх.0/24
Цікавіше починається, коли деякі проміжки не можна зберегти одним записом, наприклад (айпішки носять лише демонстративний характер):

192.168.0.1 - 192.168.0.6

- тут є 7 айпішок, які можна зберегти наприклад, ось так:

192.168.1.1/32
192.168.1.2/31
192.168.1.4/31
192.168.1.6/32

Ну і звісно, ж у самій базі це все зберігається як числа (щоб нічого поганого не подумали :)), але суть та ж - кількість записів.
Таким чином, кількість записів зменшується майже вдвічі. Але ще цікавіше починається, коли при додаванні нової айпішки потрібно перевірити її присутність в базі. Як варіант - переводити айпішки в числа і навпаки (inet_aton, inet_ntoa - є методи у Python, та й в самому MySQL), ну і бавитися з порівняннями. А ще є пошук, фільтр і так далі. Вроді би і зробив, але все воно якось виходить не дуже гарно і дуже багато багів вилазить у моїй реалізації.
Я впевнений, що така задача уже поставала неоднократно десь раніше, і Я точно не перший, хто з цим стикнувся. Але, щось не вдається нічого доброго нагуглити. Ось, може хтось з Вас, шановні, порадить якісь алгоритми, приклади і так далі.

2

Re: Зберігання в базі та обробка IP адрес

Раз у вас можуть бути "некруглі" проміжки, то запис ххх.ххх.ххх.0/24 мені видається зайвим, я б зберігав початок і кінець діапазону. Більше того, мені здається, що у вас кінець діапазону обчислюється і так.

Подякували: koala, Master_Sergius2

3

Re: Зберігання в базі та обробка IP адрес

Формат "адреса/довжина маски" зручний тільки для ручного запису, "адреса/маска" - для бітовий операцій. У вас явно мають буті діапазони, причому для швидкості можна навіть зберігати адреси 32-бітними числами, а при виводі розбивати їх на байти.

Подякували: Master_Sergius1

4

Re: Зберігання в базі та обробка IP адрес

Так, панове, ви абсолютно праві, Я забув трішки уточнити ось це:

Ну і звісно, ж у самій базі це все зберігається як числа (щоб нічого поганого не подумали ), але суть та ж - кількість записів.

Тобто, маю число - адресу, число - маску, а також число - початок, число - кінець, та маску, а вже в інтерфейсі це відображається отим записом. Але, все одно це ще не допомагає вирішити всі проблеми.
Наприклад, при додаванні якогось проміжку, який кількома шматочками уже існує в базі, потрібно вставити лише ті шматочки не існуючі. Ось пошук дублікатів при такому збереженні трохи важкий.

5

Re: Зберігання в базі та обробка IP адрес

Можете уточнити задачу - користувачу треба буде видаляти зони, які він раніше додав, чи тільки редагувати поточний стан? Тобто, якщо у нас була позначена адреса xxx.xxx.xxx.10, а потім додався діапазон xxx.xxx.xxx.0-xxx.xxx.xxx.100 з такими самими ознаками, чи треба збергіати інформацію про xxx.xxx.xxx.10?

6

Re: Зберігання в базі та обробка IP адрес

koala написав:

Можете уточнити задачу - користувачу треба буде видаляти зони, які він раніше додав, чи тільки редагувати поточний стан? Тобто, якщо у нас була позначена адреса xxx.xxx.xxx.10, а потім додався діапазон xxx.xxx.xxx.0-xxx.xxx.xxx.100 з такими самими ознаками, чи треба збергіати інформацію про xxx.xxx.xxx.10?

В такому випадку,  xxx.xxx.xxx.10 залишається, як і був, додаються лише xxx.xxx.xxx.0-xxx.xxx.xxx.9, та xxx.xxx.xxx.11-100. Бо ще має значення таймстемп додавання, та й ще додаткова перевірка на однакові ознаки - зайвий геморой (що як ознак буде багато?)

7

Re: Зберігання в базі та обробка IP адрес

Чому ви вставляєте ще один проміжок, а не розширюєте існуючий?

8

Re: Зберігання в базі та обробка IP адрес

Master_Sergius, ви не відповіли на моє запитання.

9

Re: Зберігання в базі та обробка IP адрес

quez написав:

Чому ви вставляєте ще один проміжок, а не розширюєте існуючий?

Ще раз: тому, що потрібно тоді буде бавитися ще й з ознаками, а їх кількість може рости, і робити додаткову перевірку по 5-и ознакам уже буде зайвим, як на мене (навіть якщо хоча би одна ознака відрізняється, то розширювати не можна).

koala написав:

Master_Sergius, ви не відповіли на моє запитання.

Чому ж не відповів? З прикладом відповів - додаються нові записи. Редагувати можна лише коли напряму викликати метод редагування, а при додаванні проміжку який перекриває старий проміжок, то старий проміжок повинен лишитися без змін.

10

Re: Зберігання в базі та обробка IP адрес

А я не питав, як ви робите, я питав, як вам треба. Якщо вас влаштовує те, що маєте - то нащо питаєте тут? Якщо ні - то спробуйте все ж відповісти на моє питання.

11

Re: Зберігання в базі та обробка IP адрес

koala написав:

А я не питав, як ви робите, я питав, як вам треба. Якщо вас влаштовує те, що маєте - то нащо питаєте тут? Якщо ні - то спробуйте все ж відповісти на моє питання.

1. Треба зберігати інформацію про старі записи і однакових адрес в базі бути не повинно.
2. Те, що маю майже влаштовує. Не влаштовує лиш реалізація.
3. Тому думав, може є хоч певний набір схожих задач/алгоритмів і т.д. і т.п. Може з них можна взяти щось і використати в себе.

На жаль, викласти код не можу, тому й запитую про існуючі схожі задачі. Шаримо ідеї :)

12

Re: Зберігання в базі та обробка IP адрес

Ці вимоги формально не суперечливі, але їхня комбінація вам заважає. Треба:
- або відмовитися від недублювання, тоді все буде просто елементарно, хоча записів буде трохи більше, ніж мало б бути;
- або відмовитися від старої інформації (чи позначати її як стару і зробити індекс по цій ознаці). Це, до речі, логічно - якщо у вас зараз є запис "192.168.0.100 - порно", а ви хочете переписати його на "192.168.0.100 - азартна гра", то ваша система відмовиться приймати такий запит, бо ця адреса вже є в діапазоні.
Тоді треба буде створити процедуру, що визначатиме перетини нового діапазону зі старими, видалятиме (які зможе) старі і збільшуватиме новий, щоб він охоплював і старі, і нові.

Подякували: Master_Sergius1

13

Re: Зберігання в базі та обробка IP адрес

Теоретично, доданих ІР-адрес не буде занадто багато. Чому б просто їх не додавати у varchar(15) з кластерним індексом? Хоча можна спробувати й з числовими значеннями зробити кластерний складений індекс.

Якщо гратись із проміжками... кажете в двічі зменшується об’єм? Не думаю що це дасть помітні вигоди, але майже напевно додасть проблем.

14

Re: Зберігання в базі та обробка IP адрес

koala написав:

- або відмовитися від старої інформації (чи позначати її як стару і зробити індекс по цій ознаці). Це, до речі, логічно - якщо у вас зараз є запис "192.168.0.100 - порно", а ви хочете переписати його на "192.168.0.100 - азартна гра", то ваша система відмовиться приймати такий запит, бо ця адреса вже є в діапазоні.

Для цього випадку, є окрема кнопочка - редагування та відповідний метод в API, тому, ця проблема вирішується.
Але загалом, зауваження слушні.

15

Re: Зберігання в базі та обробка IP адрес

ktretyak написав:

Теоретично, доданих ІР-адрес не буде занадто багато. Чому б просто їх не додавати у varchar(15) з кластерним індексом? Хоча можна спробувати й з числовими значеннями зробити кластерний складений індекс.

Якщо гратись із проміжками... кажете в двічі зменшується об’єм? Не думаю що це дасть помітні вигоди, але майже напевно додасть проблем.

По-моєму, індексація по числах ефективніше. Ну і коли об'єм зменшується вдвічі, а коли і в 256 разів :)

16

Re: Зберігання в базі та обробка IP адрес

Теоретично таких ІР-адрес буде максимум пару тисяч, а це ніщо для кластерного індекса.

17

Re: Зберігання в базі та обробка IP адрес

ktretyak написав:

Теоретично таких ІР-адрес буде максимум пару тисяч, а це ніщо для кластерного індекса.

Ну, як сказати... В цій базі весь інтернет :)
Там є ще багато цікавих речей, що як і куди, про які не можу розповісти, таємниця і все таке.