Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Работа с триггерами
 
 автор: dimm_kz   (25.08.2009 в 09:32)   письмо автору
1.3 Кб
 
 

Доброе время суток!
Имею следующую проблему: есть две базы данных. В базу №1 (base1), сыпится поток netflow. Есть необходимость, чтобы триггер брал данные перед вставкой и кидал в базу №2 (base2). Но не просто втупую перекидывал, а сравнивал текущие данные, т.е. если запись с приходящим айпишником уже есть, то делал UPDATE записи добавляя сумму трафика, если принимаемого айпишника нет, то делал бы INSERT.

Я примерно догадываюсь, что делается через цикл внутри тригера, но как это реализовать не знаю... перепробовал уже кучу вариантов и доков перелистал... но что-то не выходит.

Примерный дамп обеих баз в прикрепленном файле

  Ответить  
 
 автор: Trianon   (25.08.2009 в 09:48)   письмо автору
 
   для: dimm_kz   (25.08.2009 в 09:32)
 

По-моему, INSERT ... ON DUPLICATE KEY UPDATE - в самый раз.
И никаких циклов.

  Ответить  
 
 автор: dimm_kz   (25.08.2009 в 09:50)   письмо автору
 
   для: Trianon   (25.08.2009 в 09:48)
 

а можно немного поподробнее? Я до этого вообще никогда с триггерами не работал, а тут как оказалось ну очень нада....

  Ответить  
 
 автор: Trianon   (25.08.2009 в 10:13)   письмо автору
 
   для: dimm_kz   (25.08.2009 в 09:50)
 

так а этот запрос напрямую с триггерами не связан.
Вы уж определитесь, что вас интересует - триггеры или логика заполнения БД.

  Ответить  
 
 автор: Valick   (25.08.2009 в 10:19)   письмо автору
 
   для: Trianon   (25.08.2009 в 10:13)
 

наверное нужна связь двух баз в режиме master-master

  Ответить  
 
 автор: dimm_kz   (25.08.2009 в 10:23)   письмо автору
 
   для: Valick   (25.08.2009 в 10:19)
 

да тут какбы вопрос по заполнению базы, но в base2 он не просто должен ложить, но еще и суммировать, что-то типа in=in+NEW.in, out=out+NEW.out, для уже существующих данных ipin и ipout

  Ответить  
 
 автор: Valick   (25.08.2009 в 10:28)   письмо автору
 
   для: dimm_kz   (25.08.2009 в 10:23)
 

т.е. информация в базах с одним и тем же id разная?

  Ответить  
 
 автор: dimm_kz   (25.08.2009 в 10:37)   письмо автору
 
   для: Valick   (25.08.2009 в 10:28)
 

ну как бы id там нет. Принцып такой: делаю свою систему биллинга. Данные баз предназначены для сбора статистики. В базу base1 валится поток Netflow, т.е. каждые там 1-2 секунды в таблицу попадает строка в которой содержаться айпи пользователя, айпиприемника, порты, сумма входящего и иисходящего трафика. А триггер должен брать эту строчку и вставлять ее в таблицу базы base2, узнавая есть ли там айпишник пользователя и приемника или нет их и соответственно вставлять новые данные или обнавлять существующие.

  Ответить  
 
 автор: Trianon   (25.08.2009 в 10:37)   письмо автору
 
   для: dimm_kz   (25.08.2009 в 10:23)
 

Между прочим, у Вас две базы или всё же две таблицы в одной базе?

  Ответить  
 
 автор: dimm_kz   (25.08.2009 в 10:38)   письмо автору
 
   для: Trianon   (25.08.2009 в 10:37)
 

Две разные базы

  Ответить  
 
 автор: Trianon   (25.08.2009 в 10:38)   письмо автору
 
   для: dimm_kz   (25.08.2009 в 10:38)
 

На одном сервере или на разных?

  Ответить  
 
 автор: dimm_kz   (25.08.2009 в 10:47)   письмо автору
 
   для: Trianon   (25.08.2009 в 10:38)
 

пока в тестовом режиме, на одном сервере, как все пойдет нормально, на разные сервера

  Ответить  
 
 автор: Trianon   (25.08.2009 в 11:00)   письмо автору
 
   для: dimm_kz   (25.08.2009 в 10:47)
 

триггер не будет работать с базами, находящимися на другом сервере.

  Ответить  
 
 автор: Trianon   (25.08.2009 в 10:37)   письмо автору
 
   для: Valick   (25.08.2009 в 10:19)
 

