Обсуждение: Есть ли такая возможность
Привет всем. Есть ли возможность по сетевому типу 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 не подойдет? > Спасибо! Это то что нужно! -- С уважением, Виктор