Ru-MaNGOS

Ru-MaNGOS (http://mangos.ytdb.ru/index.php)
-   Tools (http://mangos.ytdb.ru/forumdisplay.php?f=22)
-   -   DataBase GUID sorter (http://mangos.ytdb.ru/showthread.php?t=3234)

Sid 17.12.2010 10:27

DataBase GUID sorter
 
Сразу прошу помидорами не кидаться :) Программиринг в стадии изучения :)
Давно еще хотел навести порядок в базе в таблицах связанных по ключевым полям GUID (например characters и от нее зависящие character_* или creature и creature_*) смысл понятен. Иногда, или даже постоянно если много работаешь с базой, появляются пробелы в гуидах и они приобретают колоссальные значения :)
Программка создает темповое поле в которое перезаписывает исходные GUID'ы в инкрементальном порядке от 1 и до значения которое выдаст запрос COUNT(*) :) Одновременно сопоставляя GUID'ы из указанных зависящих таблиц, так же создает темповое поле и записывает на него соответствующие новые GUID'ы. По окончании выполнения, удаляет из зависящих таблиц записи у которых темповое поле оказалось равным 0 (значит гуид не существует в исходной таблице) и заменяет старое guid поле на то что получилось в темповом.

Мда, не умею я красиво объяснять, но как есть :)

В итоге что пока умеет:
- Поддержка до 5 таблиц, однако можно в коде выставить больше кто желает.
- Поддержка 2 полей в PRI KEY.

Как работает:
1) Запускаем, вводим данные для соединения с базой (как правило нужен юзер с доступом на ALTER запрос.)
2) После соединения с бд вводим setvar и указываем переменные.
3) Вводим start и ждем (чем больше зависящих таблиц и записей тем дольше работает)

Скриншот результата:


Сейчас пока альфа тестовая версия консольная, позже сделаю на Qt4.

Исходники https://github.com/sidsukana/dbsorter
Релизный бинарник https://github.com/downloads/sidsuka...er_Release.zip

Спасибо за внимание :)

virusav 17.12.2010 10:34

Перенумерацию гуидов можно сделать средствами базы данных.

Sid 17.12.2010 10:41

Хм, не знал даже)) А соответствие значений в других таблицах база тоже может сделать?

virusav 17.12.2010 11:05

Со старого форума базы YTDB:
Цитата:

Сообщение от virusav (Сообщение 15208)
Восстанавливаю тему со старого форума.

Перенумерация гуидов в таблицах `creature` и `gameobject`, а также во всех связанных таблицах.

Для `creature`:
Код:

DROP TRIGGER IF EXISTS `creature_after_update`;
CREATE TRIGGER `creature_after_update` AFTER UPDATE ON `creature`
FOR EACH ROW BEGIN
UPDATE `creature_addon` SET `guid`=NEW.guid WHERE `guid`=OLD.guid;
UPDATE `creature_movement` SET `id`=NEW.guid WHERE `id`=OLD.guid;
UPDATE `game_event_creature` SET `guid`=NEW.guid WHERE `guid`=OLD.guid;
UPDATE `game_event_creature_quest` SET `id`=NEW.guid WHERE `id`=OLD.guid;
UPDATE `npc_gossip` SET `npc_guid`=NEW.guid WHERE `npc_guid`=OLD.guid;
UPDATE `pool_creature` SET `guid`=NEW.guid WHERE `guid`=OLD.guid;
UPDATE `creature_battleground` SET `guid`=NEW.guid WHERE `guid`=OLD.guid;
END;
SELECT 0 INTO @temp_var;
UPDATE `creature` SET `guid`=1000000 WHERE `guid`=0;
UPDATE `creature` SET `guid`=@temp_var:=@temp_var+1 ORDER BY `guid` ASC;
DROP TRIGGER IF EXISTS `creature_after_update`;

Для `gameobject`:
Код:

DROP TRIGGER IF EXISTS `gameobject_after_update`;
CREATE TRIGGER `gameobject_after_update` AFTER UPDATE ON `gameobject`
FOR EACH ROW BEGIN
UPDATE `event_scripts` SET `datalong`=NEW.guid WHERE `datalong`=OLD.guid AND `command` IN (9,11,12,13);
UPDATE `game_event_gameobject` SET `guid`=NEW.guid WHERE `guid`=OLD.guid;
UPDATE `gameobject_scripts` SET `id`=NEW.guid WHERE `id`=OLD.guid;
UPDATE `gameobject_scripts` SET `datalong`=NEW.guid WHERE `datalong`=OLD.guid AND `command` IN (9,11,12,13);
UPDATE `pool_gameobject` SET `guid`=NEW.guid WHERE `guid`=OLD.guid;
UPDATE `quest_start_scripts` SET `datalong`=NEW.guid WHERE `datalong`=OLD.guid AND `command` IN (9,11,12,13);
UPDATE `quest_end_scripts` SET `datalong`=NEW.guid WHERE `datalong`=OLD.guid AND `command` IN (9,11,12,13);
UPDATE `spell_scripts` SET `datalong`=NEW.guid WHERE `datalong`=OLD.guid AND `command` IN (9,11,12,13);
UPDATE `gameobject_battleground` SET `guid`=NEW.guid WHERE `guid`=OLD.guid;
END;
SELECT 0 INTO @temp_var;
UPDATE `gameobject` SET `guid`=1000000 WHERE `guid`=0;
UPDATE `gameobject` SET `guid`=@temp_var:=@temp_var+1 ORDER BY `guid` ASC;
DROP TRIGGER IF EXISTS `gameobject_after_update`;