Это еще что за зверь зачем?

  Ответить  
 
 автор: dimm_kz   (25.08.2009 в 10:41)   письмо автору
 
   для: Trianon   (25.08.2009 в 10:37)
 

в целях распределения ресурсов по 2-3 машинам... при большом объеме пользователей данные будут сыпаться с ужасными масштабами, вплоть до 500 гигов за месяц и это не предел... да и начальство так захотело...

  Ответить  
 
 автор: Valick   (25.08.2009 в 11:25)   письмо автору
 
   для: dimm_kz   (25.08.2009 в 10:41)
 

посмотрите тему http://softtime.ru/forum/read.php?id_forum=3&id_theme=66427
хотя там речь идёт о двух таблицах одной базы, но принцип, по-моему, тот который вас интересует (ближе к концу дискуссии) там и вложение есть для примера.

  Ответить  
 
 автор: dimm_kz   (25.08.2009 в 11:25)   письмо автору
 
   для: dimm_kz   (25.08.2009 в 09:32)
 

пытаюсь сделать вот такой тригер:
CREATE TRIGGER `sts_base1`.`addbase2` AFTER INSERT ON `sts_base1`.`raw20090821`
FOR EACH ROW
BEGIN
    INSERT INTO `sts_base2.stat200908` (`ipin`, `ipout`, `potrin`, `portout`, `in`, `out`)
    VALUES (`NEW.ipin`, `NEW.ipout`, `NEW.potrin`, `NEW.portout`, `NEW.in`, `NEW.out`)
    ON DUPLICATE KEY UPDATE
    `ipin` = VALUES(`NEW.ipin`),
    `ipout` = VALUES(`NEW.ipin`);
END

выдает вот такую ошибку при вставке:
mysql> insert into raw20090821 values ('3', '2', '3', '4', '5', '6');
ERROR 1146 (42S02): Table 'sts_base1.sts_base2.stat200908' doesn't exist
Это понятно что он не может найти таблицу 'sts_base1.sts_base2.stat200908' , но есть таблица 'sts_base2.stat200908' ... откуда он такое берет?

  Ответить  
 
 автор: Valick   (25.08.2009 в 11:30)   письмо автору
 
   для: dimm_kz   (25.08.2009 в 11:25)
 

Вам же сказали, что триггер не будет работать с другим сервером, тогда к чему убивать время на то что в последствии окажется ненужным.

  Ответить  
 
 автор: dimm_kz   (25.08.2009 в 11:34)   письмо автору
 
   для: Valick   (25.08.2009 в 11:30)
 

Бог с ними с серверами... как хотяб на одном сделать...

  Ответить  
 
 автор: Valick   (25.08.2009 в 11:44)   письмо автору
 
   для: dimm_kz   (25.08.2009 в 11:34)
 

