powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Хранить в SQL diff и в дальнейшем сделать select
14 сообщений из 14, страница 1 из 1
Хранить в SQL diff и в дальнейшем сделать select
    #39365864
DeeZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день
Подскажите как правильне сделать?
Есть необходимость хранить маки и IP в базе, но если раз в 5 минут просто писать в базу текущее состояние - получается очень много. медленно ищет, и долго добавляется. Написал скрипт, который просто делает diff между двумя последними состояниями и показывает различия. Примерно такие данные получаются:
id datetimeflagipmacintvlans11480409401:new:1.1.158.4374867a6836f5TenGigabitEthernet0/2/0.883074521480410001:new:1.1.159.877062b8c6c70bTenGigabitEthernet0/2/0.882093131480410001:new:1.1.157.1667062b8bf9283TenGigabitEthernet0/2/0.883044041480410001:new:1.1.158.7094de80bed855TenGigabitEthernet0/2/0.876012551480412401:del:1.1.159.877062b8c6c70bTenGigabitEthernet0/2/0.882093161480412401:new:1.1.159.211001e9096632dTenGigabitEthernet0/2/0.8830260
в момент времени 1480409401 добавился 1 адрес, в 1480410001 добавилось 3 мака, а в 1480412401 добавился 1 и один из первых исчез. Эту инфу я могу прямо так и писать в базу.

Но, допустим мне надо посмотреть кто был в базе в момент времени 1480410001 (если я просто сделаю datetime = 1480410001 то туда не попадет mac c id=1).
Те пока нет del - нужно считать что запись в базе есть. и в селекте ее показывать.

от сюда 2 вопроса:
как лучше хранить такого рода информацию?
если хранить прямо так, то как сделать селект что бы увидеть не удаленные записи? (когда именно запись была добавлена - заранее неизвестно. те 1480409401 может быть и 1000000001 и 1. ну если не делать доп селекта)
...
Рейтинг: 0 / 0
Хранить в SQL diff и в дальнейшем сделать select
    #39365957
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DeeZак лучше хранить такого рода информацию?Можно прямо так и хранить - в виде "пришел во столько-то/ушел во столько-то".
Желательно подобрать компактные типы данных, а не хранить все строками. Например, ip-адрес в unsigned int.
Вещи, которые поддаются перечислению, лучше вынести в отдельные таблицы (например, TenGigabitEthernet и 0/2/0.8830745)

Чтобы определить состояние адреса на момент времени нужно искать последнюю предыдущую запись перед эти моментом времени.
Как-то так:
Код: sql
1.
SELECT * FROM mytable WHERE mac='7062b8c6c70b' ORDER BY datetime DESC LIMIT 1

При наличии индекса (mac,datetime) работать должно быстро.
...
Рейтинг: 0 / 0
Хранить в SQL diff и в дальнейшем сделать select
    #39365989
DeeZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А если искать нужно будет по адресу?
Обычно надо найти кому был выдан IP с 1 по 5 января например.
Если это адрес динамический там может быть от 0 до 100500 МАКов, причем может получиться так что 1 мак попадет в таблицу 31 декабря, или вообще 1 января прошлого года (мало ли), а удалится 4 и 4 же этот IP получит другой клиент.
А найти нужно именно обоих.
...
Рейтинг: 0 / 0
Хранить в SQL diff и в дальнейшем сделать select
    #39366043
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DeeZА если искать нужно будет по адресу?
Обычно надо найти кому был выдан IP с 1 по 5 января например.Тогда ищете двумя отдельными запросами всё в диапазоне с 1 по 5 января и еще одну последнюю запись до 1 января. И объединяете эти запросы через UNION ALL.
...
Рейтинг: 0 / 0
Хранить в SQL diff и в дальнейшем сделать select
    #39366277
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DeeZесли раз в 5 минут просто писать в базу текущее состояние - получается очень много.Раз в 5 минут - это всего 100 тыс. записей в год, мелочь.

