Представление адресов IPv4/IPv6 в Oracle

Каков подходящий тип данных или метод представления сетевых адресов в Oracle, какие адреса могут быть IPv4 или IPv6?

Справочная информация: я конвертирую таблицу сетевой активности, созданную с использованием PostgreSQL inet тип данных для хранения адресов v4 и v6 в одной таблице.

Однако ни одна строка не содержит адреса как v4, так и v6. (То есть запись происходит либо из стека v4 машины, либо из стека v6 машины.)


person pilcrow    schedule 09.02.2011    source источник
comment
Вы выполняете агрегацию/поиск в этой таблице по IP-адресу? сколько строк вы ожидаете получить через 1 год?   -  person jachguate    schedule 10.02.2011
comment
Агрегации и поиск по IP, да. Количество строк, возможно, сотни миллионов. (Есть ли у вас маленькие/средние/большие рекомендации?)   -  person pilcrow    schedule 10.02.2011
comment
пожалуйста, используйте пометку @jachguate в своих комментариях, если хотите, чтобы я получил уведомление об этом. Для того, что вы говорите, я думаю, что лучший подход - это первый ответ @Alain.   -  person jachguate    schedule 10.02.2011


Ответы (7)


Какой тип данных или метод представления сетевых адресов в Oracle является подходящим, какие адреса могут быть IPv4 или IPv6.

Есть два подхода:

  1. только хранение.
  2. сохранение обычного представления

Только для хранения. Адрес IPV4 должен быть целым числом (достаточно 32 бита). Для IP V6, 128 бит, подойдет INTEGER (аналогичный Number(38)). Конечно, это хранение. Этот подход исходит из того, что представление является делом приложения.

Если выбрать противоположную стратегию хранения обычного представления, необходимо убедиться, что адреса IP V4 и IPV6 имеют только одно традиционное (строковое) представление. Это хорошо известно для ipV4. Что касается IPV6, то здесь тоже стандартный формат.

Я отдаю предпочтение первой стратегии. В худшем случае вы можете применить гибридный подход (хотя и некислотный) и хранить как двоичное, так и ascii-представление рядом с «приоритетом» двоичного значения.

Однако ни одна строка не содержит адреса как v4, так и v6.

Стандартное представление адреса IPV4 в формате IPV6: ::ffff:192.0.2.128.

Я не знаю контекста, но я бы зарезервировал 2 столбца, один для IPV4, а другой для отдельного адреса ipV6.

Обновление
Следуя хорошему комментарию @sleepyMonad, я хотел бы отметить, что вместо типа данных Number предпочтительнее использовать тип данных INTEGER, который с радостью вместит максимальное возможное значение, которое может быть выражено 128-битным целым числом 'ff...ff' (для которого потребуется 39 десятичных цифр). 38 — это наивысшая степень числа от 0 до 9, которое может быть закодировано 128 битами, но при этом можно вставить максимальное беззнаковое значение для 2**128 - 1 ( десятичное число 340282366920938463463374607431768211455). Вот небольшой тест, иллюстрирующий эту возможность.

create table test (
  id integer primary key,
  ipv6_address_bin INTEGER );

