PostgreSQL: сравнивать первые 3 числа адреса IPv4? - PullRequest
1 голос
/ 20 ноября 2010

Я пытаюсь запрограммировать PHP-скрипт, где пользователи могут оценить "доброту" других пользователей:

   create table pref_rep (
           id varchar(32) references pref_users(id) check (id <> author),
           author varchar(32) references pref_users(id),
           author_ip inet,
           good boolean,
           last_rated timestamp default current_timestamp
   );

Чтобы (попытаться) предотвратить подделку, я хотел бы удалить записидля одного и того же идентификатора, поступающего с одного и того же IP-адреса в течение последнего часа

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

   /* _author_ip will be $_SERVER['REMOTE_ADDR'] */
   create or replace function pref_update_rep(_id varchar,
           _author varchar, _author_ip inet,
           _good boolean) returns void as $BODY$
           begin
       delete from pref_rep
       where id = _id and
       author_ip = _author_ip and
       age(to_timestamp(last_rated)) < interval '1 hour';

       update pref_rep set
           author    = _author,
           author_ip = _author_ip,
           good      = _good,
           last_rated = current_timestamp
       where id = _id and author = _author;

       if not found then
               insert into pref_rep(id, author, author_ip, good)
               values (_id, _author, _author_ip, _good);
       end if;
           end;
   $BODY$ language plpgsql;

У меня есть 2вопросы, пожалуйста:

1) если я хотел бы сравнить только первые 3 числа IP-адреса вместо 4, как я могу это сделать? (да, я знаю о типах сетей IPv4 A, B, C, здесь неважно ...)

2) Нужно ли добавлять индекс в мою таблицуили ID и автор уже проиндексированы?

Спасибо!Alex

1 Ответ

2 голосов
/ 20 ноября 2010

1) Вы можете использовать оператор &:

postgres=# SELECT '1.2.3.4'::inet & '255.255.255.0'::inet;
 ?column?
----------
 1.2.3.0
(1 row)

Итак, вы можете сравнить

(author_ip & '255.255.255.0'::inet) = (_author_ip & '255.255.255.0'::inet)

2) Я не знаю, не так ли?

...