Toto je původní verze internetového fóra ISPforum.cz do února 2020 bez možnosti registrace nových uživatelů. Aktivní verzi fóra naleznete na adrese https://telekomunikace.cz

SQL řazení dle IP s maskou

RADIUS, CAPsMAN, The Dude, AirControl, UniFi, Zabbix atd.
Uživatelský avatar
svestka
Příspěvky: 1423
Registrován: 14 years ago
antispam: Ano

SQL řazení dle IP s maskou

Příspěvekod svestka » 5 years ago

Máme vlastní systém postavený na PHP+MySQL a řešíme jednu věc ...

Seznamy IP adres řadíme ... "ORDER BY INET_ATOM(IP)" což ale nefunguje dobře s maskou, která je občas bohužel součástí sloupce "ip" a občas je zase zvlášť. No jako u debilů :)

Nemáte na to někdo vychytanou fci v PHP, které předám pole, které je směsicí IP a IP/maska a ona si s tím poradí?
třeba
192.168.1.20
192.168.1.3
192.168.1.16/30

Díky.
0 x
UPDATE klienti SET internet_povolen = false WHERE po_splatnosti > 500
Lepší než výhra ve Sportce :)

cerva
Příspěvky: 254
Registrován: 9 years ago

Příspěvekod cerva » 5 years ago

Kód: Vybrat vše

$arr = array("192.168.1.20", "192.168.1.3", "192.168.1.16/30");
natsort($arr);
print_r($arr);

Array
(
    [1] => 192.168.1.3
    [2] => 192.168.1.16/30
    [0] => 192.168.1.20
)


Systemove ale je samozrejme drzet homogenitu dan v jednom sloupci : )
0 x

Uživatelský avatar
hapi
Příspěvky: 12989
Registrován: 16 years ago

Příspěvekod hapi » 5 years ago

no jo ale to ty data musíš nejdřív načíst a až pak srovnat. V případě že to je složitější zápis tak musíš vracet data zpět to mysql.

Nebylo by lepší mít na subnet solo sloupec? můžeš ho používat na sortování a pak mít v selectu třeba "SELECT CONCAT(ip, '/', subnet) As address" a ten ukazovat.
1 x
Supermicro + Mikrotik = SuperTik
high speed routery podle požadavků

Uživatelský avatar
Myghael
Příspěvky: 1309
Registrován: 12 years ago

Příspěvekod Myghael » 5 years ago

V naší aplikaci to přesně tak máme, v jednom sloupci IP, v druhém subnet. Pokud chci uložit jen jednu IP adresu, prostě se zadá 32 (jakože /32). Tady ty přepočty ale obstarává PHP část. Má to tu výhodu, že se s tím výborně počítá a navíc se to dá naprosto stejně použít pro IPv4 i IPv6.

Doporučil bych tedy přidat sloupec pro subnet a pak už je to o skriptu, který v každém řádku vezme tu adresu jako string a hledá v ní "/" (lomítko). Pokud nenajde, uloží subnet 32 a adresu nechá být. Pokud najde, uloží adresu samotnou a číslo za lomítkem uloží jako subnet (doporučuji přidat ověření, že tam nebude třeba /48 pro IPv4 a podobně), případně provede přepočet, pokud za tím lomítkem najde třeba 255.255.255.0 - přesně takový skript někde mám, jen ty řádky načítá z textového souboru namísto databáze (používal se při importu do databáze) - jestli ho najdu, hodím ho sem. Vrchol efektivity to není, ale na jednorázový import (případně občasný úklid) vyhovuje.
0 x
Si vis pacem, para bellum.

MikroTik, UBNT, Cisco, TP-Link... rozhoduje vhodnost toho či onoho pro konkrétní použití, ne jaké logo nalepili v Číně na krabici. Na tomto fóru vystupuji jen a pouze sám za sebe.


Uživatelský avatar
Myghael
Příspěvky: 1309
Registrován: 12 years ago

Příspěvekod Myghael » 5 years ago