DeeZмедленно ищет, и долго добавляется.Или железо такое дохлое, или индексами в структуре даже не пахнет. Хотя при сотне байтов на запись и сотне тысяч записей всё должно летать и без индексов... замените свой сервер хотя бы на пентиум-2.
...
Рейтинг: 0 / 0
Хранить в SQL diff и в дальнейшем сделать select
    #39366282
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkinaРаз в 5 минут - это всего 100 тыс. записей в год, мелочь.Насколько я понял, под одним разом понимается состояние всей сети. Т.е. не одна запись в таблице, а столько, сколько хостов сети в конкретный момент.
...
Рейтинг: 0 / 0
Хранить в SQL diff и в дальнейшем сделать select
    #39366355
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoft , он пишет не состояние, а его изменение:
DeeZв момент времени 1480409401 добавился 1 адрес, в 1480410001 добавилось 3 мака, а в 1480412401 добавился 1 и один из первых исчез .Для сети на сотню хостов это приблизительно удвоит объём - не разговор...
...
Рейтинг: 0 / 0
Хранить в SQL diff и в дальнейшем сделать select
    #39366364
DeeZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я пишу а том что у меня 10 000 записей раз в 5 минут. хранить весь список разом - много, долго, и обьективно бесполезно.
Я сделал дифы, в этом случае раз в 5 минут у меня только 4-5 строк изменений (вместо мгновенного снимка в 10 000 записей).
В год это 525 600 записей,если писать только диф (против 1 051 200 000 для полного состояния).

Но если с полным состоянием я могу просто сделать селект и получить какие адреса сейчас используются и кем, то как это сделать если в базе только дифы - не знаю.
Я заранее не знаю когда адрес начал использоваться, по этому не могу сделать селект за то число с которого нужный адерс стал занят (как предлагает miksoft).

по сути, мне нужно из дифов восстановить полнйы список и сделать по нему селект.
...
Рейтинг: 0 / 0
Хранить в SQL diff и в дальнейшем сделать select
    #39366451
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DeeZесли с полным состоянием я могу просто сделать селект и получить какие адреса сейчас используются и кем, то как это сделать если в базе только дифы - не знаю.
По сути тебе нужно для каждого адреса сделать выборку последнего состояния. А на эту тему у нас в разделе целый FAQ: Выборка первой/последней записи в группах написан... читай, просвещайтся.
...
Рейтинг: 0 / 0
Хранить в SQL diff и в дальнейшем сделать select
    #39366730
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DeeZпо этому не могу сделать селект за то число с которого нужный адерс стал занят (как предлагает miksoft).Я предлагаю выборку не по конкретному числу, а по последней записи перед этим числом. Это не одно и то же.
...
Рейтинг: 0 / 0
Хранить в SQL diff и в дальнейшем сделать select
    #39367326
DeeZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ФАК читал, и понимаю что, это то что нужно, но ни как не могу понять как должен выглядеть запрос в моем случае.
При условии что у меня 1 база (пока.потом разобью на более удачную), как учесть Flag = 1 - адерс удален (ушел)
Например, как должен выглядеть запрос типа
Код: sql
1.
2.
where ip_address=2.2.82.30 and recdate > 1481610001   
and recdate < 1481616601 


Где мак 34363b9ae000 уже ушел и должен быть удален из выборки. И
Код: sql
1.
2.
where ip_address=2.2.82.30 and recdate > 1481609401
and recdate < 1481616601


где мак 34363b9ae000 еще не ушел

SQL
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
CREATE TABLE `ArpDif` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `recdate` int(11) DEFAULT NULL,
  `routerid` tinyint(4) DEFAULT NULL,
  `flag` int(10) DEFAULT NULL,
  `ip_address` int(10) unsigned DEFAULT NULL,
  `mac_address` bigint(20) unsigned DEFAULT NULL,
  `interface` varchar(45) CHARACTER SET latin1 DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `idArpDif_UNIQUE` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=71619 DEFAULT CHARSET=utf8;

