![]() |
|
Модераторы: LSD |
![]()
|
|
| WolfAlone |
|
|||
![]() В экстазе ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1010 Регистрация: 16.9.2008 Где: Рай Репутация: нет Всего: 5 |
Доброго времени суток!
Стоит задача: перенести какую-то запись "в конец" таблицы. Для этого, на мой взгляд рациональнее всего, просто сменить ID этой записи на последний + 1. Выглядеть всё это будет примерно так:
Но тут сразу же возникает два вопроса: 1. Не случится ли однажды такое, что в один прекрасный момент, сможет затесаться другой конкурентный INSERT-запрос, между SELECT и UPDATE который добавит в таблицу какую-то запись, после чего @max_id уже перестанет значение последнего существующего ID в реальном времени? 2. После того, как я меняю ID какой-то записи на последний + 1, значение счётчика "AUTO INCREMENT" у таблицы не увеличивается! В виду чего, при следующем INSERT'e возникает ошибка о том, что запись с таким номером уже существует! (*при вставке записи, её ID я не указываю, т.к. именно для этого существует автоинкрементное поле [ID]) Первое, что приходит в голову - это изменить ID у всех записей в таблице. Но по моему, это как то не правильно... Если записей будет миллион и нужно будет переместить первую запись в конец таблицы, то предётся изменить ID у миллиона записей!? Возможно, есть какое-то более "красивое" решение? Второе, что пришло в голову - это взять все данные (собрать в массив), удалить ту запись, которую нужно переместить в конец, а затем вставить её снова. Таким образом, обе проблемы отпадают, но... по моему это тоже как-то не совсем правильно! Зачем удалять данные и снова вставлять их же, если они уже есть в таблице? -------------------- И сказал Бог: "Тогда я построю свой мир с блэк-джеком и шлюхами!" Ф топку Ubuntu, Debian наше фсё! (с) Евгений Вольф |
|||
|
||||
| WolfAlone |
|
|||
![]() В экстазе ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1010 Регистрация: 16.9.2008 Где: Рай Репутация: нет Всего: 5 |
*в качестве примера, можно считать, что в роли Сервера БД - выступает MySQL 5.1/5.5
-------------------- И сказал Бог: "Тогда я построю свой мир с блэк-джеком и шлюхами!" Ф топку Ubuntu, Debian наше фсё! (с) Евгений Вольф |
|||
|
||||
| Zloxa |
|
||||
|
Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 11 Всего: 161 |
Случится. Против конкурентного инсерта нет простого приема. MySQL, афайк не поддерживает аналог ораклиных сиквенсов и ФБшных генераторов. Можно похожий механизм реализовать самостоятельно, но тогда, по факту конкурентных инсертов происходить не будет,они будут строго упорядочены. Если два запроса объединить в один и использовать режим изоляции read commited, то конкурентные апдейты сериализуются и не приведут к рассогласованию данных
В этом же случае конкурентый инсерт производить средствами insert into table select coalesce(max(id)+1,1), :fld1, :fld2,:fld3 from table. Так же в режиме изоляции read commited. Но производительность такой вставки будет оставлять желать лучшего и инсерты будут таки не конкурентны а последовательны. нууу о том что дизайн говен, думаю говорить не стоит, вы и сами это видите. -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка |
||||
|
|||||
| Akina |
|
|||
|
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 13 Всего: 454 |
А на мой взгляд, разумнее дополнительное поле, задающее порядок. -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
| WolfAlone |
|
|||
![]() В экстазе ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1010 Регистрация: 16.9.2008 Где: Рай Репутация: нет Всего: 5 |
Zloxa, скажите пожалуйста, если "проблему" попробовать решить вот таким вот образом:
Это даст гарантию того, что никакой конкурентный запрос не "вклинится" и не нарушит целостность данных? -------------------- И сказал Бог: "Тогда я построю свой мир с блэк-джеком и шлюхами!" Ф топку Ubuntu, Debian наше фсё! (с) Евгений Вольф |
|||
|
||||
| Zloxa |
|
|||
|
Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 11 Всего: 161 |
Точно не уверен, я не являюсь экспертом по mysql.
Мне кажется этот запрос таки заблокирует простой инсерт, но я не могу за то поручиться. Практика - критерий истины. ))) Попробойте в одной сессии начать транзакцию, выполнить аптдейт и не коммититься. Во второй сессии, просто выполните простой инсерт. Желателльно в диртириде. Если он встанет на блокировке - радуйтесь )) Тут согласен. ПК для этих целей использовть не гоже. Лучше для этих целей использовать суррогатное поле. Однако же проблема конкурентной модификации ранга все равно останется. -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка |
|||
|
||||
| WolfAlone |
|
|||
![]() В экстазе ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1010 Регистрация: 16.9.2008 Где: Рай Репутация: нет Всего: 5 |
Что-то у меня никак не получается создать 2 одновременных конкурентных запроса, описанных выше. Подскажите пожалуйста ПО для реализации такого эксперемента! *Желательно под винду.
-------------------- И сказал Бог: "Тогда я построю свой мир с блэк-джеком и шлюхами!" Ф топку Ubuntu, Debian наше фсё! (с) Евгений Вольф |
|||
|
||||
| LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 24 Всего: 538 |
Любой SQL клиент у которого можно: - открыть 2 сессии к базе - отключить автокомммит -------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
|||
|
||||
| WolfAlone |
|
||||
![]() В экстазе ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1010 Регистрация: 16.9.2008 Где: Рай Репутация: нет Всего: 5 |
LSD, пробовал SQL Maestro for MySQL и HeidiSQL (то, с чем работаю повседневно). Две сессии открываю в виде двух экзепмляров программы, отключить "автокоммит" и запустить тразакцию пытаюсь вот так:
Результат что-то пока нулевой... В ответ получаю:
Никакой блокировки не происходит. Подозреваю, что что-то я делаю не так. В настройках софта поставил "Keep connection alive", что бы не от отключался/подключался после каждого запроса. -------------------- И сказал Бог: "Тогда я построю свой мир с блэк-джеком и шлюхами!" Ф топку Ubuntu, Debian наше фсё! (с) Евгений Вольф |
||||
|
|||||
| WolfAlone |
|
|||
![]() В экстазе ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1010 Регистрация: 16.9.2008 Где: Рай Репутация: нет Всего: 5 |
Помогите пожалуйста с экспериментом, что-то у меня не получается совсем!
-------------------- И сказал Бог: "Тогда я построю свой мир с блэк-джеком и шлюхами!" Ф топку Ubuntu, Debian наше фсё! (с) Евгений Вольф |
|||
|
||||
| Zloxa |
|
||||||||||
|
Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 11 Всего: 161 |
совершенно не понятно чему там можно не получаться.
У меня нет ни одной инсталляции MySQL, но у меня есть подключение к MS SQL. MS SQL, как и МySQL является блокировочником и, очень вероятно, что они будут работать одинаково. Запускаю интерпарйз манаджер, соединяюсь с базой. Открыаю новое окно. Выполняю.
northwind - демонстрационная база данных, которая разворачивается автоматически, при установке sql сервера. Я создал запись, над которой буду производить эксперименты. Далее, в том же окне
Открываю новое окно, это конкурируюая сессиия. Выполняю
С удовольствием наблюдаю, что insert завис - встал на блокировке. Значит моя гепотеза была верна. Иду в первое окно выполняю
Радостно наблюдаю, что тот инсерт отвис и выполнился повторно выполняю в этом же окне
Радостно наблюдаю что теперь этот запрос завис(встал на блокировке). Перехожу во второе окно, деаю там rollback, это запрос в первом окне завершается, делаю роллбэк и там Резюме - можно пользовать, достаточность serializable доказана. Теперь повторяю этот же эксперимент, но вместо serializable использую read committed. Первый же кейс не приводит к зависанию инсерта. Он происходит успешно, а значит может привести к потере согласованности данных. На момент фиксации транзакции, новоприсвоенный айди в базе уже будет не наибольшим. Резюме - необходимость serializable доказана. Однако все равно не понятно к чему весь этот пляс, если что делать с счетчиком автоинкремента - все равно не понятно. Это сообщение отредактировал(а) Zloxa - 7.7.2011, 09:51 -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка |
||||||||||
|
|||||||||||
| Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 3 Всего: 329 |
Не играйся с ID
|
|||
|
||||
| WolfAlone |
|
|||
![]() В экстазе ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1010 Регистрация: 16.9.2008 Где: Рай Репутация: нет Всего: 5 |
Akella, во истину мудрое решение! Спасибо!
P.S. Вопрос закрыт. -------------------- И сказал Бог: "Тогда я построю свой мир с блэк-джеком и шлюхами!" Ф топку Ubuntu, Debian наше фсё! (с) Евгений Вольф |
|||
|
||||
![]()
|
| Правила форума "Общие вопросы по базам данных" | |
|
|
Данный форум предназначен для обсуждения вопросов о базах данных не попадающих под тематику других форумов:
Данный форум не предназначен для:
Если вы не соблюдаете эти правила, не удивляйтесь потом не найдя свою тему/сообщение.
Полезные советы: Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, LSD, Zloxa. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | СУБД, общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |