Thread: Есть ли такая возможность
Привет всем. Есть ли возможность по сетевому типу inet проверить вхождение адреса для СПИСКА значений inet? Т.е. есть некий IP адрес: xxx.xxx.xxx.xxx Есть также таблица сетей CREATE TABLE nets_tbl ( id SERIAL PRIMARY KEY, netname CHAR(10), net INET UNIQUE ); в которой забито несколько значений например: SELECT * FROM nets_tbl; id | name | net ----+--------+------------------ 13 | perm | 195.222.128.0/19 14 | perm | 62.16.32.0/19 15 | perm | 195.42.134.0/24 Мне надо сделать запрос, который бы позволил мне сказать, входит ли IP адрес xxx.xxx.xxx.xxx в любую из сетей, которая соответствует имени 'perm'. Напрашивается такой вариант: SELECT * FROM nets_tbl WHERE 'xxx.xxx.xxx.xxx' IN (SELECT net FROM nets_tbl WHERE name='perm'); Однако, такой запрос всегда будет выдавать 0 записей, т.е. совпадения никогда не будет, если только значение в поле net не точно такое же как и у xxx.xxx.xxx.xxx. Это вроде бы понятно почему - надо сравнение делать с помощью функций, предназначенных для этого типа. Ищу такую функцию и нахожу "<<", но она работает только для единичных значений, т.е. SELECT * FROM nets_tbl WHERE 'xxx.xxx.xxx.xxx' << (SELECT net FROM nets_tbl WHERE id=13); работать будет, а вот: SELECT * FROM nets_tbl WHERE 'xxx.xxx.xxx.xxx' << (SELECT net FROM nets_tbl WHERE name='perm'); нет, потому что: ERROR: more than one row returned by a subquery used as an expression Но мне бы хотелось сравнить значение именно со списком! КАК? -- С уважением, Виктор
Viktor Vislobokov wrote: > Привет всем. > Есть ли возможность по сетевому типу inet проверить вхождение адреса для > СПИСКА значений inet? > Т.е. > > есть некий IP адрес: xxx.xxx.xxx.xxx > > Есть также таблица сетей > > CREATE TABLE nets_tbl ( > id SERIAL PRIMARY KEY, > netname CHAR(10), > net INET UNIQUE > ); > > в которой забито несколько значений например: > SELECT * FROM nets_tbl; > id | name | net > ----+--------+------------------ > 13 | perm | 195.222.128.0/19 > 14 | perm | 62.16.32.0/19 > 15 | perm | 195.42.134.0/24 > > Мне надо сделать запрос, который бы позволил мне сказать, входит ли IP > адрес xxx.xxx.xxx.xxx в любую из сетей, которая соответствует имени 'perm'. > > Напрашивается такой вариант: > SELECT * FROM nets_tbl WHERE 'xxx.xxx.xxx.xxx' IN (SELECT net FROM > nets_tbl WHERE name='perm'); > > Однако, такой запрос всегда будет выдавать 0 записей, т.е. совпадения > никогда не будет, если только значение в поле net не точно такое же как > и у xxx.xxx.xxx.xxx. Это вроде бы понятно почему - надо сравнение делать > с помощью функций, предназначенных для этого типа. Ищу такую функцию и > нахожу "<<", но она работает только для единичных значений, т.е. > > SELECT * FROM nets_tbl WHERE 'xxx.xxx.xxx.xxx' << (SELECT net FROM > nets_tbl WHERE id=13); > > работать будет, а вот: > > SELECT * FROM nets_tbl WHERE 'xxx.xxx.xxx.xxx' << (SELECT net FROM > nets_tbl WHERE name='perm'); > > нет, потому что: > ERROR: more than one row returned by a subquery used as an expression > > Но мне бы хотелось сравнить значение именно со списком! КАК? А может это просто чрезмерное увлечение вложенными запросами? :) SELECT * FROM nets_tbl WHERE 'xxx.xxx.xxx.xxx' << net AND name='perm' ; -- Mykola Dzham, LEFT-(UANIC|RIPE) JID: levsha@jabber.kiev.ua
>>Но мне бы хотелось сравнить значение именно со списком! КАК? >> >> > >А может это просто чрезмерное увлечение вложенными запросами? :) > >SELECT * FROM nets_tbl WHERE 'xxx.xxx.xxx.xxx' << net AND name='perm' ; > > > Вот что бывает, когда пытаешься упросить задачу для объяснения. ;) Всё сложнее, поэтому (на мой взгляд) и понадобился список. Я сильно упростил задачу, чтобы дать понять, что я хочу. В итоге получил более рациональное и правильное решение, но увы не применимое в моём случае, а только в том случае, который я описал. Ладно попробуем снова, теперь по полной программе: Есть таблица тафика: CREATE TABLE traffic_tbl ( id SERIAL PRIMARY KEY, tdate DATE, src_ip INET NOT NULL, src_port INT, dst_ip INET NOT NULL, dst_port INT, size INT4 NOT NULL ); где полный трафик Есть таблица сетей: CREATE TABLE nets_tbl ( id SERIAL PRIMARY KEY, name VARCHAR(40) NOT NULL, net INET NOT NULL ); В этой таблице есть ряд записей про пермские сети и ряд записей про IP адреса сетевых интерфейсов компьютера alpha Хочу получить данные о всём пермском трафике, исходящем с компьютера alpha по всем сетевым интерфейсам в некую таблицу results_tbl: INSERT INTO results_tbl (month, year, note, size) VALUES(4,2005,'Пермский исходящий трафик с alpha', (SELECT sum(size) FROM traffic_tbl WHERE src_ip IN (SELECT net FROM nets_tbl WHERE name='alpha') AND dst_ip __________IN__________ (SELECT net FROM nets_tbl WHERE name='perm'))); Вот там где ______IN________ очень бы хотелось сравнить со списком. Как сделать подругому - я не знаю, ибо не очень силён в SQL. -- С уважением, Виктор
Здравствуйте, Viktor Vislobokov! Я думаю что могу немного помочь в этом вопросе. Насколько я понял задача стоит разделения трафика на типы, в моём слечаее это был мир/украина. Тоже сначала думал всё пихать в БД, но это очень дорого обходится, как в объёмах так и в обработке. И решил что лучше всего брать fprobe(не из Debian) и ставить flow-tools и писать соответствующие скрипты. А в базу складывать уже результаты, например раз в полчаса. Скриптами могу поделиться. On Mon, Jul 04, 2005 at 03:33:12PM +0600, you wrote: -> -> >>Но мне бы хотелось сравнить значение именно со списком! КАК? -> >> -> >> -> > -> >А может это просто чрезмерное увлечение вложенными запросами? :) -> > -> >SELECT * FROM nets_tbl WHERE 'xxx.xxx.xxx.xxx' << net AND name='perm' ; -> > -> > -> > -> Вот что бывает, когда пытаешься упросить задачу для объяснения. ;) -> Всё сложнее, поэтому (на мой взгляд) и понадобился список. Я сильно -> упростил задачу, чтобы дать понять, что я хочу. В итоге получил более -> рациональное и правильное решение, но увы не применимое в моём случае, а -> только в том случае, который я описал. -> -> Ладно попробуем снова, теперь по полной программе: -> Есть таблица тафика: -> CREATE TABLE traffic_tbl ( -> id SERIAL PRIMARY KEY, -> tdate DATE, -> src_ip INET NOT NULL, -> src_port INT, -> dst_ip INET NOT NULL, -> dst_port INT, -> size INT4 NOT NULL -> ); -> где полный трафик -> -> Есть таблица сетей: -> CREATE TABLE nets_tbl ( -> id SERIAL PRIMARY KEY, -> name VARCHAR(40) NOT NULL, -> net INET NOT NULL -> ); -> В этой таблице есть ряд записей про пермские сети и ряд записей про IP -> адреса сетевых интерфейсов компьютера alpha -> -> Хочу получить данные о всём пермском трафике, исходящем с компьютера -> alpha по всем сетевым интерфейсам -> в некую таблицу results_tbl: -> -> INSERT INTO results_tbl (month, year, note, size) -> VALUES(4,2005,'Пермский исходящий трафик с alpha', -> (SELECT sum(size) FROM traffic_tbl WHERE -> src_ip IN (SELECT net FROM nets_tbl WHERE name='alpha') AND -> dst_ip __________IN__________ (SELECT net FROM nets_tbl -> WHERE name='perm'))); -> -> Вот там где ______IN________ очень бы хотелось сравнить со списком. Как -> сделать подругому - я не знаю, ибо не очень силён в SQL. -> -> -- -> С уважением, Виктор -> -> -> -> ---------------------------(end of broadcast)--------------------------- -> TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org -> С уважением, -- Denis A. Egorov
Denis A. Egorov wrote: >Здравствуйте, Viktor Vislobokov! > >Я думаю что могу немного помочь в этом вопросе. > >Насколько я понял задача стоит разделения трафика на типы, в моём >слечаее это был мир/украина. > >Тоже сначала думал всё пихать в БД, но это очень дорого обходится, как в >объёмах так и в обработке. > > Задача стоит парсить соответствующие логи. Логи уже есть и менять их нельзя. Вообще-то я в логи кладу уже несколько обсчитанную информацию, как можно было заметить - за день. Насколько здесь выгодно или нет использовать БД - вопрос спорный. Меня сейчас интересует другой вопрос - как быть с соответствием IP адреса списку. За предложение помощи - спасибо, но у меня свой путь ;) -- С уважением, Виктор
Viktor Vislobokov wrote: > >>Но мне бы хотелось сравнить значение именно со списком! КАК? > >> > >> > > > >А может это просто чрезмерное увлечение вложенными запросами? :) > > > >SELECT * FROM nets_tbl WHERE 'xxx.xxx.xxx.xxx' << net AND name='perm' ; > > > > > > > Вот что бывает, когда пытаешься упросить задачу для объяснения. ;) > Всё сложнее, поэтому (на мой взгляд) и понадобился список. Я сильно > упростил задачу, чтобы дать понять, что я хочу. В итоге получил более > рациональное и правильное решение, но увы не применимое в моём случае, а > только в том случае, который я описал. > > Ладно попробуем снова, теперь по полной программе: > Есть таблица тафика: > CREATE TABLE traffic_tbl ( > id SERIAL PRIMARY KEY, > tdate DATE, > src_ip INET NOT NULL, > src_port INT, > dst_ip INET NOT NULL, > dst_port INT, > size INT4 NOT NULL > ); > где полный трафик > > Есть таблица сетей: > CREATE TABLE nets_tbl ( > id SERIAL PRIMARY KEY, > name VARCHAR(40) NOT NULL, > net INET NOT NULL > ); > В этой таблице есть ряд записей про пермские сети и ряд записей про IP > адреса сетевых интерфейсов компьютера alpha > > Хочу получить данные о всём пермском трафике, исходящем с компьютера > alpha по всем сетевым интерфейсам > в некую таблицу results_tbl: > > INSERT INTO results_tbl (month, year, note, size) > VALUES(4,2005,'Пермский исходящий трафик с alpha', > (SELECT sum(size) FROM traffic_tbl WHERE > src_ip IN (SELECT net FROM nets_tbl WHERE name='alpha') AND > dst_ip __________IN__________ (SELECT net FROM nets_tbl > WHERE name='perm'))); > > Вот там где ______IN________ очень бы хотелось сравнить со списком. Как > сделать подругому - я не знаю, ибо не очень силён в SQL. По моему если в таблице nets_tbl нет записей для которых name1 = name2 и net1 << net2 , то этот запрос эквивалентен запросу INSERT INTO results_tbl (month, year, note, size) VALUES(4,2005,'Пермский исходящий трафик с alpha', (SELECT sum(size) FROM traffic_tbl, nets_tbl AS src_nets, nets_tbl AS dst_nets WHERE src_ip = src_nets.net AND src_nets.name='alpha' AND dst_ip << dst_nets.net dst_nets.name='perm')); Но в любом случае правильнее метить трафик на принадлежность к определенной группе на этапе вставки его в базу, потому как сети могут меняться. -- Mykola Dzham, LEFT-(UANIC|RIPE) JID: levsha@jabber.kiev.ua
Viktor Vislobokov wrote: > Привет всем. > Есть ли возможность по сетевому типу inet проверить вхождение адреса для > СПИСКА значений inet? > Т.е. > > есть некий IP адрес: xxx.xxx.xxx.xxx > > Есть также таблица сетей > > CREATE TABLE nets_tbl ( > id SERIAL PRIMARY KEY, > netname CHAR(10), > net INET UNIQUE > ); > > в которой забито несколько значений например: > SELECT * FROM nets_tbl; > id | name | net > ----+--------+------------------ > 13 | perm | 195.222.128.0/19 > 14 | perm | 62.16.32.0/19 > 15 | perm | 195.42.134.0/24 > > Мне надо сделать запрос, который бы позволил мне сказать, входит ли IP > адрес xxx.xxx.xxx.xxx в любую из сетей, которая соответствует имени 'perm'. > > Напрашивается такой вариант: > SELECT * FROM nets_tbl WHERE 'xxx.xxx.xxx.xxx' IN (SELECT net FROM > nets_tbl WHERE name='perm'); > > Однако, такой запрос всегда будет выдавать 0 записей, т.е. совпадения > никогда не будет, если только значение в поле net не точно такое же как > и у xxx.xxx.xxx.xxx. Это вроде бы понятно почему - надо сравнение делать > с помощью функций, предназначенных для этого типа. Ищу такую функцию и > нахожу "<<", но она работает только для единичных значений, т.е. > > SELECT * FROM nets_tbl WHERE 'xxx.xxx.xxx.xxx' << (SELECT net FROM > nets_tbl WHERE id=13); > > работать будет, а вот: > > SELECT * FROM nets_tbl WHERE 'xxx.xxx.xxx.xxx' << (SELECT net FROM > nets_tbl WHERE name='perm'); > > нет, потому что: > ERROR: more than one row returned by a subquery used as an expression > > Но мне бы хотелось сравнить значение именно со списком! КАК? > ANY не подойдет? -- С уважением, технический директор ООО "ЦСА" Николай Газалов www.sbin.org +7 8793 365584 (GPG Key ID: 4396B2D0)
> ANY не подойдет? > Спасибо! Это то что нужно! -- С уважением, Виктор