Vskutku, ale dotaz byl na MySQL.
0 x
Si vis pacem, para bellum.

MikroTik, UBNT, Cisco, TP-Link... rozhoduje vhodnost toho či onoho pro konkrétní použití, ne jaké logo nalepili v Číně na krabici. Na tomto fóru vystupuji jen a pouze sám za sebe.

ludvik
Příspěvky: 4448
Registrován: 12 years ago

Příspěvekod ludvik » 5 years ago

Pravdu má předřečník - každý sloupec v DB má být takový, aby už nešel rozdělit. Tak jako se blbě třídí (a vlastně i prohledává) sloupec JMENO_PRIMENI, stejně blbý je způsob IP/MASKA.
Čili bych v prvé řadě přistoupil k oddělení těchto informací.
No a po oddělení je dobré si uvědomit, že maska k IP adrese uživatele prostě nepatří. Ta patří segmentu, kam je připojen. Čili je to vazba k evidenci něčeho jiného - třeba síťového rozhraní routeru.

Třídění podle funkce nebude zrovna optimální. IP adresa je prostě číslo - zapisovat do DB jeho prezentační tvar je většinou hloupost. Od toho jsou číselné typy.
0 x
Jelikož je zde zakázáno se negativně vyjadřovat k provozním záležitostem, tak se holt musím vyjádřit takto: nové fórum tak jak je připravováno považuji za cestu do pekel. Nepřehledný maglajz z toho bude. Do podpisu se mi pozitiva již nevejdou.

cerva
Příspěvky: 254
Registrován: 9 years ago

Příspěvekod cerva » 5 years ago

ludvik píše:Pravdu má předřečník - každý sloupec v DB má být takový, aby už nešel rozdělit. Tak jako se blbě třídí (a vlastně i prohledává) sloupec JMENO_PRIMENI, stejně blbý je způsob IP/MASKA.
Čili bych v prvé řadě přistoupil k oddělení těchto informací.
No a po oddělení je dobré si uvědomit, že maska k IP adrese uživatele prostě nepatří. Ta patří segmentu, kam je připojen. Čili je to vazba k evidenci něčeho jiného - třeba síťového rozhraní routeru.

Třídění podle funkce nebude zrovna optimální. IP adresa je prostě číslo - zapisovat do DB jeho prezentační tvar je většinou hloupost. Od toho jsou číselné typy.

Přesně tak, jediné správné řešení je dodržovat při návrhu DB databázové formy (https://cs.wikipedia.org/wiki/Normalizace_databáze). Na druhou stranu není vždy efektivní měnit DB model už existujícího systému, pokud potřebujeme jen nějakou jednorázovou drobnost navíc - pak bych se klonil klidně k použití toho natsort(). Používání specifického datového typu na uložení IP adresy zní jako fajn nápad - pokud se v budoucnu nebude řešit migrace mezi DB (třeba MariaDB -> Postgress).
1 x

Uživatelský avatar
k3dt
Příspěvky: 44
Registrován: 12 years ago

Příspěvekod k3dt » 5 years ago

IP urcite ukladat jako int unsigned a masku zvlast.. usetrite si hodne starosti i nejakej ten vykon.

ale muzete to vyprasit pres:

Kód: Vybrat vše

ORDER BY INET_ATON(SUBSTRING_INDEX(segment,'/',1))
1 x

Uživatelský avatar
svestka
Příspěvky: 1423
Registrován: 14 years ago
antispam: Ano

Příspěvekod svestka » 5 years ago

k3dt píše:IP urcite ukladat jako int unsigned a masku zvlast.. usetrite si hodne starosti i nejakej ten vykon.

ale muzete to vyprasit pres:

Kód: Vybrat vše

ORDER BY INET_ATON(SUBSTRING_INDEX(segment,'/',1))


Vypraseno ... funguje ... diky.
0 x
UPDATE klienti SET internet_povolen = false WHERE po_splatnosti > 500
Lepší než výhra ve Sportce :)