-- Let's enter 2**128 - 1 in the nueric field
insert into test (id, ipv6_address_bin) values ( 1, to_number ( 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX') ) ;

-- retrieve it to make sure it's not "truncated".
select to_char ( ipv6_address_bin, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' ) from test where id = 1 ;
-- yields 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'

select to_char ( ipv6_address_bin ) from test where id = 1 ;
-- yields 340282366920938463463374607431768211455

select LOG(2, ipv6_address_bin) from test where id = 1 ;
-- yields 128

select LOG(10, ipv6_address_bin) from test where id = 1 ;
-- yields > 38
person Alain Pannetier    schedule 09.02.2011
comment
Определенно согласен с отдельными столбцами для значений IPv4 и IPv6. - person Gary Myers; 10.02.2011
comment
Не могли бы вы также ограничить столбцы v4 и v6, чтобы один и только один из них был NULL? (Что-то вроде CHECK((src_v4 IS NULL and src_v6 IS NOT NULL) or (src_v4 IS NOT NULL and src_v6 IS NULL))) ? - person pilcrow; 10.02.2011
comment
Все зависит от того, что должны содержать данные таблицы. Если предположить, что IP-адрес не является ключом (кажется очевидным из вашего вопроса), и вы отслеживаете пользователей, тогда я бы оставил дверь открытой, потому что люди могут подключаться с разных IP-адресов. Если вместо этого ваша таблица отслеживает события подключения, а не пользователей (предположительно с отношением один к n), тогда да, потому что вы подключаетесь либо в IP v4, либо в V6 (хотя, как я уже сказал, адреса IP v4 имеют представление V6) . - person Alain Pannetier; 10.02.2011
comment
Если у вас есть ipv4 ИЛИ ipv6, но никогда оба, сохраните адреса ipv4, используя их эквивалент ipv6. - person ThiefMaster; 10.02.2011
comment
@ВорМастер. Да, действительно, потому что диапазон ::ffff:a.b.c.d зарезервирован именно для этого случая. - person Alain Pannetier; 10.02.2011
comment
@ Ален Паннетье: поскольку 2 ^ 128 имеет 39 десятичных цифр, неясно, как это вписывается в NUMBER (38). - person sleepyMonad; 06.06.2011
comment
@sleepyMonad. Я добавил пример кода sql, чтобы проиллюстрировать возможность кодирования ffff:ffff:.......ffff ipv6-адресов в поле INTEGER (вы правы, в каком-то смысле проще использовать INTEGER, чем NUMBER(38), но INTEGER тоже 128 бит). NUMBER(38) не будет работать так гладко, как INTEGER. Исправление. - person Alain Pannetier; 06.06.2011
comment
@Ален Паннетье. Это совершенно неправильно. В Oracle тип данных Integer является синонимом NUMBER (38). SQL› создать тестовую таблицу (первичный ключ id integer, ipv6_address_bin INTEGER ); Таблица создана. SQL› desc test Name Null? Тип ----------------------------------------- -------- ---------------------------- ID NOT NULL NUMBER(38) IPV6_ADDRESS_BIN NUMBER(38) SQL› проверка таблицы удаления; Стол упал. SQL› - person miracle173; 20.10.2011
comment
@чудо173. Я попробовал код выше (в ответе) как с INTEGER, так и с NUMBER (38). Работал как ветер с INTEGER, но не с NUMBER (38). 11gR2 IIRC. Вы пробовали это? На 11gR2 работает? - person Alain Pannetier; 20.10.2011
comment
@Ален Паннетье. Я попробовал ваш код, и вы правы, это сработало. Вывод описательных функций кажется неправильным. я запросил user_tab_columns, и он дает мне для столбца data_precision NULL для столбца INTEGER и 38 для столбца NUMBER (38). Я буду исследовать это дальше, когда у меня будет больше времени. Думаю, не стоит полагаться на эту недокументированную возможность. - person miracle173; 25.10.2011
comment
я проверил это с помощью последовательности чисел и не смог найти ни одного ip, который не был бы представлен - person ShoeLace; 22.08.2013
comment
Имейте в виду, если вы используете такие значения в любом коде PL/SQL. i INTEGER := 2**128-1; (т. е. ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff) вызывает ORA-06502: PL/SQL: ошибка числа или значения: слишком большая точность числа. INTEGER поскольку тип данных столбца отличается от INTEGER типа данных PL/SQL! - person Wernfried Domscheit; 18.05.2018

Сохраняйте в RAW.

RAW - это массив байтов переменной длины, поэтому....

  • просто рассматривайте IPv4 как массив из 4 байтов
  • и IPv6 как массив из 16 байт

...и сохранить любой из них непосредственно в RAW(16).


RAW может быть проиндексирован, быть PK, UNIQUE или FOREIGN KEY, поэтому вы можете делать все, что обычно делаете с VARCHAR2 или INT/NUMBER/DECIMAL, но с меньшими затратами на преобразование и хранение.

Чтобы проиллюстрировать накладные расходы хранения INT по сравнению с RAW, рассмотрим следующий пример:

CREATE TABLE IP_TABLE (
    ID INT PRIMARY KEY,
    IP_RAW RAW(16), 
    IP_INT INT
);

INSERT INTO IP_TABLE (ID, IP_RAW, IP_INT) VALUES (
    1,
    HEXTORAW('FFFFFFFF'),
    TO_NUMBER('FFFFFFFF', 'XXXXXXXX')
);

INSERT INTO IP_TABLE (ID, IP_RAW, IP_INT) VALUES (
    2,
    HEXTORAW('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'),
    TO_NUMBER('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
);

SELECT VSIZE(IP_RAW), VSIZE(IP_INT), IP_TABLE.*  FROM IP_TABLE;

Результат (под Oracle 10.2):

table IP_TABLE created.
1 rows inserted.
1 rows inserted.
VSIZE(IP_RAW)          VSIZE(IP_INT)          ID                     IP_RAW                           IP_INT                 
---------------------- ---------------------- ---------------------- -------------------------------- ---------------------- 
4                      6                      1                      FFFFFFFF                         4294967295             
16                     21                     2                      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 340282366920938463463374607431768211455 
person Branko Dimitrijevic    schedule 03.02.2012
comment
Еще одно преимущество RAW: вы можете использовать UTL_RAW.BIT_AND и UTL_RAW.BIT_OR, если работаете с подсетями. - person Wernfried Domscheit; 17.05.2018

@Alain Pannetier (потому что я пока не могу комментировать): тип данных ANSI INTEGER сопоставляется с NUMBER (38) в Oracle в соответствии с http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/sql_elements001.htm#i54335. Ниже таблицы вы найдете информацию о том, что NUMBER обеспечивает только 126-битную двоичную точность, чего недостаточно для 128-битного IPv6-адреса. Максимальное значение может храниться нормально, но будут адреса, которые округляются до следующего меньшего значения.

Внутренний числовой формат: ROUND((длина(p)+s)/2))+1 (http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/datatype)..htm#i16209).

Обновление: После того, как я снова повозился с проблемой, я нашел решение, которое позволяет высокопроизводительно запрашивать сети, содержащие адрес IPv6: сохранять адреса IPv6 и маски подсети в столбцах RAW(16) и сравните их, используя UTL_RAW.BIT_AND:

SELECT name, DECODE(UTL_RAW.BIT_AND('20010DB8000000000000000000000001', ipv6_mask), ipv6_net, 1, 0)
FROM ip_net
WHERE ipv6_net IS NOT NULL;
person Alexander Hartmaier    schedule 20.10.2011

вы также можете использовать собственный объект оракула.

SQL>set SERVEROUTPUT on
SQL>drop table test;

Table dropped.

SQL>drop type body inaddr;

Type body dropped.

SQL>drop type inaddr;

Type dropped.

SQL>create type inaddr as object
  2  ( /* TODO enter attribute and method declarations here */
  3  A number(5),
  4  B number(5),
  5  C number(5),
  6  D number(5),
  7  E number(5),
  8  F number(5),
  9  G number(5),
 10  H NUMBER(5),
 11  MAP MEMBER FUNCTION display RETURN VARCHAR2,
 12  MEMBER FUNCTION toString( SELF IN INADDR , CONTRACT BOOLEAN DEFAULT TRUE) RETURN VARCHAR2,
 13  CONSTRUCTOR FUNCTION INADDR(SELF IN OUT NOCOPY INADDR, INADDRASSTRING VARCHAR2)  RETURN SELF AS RESULT
 14  
 15  ) NOT FINAL;
 16  /

SP2-0816: Type created with compilation warnings

SQL>
SQL>
SQL>CREATE TYPE BODY INADDR AS
  2  
  3  MAP MEMBER FUNCTION display RETURN VARCHAR2
  4  IS BEGIN
  5  return tostring(FALSE);
  6  END;
  7  
  8  
  9  MEMBER FUNCTION TOSTRING( SELF IN  INADDR , CONTRACT BOOLEAN DEFAULT TRUE) RETURN VARCHAR2 IS
 10  IP4 VARCHAR2(6) := 'FM990';
 11  ip6 varchar2(6) := 'FM0XXX';
 12    BEGIN
 13  IF CONTRACT THEN
 14    ip6 := 'FMXXXX';
 15  end if;
 16  
 17  IF CONTRACT AND A =0 AND B=0 AND C = 0 AND D=0 AND E =0 AND F = 65535 THEN --ipv4
 18      RETURN  '::FFFF:'||TO_CHAR(TRUNC(G/256),'FM990.')||TO_CHAR(MOD(G,256),'FM990.')||TO_CHAR(TRUNC(H/256),'FM990.')||TO_CHAR(MOD(H,256),'FM990');
 19  ELSE
 20      RETURN
 21  TO_CHAR(A,ip6)||':'||
 22  TO_CHAR(B,IP6)||':'||
 23  TO_CHAR(C,ip6)||':'||
 24  TO_CHAR(D,ip6)||':'||
 25  TO_CHAR(E,ip6)||':'||
 26  TO_CHAR(F,ip6)||':'||
 27  TO_CHAR(G,ip6)||':'||
 28  TO_CHAR(H,ip6);
 29  end if;
 30    end;
 31  
 32      CONSTRUCTOR FUNCTION inaddr(SELF IN OUT NOCOPY inaddr, inaddrasstring VARCHAR2)
 33                                 RETURN SELF AS RESULT IS
 34      begin
 35          if instr(inaddrasstring,'.') > 0 then
 36            --ip4
 37  null;
 38              a := 0;
 39              B := 0;
 40              C := 0;
 41              D := 0;
 42              E := 0;
 43              F := TO_NUMBER('FFFF', 'XXXX');
 44              G := TO_NUMBER(TO_CHAR(TO_NUMBER(REGEXP_SUBSTR(INADDRASSTRING,'([0-9]{1,3}).',1,1,'i',1),'999'),'FM0X')
 45  ||TO_CHAR(TO_NUMBER(REGEXP_SUBSTR(INADDRASSTRING,'([0-9]{1,3}).',1,2,'i',1),'999'),'FM0X')
 46  ,'XXXX');
 47              h := TO_NUMBER(TO_CHAR(TO_NUMBER(REGEXP_SUBSTR(INADDRASSTRING,'([0-9]{1,3}).',1,3,'i',1),'999'),'FM0X')
 48  ||TO_CHAR(TO_NUMBER(REGEXP_SUBSTR(INADDRASSTRING,'([0-9]{1,3})',1,4,'i',1),'999'),'FM0X')
 49  ,'XXXX');
 50  
 51          ELSIF instr(inaddrasstring,':') > 0 then
 52              --ip6
 53              a := TO_NUMBER(REGEXP_SUBSTR(inaddrasstring,'([0-9a-fA-F]{1,4})',1,1,'i',1),'XXXX');
 54              b := TO_NUMBER(REGEXP_SUBSTR(inaddrasstring,'([0-9a-fA-F]{1,4})',1,2,'i',1),'XXXX');
 55              c := TO_NUMBER(REGEXP_SUBSTR(inaddrasstring,'([0-9a-fA-F]{1,4})',1,3,'i',1),'XXXX');
 56              d := TO_NUMBER(REGEXP_SUBSTR(inaddrasstring,'([0-9a-fA-F]{1,4})',1,4,'i',1),'XXXX');
 57              E := TO_NUMBER(REGEXP_SUBSTR(inaddrasstring,'([0-9a-fA-F]{1,4})',1,5,'i',1),'XXXX');
 58              f := TO_NUMBER(REGEXP_SUBSTR(inaddrasstring,'([0-9a-fA-F]{1,4})',1,6,'i',1),'XXXX');
 59              g := TO_NUMBER(REGEXP_SUBSTR(inaddrasstring,'([0-9a-fA-F]{1,4})',1,7,'i',1),'XXXX');
 60              H := TO_NUMBER(REGEXP_SUBSTR(inaddrasstring,'([0-9a-fA-F]{1,4})',1,8,'i',1),'XXXX');
 61          end if;
 62  
 63          RETURN;
 64      END;
 65  end;
 66  /

Type body created.

SQL>
SQL>create table test
  2  (id integer primary key,
  3  address inaddr);

Table created.

SQL>
SQL>select * from test;

no rows selected

SQL>
SQL>
SQL>insert into test values (1, INADDR('fe80:0000:0000:0000:0202:b3ff:fe1e:8329') );

1 row created.

SQL>INSERT INTO TEST VALUES (2, INADDR('192.0.2.128') );

1 row created.

SQL>insert into test values (3, INADDR('20.0.20.1') );

1 row created.

SQL>insert into test values (4, INADDR('fe80:0001:0002:0003:0202:b3ff:fe1e:8329') );

1 row created.

SQL>insert into test values (5, INADDR('fe80:0003:0002:0003:0202:b3ff:fe1e:8329') );

1 row created.

SQL>INSERT INTO TEST VALUES (6, INADDR('fe80:0003:0001:0003:0202:b3ff:fe1e:8329') );

1 row created.

SQL>INSERT INTO TEST VALUES (7, INADDR('fe80:0003:0001:0003:0202:b3ff:fe1e:8328') );

1 row created.

SQL>INSERT INTO TEST VALUES (8, INADDR('dead:beef:f00d:cafe:dea1:aced:b00b:1234') );

1 row created.

SQL>
SQL>COLUMN INET_ADDRESS_SHORT FORMAT A40
SQL>column inet_address_full format a40
SQL>
SQL>select t.address.toString() inet_address_short, t.address.display( ) inet_address_full
  2  from test T
  3  order by t.address ;

INET_ADDRESS_SHORT                       INET_ADDRESS_FULL
---------------------------------------- ----------------------------------------
::FFFF:20.0.20.1                         0000:0000:0000:0000:0000:FFFF:1400:1401
::FFFF:192.0.2.128                       0000:0000:0000:0000:0000:FFFF:C000:0280
DEAD:BEEF:F00D:CAFE:DEA1:ACED:B00B:1234  DEAD:BEEF:F00D:CAFE:DEA1:ACED:B00B:1234
FE80:0:0:0:202:B3FF:FE1E:8329            FE80:0000:0000:0000:0202:B3FF:FE1E:8329
FE80:1:2:3:202:B3FF:FE1E:8329            FE80:0001:0002:0003:0202:B3FF:FE1E:8329
FE80:3:1:3:202:B3FF:FE1E:8328            FE80:0003:0001:0003:0202:B3FF:FE1E:8328
FE80:3:1:3:202:B3FF:FE1E:8329            FE80:0003:0001:0003:0202:B3FF:FE1E:8329
FE80:3:2:3:202:B3FF:FE1E:8329            FE80:0003:0002:0003:0202:B3FF:FE1E:8329

8 rows selected.

SQL>spool off

Я только что собрал это за последний час (и в то же время учил себя предметам), так что я уверен, что это можно улучшить. если я буду делать обновления, я буду размещать их здесь

person ShoeLace    schedule 30.05.2012
comment
Согласно RFC 5952 адрес FE80:0:0:0:202:B3FF:FE1E:8329 должен быть представлен как fe80::202:b3ff:fe1e:8329 - person Wernfried Domscheit; 18.05.2018
comment
справедливое замечание.. дополнительное regexp_replace в методе toString исправило бы это.. regexp_replace('FE80:0:0:0:202:B3FF:FE1E:8329',':[0:]*:','::') - person ShoeLace; 31.05.2018
comment
однако было бы 2001:db8:0:0:1:0:0:1 неправильно, так как можно уменьшить только набор 0 (и это должен быть самый длинный набор) - person ShoeLace; 31.05.2018
comment
Я думаю, что вы не можете сократить серию от 0:0 до :: только с Regex - по крайней мере, не в Oracle, потому что он не поддерживает обратную ссылку, см. это решение: stackoverflow.com/questions/7043983/ - person Wernfried Domscheit; 31.05.2018
comment
Я написал этот общий пакет: stackoverflow.com/questions/43221720/ Функция Canonical_IPv6 делает правильный вывод. - person Wernfried Domscheit; 31.05.2018

Я бы предпочел хранить IP-адреса только в строке в формате, возвращаемом SYS_CONTEXT ('USERENV', 'IP_ADDRESS')

В ссылке на SYS_CONTEXT в 11g описывается только возврат по умолчанию длина значения составляет 256 байт и не описывает размер возвращаемого значения именно для контекста «IP_ADDRESS».

В документе база данных Oracle и Заявление о направлении IPv6 описано:

Oracle Database 11g Release 2 поддерживает стандартную нотацию адресов IPv6, указанную в RFC2732. 128-битный IP-адрес обычно представлен в виде 8 групп из 4 шестнадцатеричных цифр с символом «:» в качестве разделителя групп. Ведущие нули в каждой группе удаляются. Например, 1080:0:0:0:8:800:200C:417A будет действительным адресом IPv6. Одно или несколько последовательных нулевых полей могут быть дополнительно сжаты с помощью разделителя «::». Например, 1080::8:800:200C:417A.

Из этих заметок я предпочитаю сделать столбец IP_ADDRESS varchar2(39), чтобы позволить хранить 8 групп по 4 цифры и 7 разделителей между этими группами.

person Nashev    schedule 12.03.2014
comment
Использование VARCHAR2 может создать некоторые проблемы. 1080::8:800:200C:417A, 1080::8:800:32.12.65.122, 1080::8:800:200c:417a, 1080:0:0:0:8:800:200C:417A, 1080:0000:0000:0000:0008:0800:200C:417A — все это законные представления одного и того же IP-адреса IPv6 (см. RFC 5952 и RFC 4291). Если вы не применяете определенный формат, у вас возникнут проблемы, если вам придется использовать его в предложении WHERE. - person Wernfried Domscheit; 16.05.2018
comment
В зависимости от формата VARCHAR2(39) недостаточно, в худшем случае у вас может быть 1080:1234:1234:1234:0008:5800:132.212.165.122 длиной 45 символов. - person Wernfried Domscheit; 16.05.2018
comment
Для адресов от Оракула достаточно, если они будут последовательно следовать своему обещанию из приведенной выше цитаты. Для адресов из других источников Вы правы, спасибо. - person Nashev; 16.05.2018

В документации Oracle указано, что INTEGER является псевдонимом NUMBER(38), но это, вероятно, опечатка, поскольку в абзаце выше говорится:

ЧИСЛО(p,s), где: p - точность... Oracle гарантирует переносимость чисел с точностью до 20 знаков по основанию 100, что эквивалентно 39 или 40 десятичным знакам в зависимости от положения десятичной точки.

Таким образом, NUMBER может хранить от 39 до 40 цифр, а INTEGER, скорее всего, является псевдонимом NUMBER (максимальная точность), а не NUMBER (38). Вот почему приведенный пример работает (и он работает, если вы измените INTEGER на NUMBER).

person Franky Wong    schedule 03.02.2012
comment
Как это отвечает на вопрос? - person wallyk; 30.10.2012

Возможности:

  • Сохранить как строку, т. е. VARCHAR2 (пример 1080::8:800:200c:417a)
  • Store as numeric value
    • NUMBER data type
    • INTEGER тип данных
  • Store as RAW value
    • One RAW value, i.e. RAW(4) or RAW(16) for IPv4 or IPv6 respectively
    • 4 x RAW(1) или 8 x RAW(2) для IPv4 или IPv6 соответственно

Я бы рекомендовал использовать значения RAW, потому что

  • Если вы используете строки, вы должны учитывать различные форматы IPv6.

    1080::8:800:200C:417A
    1080::8:800:200c:417a
    1080::8:800:32.12.65.122
    1080:0:0:0:8:800:200C:417A
    1080:0:0:0:0008:0800:200C:417A
    1080:0000:0000:0000:0008:0800:200C:417A
    

    все являются юридическими представлениями одного и того же IP-адреса IPv6. Ваше приложение должно применять общий формат для правильного использования, например. б/у в WHERE состоянии.

  • NUMBER/INTEGER значения не имеют смысла без преобразования в удобочитаемый формат. Вы не можете использовать тип данных INTEGER в PL/SQL

    i INTEGER := 2**128-1; -- i.e. ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
    
    -> ORA-06502: PL/SQL: numeric or value error: number precision too large. 
    
  • Если вам нужно работать с подсетями, вы не можете использовать функцию BITAND - он также поддерживает числа только до 2^127

  • Вы можете использовать функции UTL_RAW UTL_RAW.BIT_AND, UTL_RAW.BIT_COMPLEMENT, UTL_RAW.BIT_OR для подсети операции.

  • В случае, если вам приходится иметь дело с действительно большим объемом данных (я говорю о миллиардах строк), может быть полезно разделить IP-адрес на несколько значений RAW, т.е. 4 x RAW(1) или 8 x RAW(2). Такие столбцы будут предопределены для битмап-индексов. сэкономить много места на диске и повысить производительность.

person Wernfried Domscheit    schedule 31.05.2018
comment
RFC 5952, Рекомендации по текстовому представлению адреса IPv6 поясняет, что должен принимать все допустимые текстовые представления IPv6, но вы должны представлять только одно текстовое представление IPv6, описанное в RFC. - person Ron Maupin; 31.05.2018