Автоматическое заполнение таблицы IP-адресами в зависимости от сетевой маски CIDR

У меня есть 2 таблицы cidr и ip.

В первом я храню маску сети CIDR. (таблица с 2 столбцами, id_cidr, cidr), вот пример (значения вымышленные):

 id_cidr |     cidr
---------+----------------
    1    | 14.44.182.0/24
---------+----------------
    2    | 26.232.49.0/22

Во втором я хочу хранить IP-адреса в каждой сетевой маске cidr (таблица из 3 столбцов, id_ip, cidr_id, ip), вот пример (значения вымышленные):

  id_ip  | cidr_id  |     ip
---------+--------------------------
    1    |    1     | 14.44.182.0
---------+--------------------------
    2    |    1     | 14.44.182.1
---------+--------------------------
    3    |    1     | 14.44.182.2
---------+--------------------------
   ...   |    1     | ...
---------+--------------------------
   256   |    1     | 14.44.182.255
---------+--------------------------
   257   |    2     | 26.232.48.0
---------+--------------------------
   258   |    2     | 26.232.48.1
---------+--------------------------
   259   |    2     | 26.232.48.2
---------+--------------------------
   ...   |    2     | ...
---------+--------------------------
  1280   |    2     | 26.232.51.255

Я хочу добиться следующего: всякий раз, когда я добавляю сетевую маску cidr в cidr table, я хочу, чтобы мой ip table автоматически заполнял поля всем диапазоном IP-адресов в этой сетевой маске cidr. Есть ли способ добиться этого в mysql?

Примечание. Чтобы преобразовать сетевую маску cidr в диапазон IP-адресов, нажмите здесь


person paulalexandru    schedule 21.08.2016    source источник
comment
Первый IP-адрес, сгенерированный под этим ip series = 26.232.49.0/22, будет 26.232.48.0. это ожидается? А также скажите нам, предпочитаете ли вы вызов процедуры для заполнения второй таблицы?   -  person 1000111    schedule 21.08.2016
comment
Вы правы, ошибся, исправил. Да, я думаю, какая-то процедура или любое другое решение, кроме PHP. Итак, из mysql, и я спрашиваю об этом, потому что у меня нет опыта работы с продвинутым mysql.   -  person paulalexandru    schedule 21.08.2016
comment
То, что вы хотите, звучит так, как будто вам нужен триггер для этого. Но вызывать процедуру внутри триггера не рекомендуется. Но на вашем месте я бы сделал это так: 1) вставить в таблицу cidr 2) получить последний идентификатор вставки 3) вызвать процедуру, предоставляющую последний вставленный идентификатор cidr и сам cidr для вставки в таблицу ip   -  person 1000111    schedule 21.08.2016
comment
Это полезно для вас здесь моего, в частности, в таблице с 1 строкой, показывающей это ... меньше уборки   -  person Drew    schedule 21.08.2016


Ответы (1)


Процедура:

DELIMITER $$
CREATE PROCEDURE populateIpProcedure(cidrID INT)
BEGIN
  DECLARE my_cidr_id INT;
  DECLARE my_cidr_str VARCHAR(25);
  DECLARE my_initial_ip VARCHAR(15);
  DECLARE my_initial_ip_int INT;
  DECLARE my_ip_limit INT;
  DECLARE my_loop_variable INT DEFAULT 0;

  SET my_cidr_id = cidrID;
  SELECT cidr INTO my_cidr_str FROM cidr WHERE id_cidr = my_cidr_id;  
  SELECT 
    SUBSTRING_INDEX(my_cidr_str,'/',1),SUBSTRING_INDEX(my_cidr_str,'/',-1)+0 INTO my_initial_ip, my_ip_limit;

  SET my_ip_limit = (SELECT POWER(2, (32-my_ip_limit)));
  SELECT INET_ATON(my_initial_ip) INTO my_initial_ip_int;


    WHILE my_loop_variable < my_ip_limit DO 
        INSERT INTO ip(cidr_id,ip) SELECT my_cidr_id, INET_NTOA(my_initial_ip_int+my_loop_variable);
    SET my_loop_variable := my_loop_variable + 1;
  END WHILE;
END$$
DELIMITER ;

В приведенной выше процедуре в качестве аргумента используется идентификатор cidr.

Затем он извлекает запись из таблицы cidr по заданному идентификатору.

Позже он вставляет все ips под этим cidr в таблицу ip.

Тест:

CALL populateProcedure(1);

Это добавит 256 записей в таблицу ip под этой серией IP-адресов 14.44.182.0/24.

Схема тестирования и данные:

DROP TABLE IF EXISTS `cidr`;
CREATE TABLE `cidr` (
  `id_cidr` int(11) NOT NULL AUTO_INCREMENT,
  `cidr` varchar(25) NOT NULL,
  PRIMARY KEY (`id_cidr`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

INSERT INTO `cidr` VALUES ('1', '14.44.182.0/24');
INSERT INTO `cidr` VALUES ('2', '26.232.49.0/22');

DROP TABLE IF EXISTS `ip`;
CREATE TABLE `ip` (
  `id_ip` int(11) NOT NULL AUTO_INCREMENT,
  `cidr_id` int(11) NOT NULL,
  `ip` char(15) NOT NULL,
  PRIMARY KEY (`id_ip`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
person 1000111    schedule 22.08.2016