Если надо сделать автоинкременты в этих таблицах и сбросить их, то после перенумерации:
Код:

ALTER TABLE `creature` CHANGE COLUMN `guid` `guid` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `creature` AUTO_INCREMENT=1;
ALTER TABLE `gameobject` CHANGE COLUMN `guid` `guid` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `gameobject` AUTO_INCREMENT=1;

Список таблиц можно пополнить в любой момент.


selector 18.12.2010 19:24

virusav возможно ли такое сделать с чарами. Например гуиды в item_instance зашкаливают(уже триллионы пошли), да и таблицу characters надо бы упорядочить. Проблема лишь в удаленных чарах(которых можно восстановить через .char deleted restore). У них нуиды и все сбито(нули)

KiriX 18.12.2010 19:48

Цитата:

Сообщение от selector (Сообщение 17306)
virusav возможно ли такое сделать с чарами. Например гуиды в item_instance зашкаливают(уже триллионы пошли), да и таблицу characters надо бы упорядочить. Проблема лишь в удаленных чарах(которых можно восстановить через .char deleted restore). У них нуиды и все сбито(нули)

Можно и когда-то где-то было.
У удалённых сбито потому что присваивается при заливке всё новое ;)

virusav 18.12.2010 19:52

Можно взять приведенные запросы за основу и подставить названия нужных таблиц.
Главное - не забыть указать все связанные таблицы.

PSZ 19.12.2010 01:13

Для более-менее старого сервера да еще и с большим онлайном скорее всего такое упорядочивание загнет mysql на пару суток :)

virusav 19.12.2010 10:00

Не согласен.

Если, например, 1к персов, 10к записей в связанных таблицах, то получим 11к запросов UPDATE, что будет выполняться не очень долго.

rsa 19.12.2010 10:18

По хорошему этим ядро должно заниматься. FindFirstFreeGuid - и далее заполнять не по следующему а по первому свободному. Иначе это принципиальный затык на переполнении (хотя и не скоро).

Кот ДаWINчи 19.12.2010 12:22

Цитата:

Сообщение от rsa (Сообщение 17318)
По хорошему этим ядро должно заниматься. FindFirstFreeGuid - и далее заполнять не по следующему а по первому свободному. Иначе это принципиальный затык на переполнении (хотя и не скоро).

согласен, хотя есть такая не хорошая тема для раздумий. У пользователя третье лицо ради шутки стирает персонажа. Бедный пользователь пишет сквозь слезы письмо админу, мол восстанови мне любимого перса.... а гуид уже занят...
Может при удалении в базу заносить дату и гуид удаления персонажа, и несколько дней не трогать этот гуид.

virusav 19.12.2010 13:25

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

rsa 19.12.2010 14:06

Цитата:

Сообщение от Кот ДаWINчи (Сообщение 17320)
согласен, хотя есть такая не хорошая тема для раздумий. У пользователя третье лицо ради шутки стирает персонажа. Бедный пользователь пишет сквозь слезы письмо админу, мол восстанови мне любимого перса.... а гуид уже занят...
Может при удалении в базу заносить дату и гуид удаления персонажа, и несколько дней не трогать этот гуид.

именно эта проблема уже полгода как в ядре решена. количество дней настраивается в конфиге.

PSZ 19.12.2010 19:27

Цитата:

Сообщение от virusav (Сообщение 17317)
Не согласен.

Если, например, 1к персов, 10к записей в связанных таблицах, то получим 11к запросов UPDATE, что будет выполняться не очень долго.

Это какой-то очень мелкий сервер ). У меня, например, сервер тоже, я считаю, маленький (100-150 онлайна), в таблице чаров - около 30к записей. А связанных - так вообще караул. А что говорить о тех, у кого более 1000 онлайна...

virusav 19.12.2010 19:33

Запросы на обновление выполняются довольно быстро.
Как-то по работе надо было делать несколько тысяч UPDATE, тоже думали, что будет долго.

Главное - правильно расставить ключи, если их нет.

Уже не раз убеждался, что операции с большим объемом данных лучше делать средствами самого MySQL.

Sid 19.12.2010 21:59

Ну, у меня по изучении с++ стояла задача сделать все на стороне программы :) Вкачиваем скил ненужным софтом так сказать :). А за запросы, спасибо!

tempura 20.12.2010 10:06

По программированию - ЗОЧОД. :)

А по поводу "надо - не надо" - дело десятое. Кому-то может и пригодится. :)


Текущее время: 12:20. Часовой пояс GMT +3.

ru-mangos.ru - Русское сообщество MaNGOS