INSERT INTO ArpDif(recdate, routerid, flag, ip_address, mac_address, interface) VALUES
(1481576401, "1","0", INET_ATON ("2.2.82.30"), CONV("f03404852308",16,10),"TenGigabitEthernet0/2/0.30200664"),
(1481577001, "1","1", INET_ATON ("2.2.82.30"), CONV("f03404852308",16,10),"TenGigabitEthernet0/2/0.30200664"),
(1481601601, "1","0", INET_ATON ("2.2.82.30"), CONV("e8b4c84cb852",16,10),"TenGigabitEthernet0/2/0.8540904"),
(1481602201, "1","1", INET_ATON ("2.2.82.30"), CONV("e8b4c84cb852",16,10),"TenGigabitEthernet0/2/0.8540904"),
(1481606401, "1","0", INET_ATON ("2.2.82.30"), CONV("34363b9ae000",16,10),"TenGigabitEthernet0/2/0.8510099"),
(1481610001, "1","1", INET_ATON ("2.2.82.30"), CONV("34363b9ae000",16,10),"TenGigabitEthernet0/2/0.8510099"),
(1481610601, "1","0", INET_ATON ("2.2.82.30"), CONV("000af5898980",16,10),"TenGigabitEthernet0/2/0.8610652"),
(1481615401, "1","1", INET_ATON ("2.2.82.30"), CONV("000af5898980",16,10),"TenGigabitEthernet0/2/0.8610652"),
(1481616601, "1","0", INET_ATON ("2.2.82.30"), CONV("000af5898980",16,10),"TenGigabitEthernet0/2/0.8610652"),
(1481620201, "1","1", INET_ATON ("2.2.82.30"), CONV("000af5898980",16,10),"TenGigabitEthernet0/2/0.8610652"),
(1481620801, "1","0", INET_ATON ("2.2.82.30"), CONV("000af5898980",16,10),"TenGigabitEthernet0/2/0.8610652"),
(1481622601, "1","1", INET_ATON ("2.2.82.30"), CONV("000af5898980",16,10),"TenGigabitEthernet0/2/0.8610652"),
(1481624402, "1","0", INET_ATON ("2.2.82.30"), CONV("10d38af7f795",16,10),"TenGigabitEthernet0/2/0.30150702"),
(1481640001, "1","1", INET_ATON ("2.2.82.30"), CONV("10d38af7f795",16,10),"TenGigabitEthernet0/2/0.30150702");

...
Рейтинг: 0 / 0
Хранить в SQL diff и в дальнейшем сделать select
    #39367338
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А где эталонный результат?
И что значит ушёл / не ушёл?
А так не вижу сложностев.
Код: sql
1.
2.
3.
4.
5.
6.
SELECT MAX(recdate), ip_address, mac_address, interface
FROM ArpDif
WHERE ip_address=INET_ATON ("2.2.82.30") 
  AND recdate > 1481609401
  AND recdate < 1481616601
GROUP BY ip_address, mac_address, interface

тебе даёт всё, что нужно для идентификации последней записи. По ним из второй копии таблицы получаешь всю запись, и отбираешь только те, в которых Flag = 0.
...
Рейтинг: 0 / 0
Хранить в SQL diff и в дальнейшем сделать select
    #39367383
DeeZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
(1481606401, "1","0", INET_ATON ("2.2.82.30"), CONV("34363b9ae000",16,10),"TenGigabitEthernet0/2/0.8510099"),
запрос 1
>1481609401   тут 34363b9ae000 должен попасть в выборку, хотя 1481606401 не удовлетворяет условию  ">1481609401"
(1481610001, "1","1", INET_ATON ("2.2.82.30"), CONV("34363b9ae000",16,10),"TenGigabitEthernet0/2/0.8510099"),
запрос 2
>1481610001 а тут нет, тк он уже ушел к этому моменту Flag=1
(1481610601, "1","0", INET_ATON ("2.2.82.30"), CONV("000af5898980",16,10),"TenGigabitEthernet0/2/0.8610652"),
(1481615401, "1","1", INET_ATON ("2.2.82.30"), CONV("000af5898980",16,10),"TenGigabitEthernet0/2/0.8610652"),
(1481616601, "1","0", INET_ATON ("2.2.82.30"), CONV("000af5898980",16,10),"TenGigabitEthernet0/2/0.8610652"),
<1481616601  включить записи до сюда (000af5898980 не удалять тк он был, ушел но был в заданый период
(1481620201, "1","1", INET_ATON ("2.2.82.30"), CONV("000af5898980",16,10),"TenGigabitEthernet0/2/0.8610652"),
...
Рейтинг: 0 / 0
Хранить в SQL diff и в дальнейшем сделать select
    #39367454
DeeZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ну хотя тут еще можно выцепить не обращая внимание на флаг. но как выцепить тех кто получил раньше и освободил ползже? те вообще не попал в выборку?

Например из этой выборки получить 000af5898980 при условии recdate > 1481610610 and recdate < 1481615301
(1481610601, "1","0", INET_ATON ("2.2.82.30"), CONV("000af5898980",16,10),"TenGigabitEthernet0/2/0.8610652"),
(1481615401, "1","1", INET_ATON ("2.2.82.30"), CONV("000af5898980",16,10),"TenGigabitEthernet0/2/0.8610652"),
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Хранить в SQL diff и в дальнейшем сделать select
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]