я вам ссылку дал, смотрели?
и ещё в последнем номере журнала ][акер меня заинтересовала статья "Да пошел ты, SQL"

  Ответить  
 
 автор: Trianon   (25.08.2009 в 11:50)   письмо автору
 
   для: dimm_kz   (25.08.2009 в 11:25)
 

Может быть всё же `sts_base2`.`stat200908` а не `sts_base2.stat200908` ?
Не факт, правда, что поспособствует, но так как сейчас - явная лажа.

  Ответить  
 
 автор: dimm_kz   (25.08.2009 в 13:14)   письмо автору
 
   для: Trianon   (25.08.2009 в 11:50)
 

не спасла меня ссылка, но исправление на `sts_base2`.`stat200908` выдало новую ошибку, о том, что `sts_base2.stat200908` doesn't exist

  Ответить  
 
 автор: Valick   (25.08.2009 в 14:46)   письмо автору
 
   для: dimm_kz   (25.08.2009 в 13:14)
 

Да что вы так привязались к этим триггерам
Вы же сказали что база будет и так сильно нагружена, а если ещё после каждого инсёрта триггер юзать вам сервак в криогенную камеру останется засунуть. В чём выгода? С тем же успехом можно сразу писать в базу2. (даже КПД выше будет в этом случае)
В моём варианте база в которую сплошным потоком пишется информация используется в качестве буфера, объём этого "буфера" можно подобрать уже во время работы, т.е. выбрать золотую середину.
И весь смысл затеи в том что этот буфер будет периодически очищатся (!)
У вас же база1 будет неимоверно разрастаться от секунды к секунде.
В общем делайте как хотите, я вам не указ. (да и морального права не имею)

  Ответить  
 
 автор: Trianon   (25.08.2009 в 15:11)   письмо автору
 
   для: Valick   (25.08.2009 в 14:46)
 

>Да что вы так привязались к этим триггерам
>Вы же сказали что база будет и так сильно нагружена, а если ещё после каждого инсёрта триггер юзать вам сервак в криогенную камеру останется засунуть. В чём выгода? С тем же успехом можно сразу писать в базу2.

не надо так шипеть.
Я вполне могу предположить, что внешний источник данных просто не умеет делать INSERTы дважды.

  Ответить  
 
 автор: Valick   (25.08.2009 в 15:15)   письмо автору
 
   для: Trianon   (25.08.2009 в 15:11)
 

а я вовсе и не шипеть, наоборот я уже давно превратился в одно большое ухо... и пока что слушаю тишину.
Я вполне могу предположить, что внешний источник данных просто не умеет делать INSERTы дважды.
Если можно скажите в двух словах суть, и как от этого спасает применение базы1.
Пока что я вижу 1 инсёрт и 1 триггер к нему в связке.

  Ответить  
 
 автор: dimm_kz   (25.08.2009 в 16:00)   письмо автору
 
   для: Valick   (25.08.2009 в 15:15)
 

суть такая, что в базу1 будет валиться неотсартированный поток, т.е. все содержание netflow. валиться будет кучно. В последующем обрабатывать такие данные будет крайне долго... для этого данные валятся в базу2 и сортируются по признаку ip, т.е. если совпадает ip-источника и ip-приемникаданные переписываюся. а информация в базе1 раз в 2-3 месяца пакуется и удаляется в архив на 3 года...
> Я вполне могу предположить, что внешний источник данных просто не умеет делать INSERTы дважды.
Именно так и было... я работаю над sql и php частью, в оборудование не лезу, если мне сказали что не может 2 INSERT делать, то и вопросов я больше не задавал... Поток снимается Netflo версии 5, а для него якобы нет каких-то премудростей. Ну да и ладна.
Сложив силы, написал вот такой тригер:

CREATE TRIGGER `sts_base1`.add BEFORE INSERT
 ON raw20090821
 FOR EACH ROW 
begin 
  INSERT INTO `sts_base2`.`stat200908` VALUES (NEW.`ipin`, NEW.`ipout`, NEW.`portin`, NEW.`portout`, NEW.`in`, NEW.`out`)
end

Он работает хорошо.
Не имея в базе PRIMARY KEY вариант с ON DUPLICATE KEY UPDATE отпадает (а жаль). Далее необходимо сделать проверочку. Если совпадают поля ipin и ipout в базе2, то необходимо сделать UPDATE этой строки в базе2, если не савпадают, то INSERT новой строки.

На самом деле, кроме триггеров, для меня сейчас нет доступных вариантов реализации... если есть другое видение картины, будь-те добры, подскажите...

  Ответить  
 
 автор: Trianon   (25.08.2009 в 16:04)   письмо автору
 
   для: dimm_kz   (25.08.2009 в 16:00)
 

Стоп. А что мешает поставить primary key на `sts_base2`.`stat200908`.(`ipin`,`ipout`) ?

  Ответить  
 
 автор: dimm_kz   (25.08.2009 в 16:09)   письмо автору
 
   для: Trianon   (25.08.2009 в 16:04)
 

ipin и ipout не могут быть примари, т.к. ... просто пример: пошел пользователь с ip 192.168.2.2 на ip 10.40.40.2, потом пошел на ip 10.40.40.5, потом на ip 10.40.40.28, ipin остается неменяемым, а ipout меняется

  Ответить  
 
 автор: Valick   (25.08.2009 в 16:38)   письмо автору
 
   для: dimm_kz   (25.08.2009 в 16:09)
 

ipin остается неменяемым, а ipout меняется
но как одно целое, то они уникальны?
Трианон, если не ошибаюсь, говорил о первичном ключе на оба поля.

  Ответить  
 
 автор: Trianon   (25.08.2009 в 17:16)   письмо автору
 
   для: dimm_kz   (25.08.2009 в 16:09)
 

я не предлагал делать праймэри один из них.
Можно сделать составной первичный ключ.
Соответственно, ключом будет 192.168.2.2 - 10.40.40.2

  Ответить  
 
 автор: Valick   (25.08.2009 в 16:16)   письмо автору
 
   для: dimm_kz   (25.08.2009 в 16:00)
 

если мне сказали что не может 2 INSERT делать, то и вопросов я больше не задавал...
а я вот задаю и хочу разобраться в этом.
2 INSERT - речь я так понимаю идёт о инсёрте в одну базу и невозможности повторить этот инсёрт во вторую базу, так?
Я всего лишь пристебался к вашему триггеру только лишь потому что он срабатывает по инсёрту, если бы речь шла о зеркале базы, то никаких вопросов, но это не ваш случай.
Если бы вы стартовали триггер по другому условию (например каждые 1000 инсёртов), то я бы тоже почти не задавал вопросов.
Давайте на пальцах (в лучшем смысле этого слова) поговорим.
в базу 1 летят данные (неважно откуда), назовём их "пакет1"
теперь скажите что делает ваш триггер?
пока, что я вижу, что он кидает этот "пакет1" в базу2

  Ответить  
 
 автор: Valick   (25.08.2009 в 17:21)   письмо автору
 
   для: dimm_kz   (25.08.2009 в 16:00)
 

Важно ли для программиста образное мышление?
Может у меня слишком бурная фантазия, но вот что я вижу в вашем варианте.
Имеются две цистерны, назовём их база1 и база2.
В базу 1 капает эмульсия (например вода с песком), предположим объёмом в одну чайную ложку.
Василий Петрович Триггер наблюдая за процессом попадания эмульсии в цистерну номер один, хватает ложку
наливает туда воды, засыпает песка и доводит это дело до состояния эмульсии (грубо говоря создаёт копию).
Затем бежит к цистерне номер два (база2), у которой на входе стоит сепаратор, кидает туда ложку скопированной
эмульсии и нажимает на кнопку. Затем рвёт когти обратно к цистерне номер один.
В итоге через месяц база1 содержит пару тонн говна эмульсии, в базе2 чистая как слеза вода.
Теперь о моём варианте
(продолжение следует)
___
лирическое отступление о шипении
"Вам может показаться, что мы квакаем, на самом деле песню мы поём"

  Ответить  
 
 автор: Valick   (25.08.2009 в 17:36)   письмо автору
 
   для: Valick   (25.08.2009 в 17:21)
 

Имеем те же самые две цистерны (база1 и база2)
В цистерну номер один капает ложка эмульсии, вторая, третья.. стопятьдесятвторая... и тд.
В это время Иван Михалыч Крон сидит курит, да поглядывает на часы
Звенит будильник и дядя Ваня, нажимает на кнопку базы1 и песок выпадает в осадок, затем выбрасывает песок,
сливает чистую воду в ведро и несёт в цистерну номер два.
В итоге через месяц(а также после каждой ходки дяди Вани) имеем чистую базу1 и базу2 содержащую чистую
как слеза воду (в принципе, там может и спирт оказаться)
А теперь наша задача как заварившего всю эту байду, добиться того чтобы Иван Михалыч Крон
не шастал туда сюда с полуппорожним ведром или не надорвался половиной цистены.

  Ответить  
 
 автор: dimm_kz   (25.08.2009 в 17:44)   письмо автору
 
   для: Valick   (25.08.2009 в 17:36)
 

База1 и база 2 сейчас идентичны, да. Но это только пока я учусь, на самом деле у нетфло очень много полей, а из них мне много не надо

  Ответить  
 
 автор: dimm_kz   (25.08.2009 в 17:48)   письмо автору
 
   для: Valick   (25.08.2009 в 17:36)
 

Ребят, спасибо за дискусии, завтра продолжем, сегодня хэд уже не тот! Спасибо еще раз!

  Ответить  
 
 автор: dimm_kz   (26.08.2009 в 09:27)   письмо автору
 
   для: Valick   (25.08.2009 в 17:36)
 

Гаспада! ну просто огромное вам спасибо! на свежую голову и с вчерашней влитой информацией все пришло само!!! Возможно тригеры не самый лучший вариант реализации, но сейчас он работает и это главное! возможнов дальнейшем всем этим безобразием и будет рулить Иван Михалыч Крон, но пока так))))))))
Для тех кому интересна реализация вот:
CREATE DEFINER=`root`@`localhost` TRIGGER `base1`.add BEFORE INSERT
 ON raw20090821
 FOR EACH ROW 
begin 
 INSERT INTO `base2`.`stat200908` VALUES (NEW.`ipin`, NEW.`ipout`, NEW.`portin`, NEW.`portout`, NEW.`in`, NEW.`out`)
  ON DUPLICATE KEY UPDATE
  `in` = NEW.`in` + `in`,
  `out` = NEW.`out` + `out`;
end

Это при реализации составного первичного ключа полей ipin и ipout

  Ответить  
 
 автор: dimm_kz   (21.01.2010 в 09:26)   письмо автору
 
   для: dimm_kz   (26.08.2009 в 09:27)
 

К сожалению, как показала практика, при активном поступлении данных в базу, имея 2 тригера на обработку, MySQL падает... сэляви...

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования