|
|
|
Эмуляция autoincrement + паралельные запросы
|
|||
|---|---|---|---|
|
#18+
Есть таблица с записями, упрощенно такая: id (primary, autoincrement) group_id (int) data Нужно группировать записи по полю group_id. То есть, если при вставке group_id не указан, брать максимальное его значение и увеличивать на единицу. Это будет означать создание новой группы. Все кажется нормальным, кроме возможной проблемы с паралельными запросами. Т.е. если два запроса попытаются сделать выборку максимального значения + вставку, то возможно дублирование group_id для не связанных записей, что недопустимо. Даже если использовать транзакцию, где соединить выборку максимального значения group_id и вставку записи с group_id+1, то прийдется блокировать часть строк, что при паралельных транзакциях вернет ошибку для второй транхакции. А этого нужно июеждать. Очевидный вариант с введением дополнительной таблицы не желателен, так как таблиц такого плана в БД очень много и не хотелось бы захламлять ее кучей таблиц с одними только primary key, да и выборку предпочтительнее делать из одной. Надеюсь, я понятно все объяснил. Используется MySQL InnoDB, но теоретически база можен быть перенесена в другую СУБД. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2011, 21:32 |
|
||
|
Эмуляция autoincrement + паралельные запросы
|
|||
|---|---|---|---|
|
#18+
А по какому принципу происходит вставка полей с одинаковым group_id? Т.е. откуда происходит информация о том, что какие-то записи от носятся к одной группе? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2011, 23:09 |
|
||
|
Эмуляция autoincrement + паралельные запросы
|
|||
|---|---|---|---|
|
#18+
miksoftА по какому принципу происходит вставка полей с одинаковым group_id? Т.е. откуда происходит информация о том, что какие-то записи от носятся к одной группе? Этот справедливый вопрос основан, вероятно, на вот этом предложении из исходного сообщения: "Т.е. если два запроса попытаются сделать выборку максимального значения + вставку, то возможно дублирование group_id для не связанных записей, что недопустимо ." ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2011, 10:01 |
|
||
|
Эмуляция autoincrement + паралельные запросы
|
|||
|---|---|---|---|
|
#18+
Рубик3 Очевидный вариант с введением дополнительной таблицы не желателен, так как таблиц такого плана в БД очень много и не хотелось бы захламлять ее кучей таблиц с одними только primary key, да и выборку предпочтительнее делать из одной. Во-первых, зачем "куча"? Вам принципиально, будет у Вас 1,2,3 или 1,3,6? (Правда конкуренция возрастает для извлечения этой мифической группы). Во-вторых, это же одно удовольствие использовать очевидный вариант:) Почему "захламлять" БД "записями" можно, а "таблицами" нельзя? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2011, 10:11 |
|
||
|
Эмуляция autoincrement + паралельные запросы
|
|||
|---|---|---|---|
|
#18+
Рубик3то прийдется блокировать часть строк, что при паралельных транзакциях вернет ошибку для второй транхакции. Уверены? Обычным и общепринятым поведением в этом случае является ожидание второй транзакцией снятия блокировки. А вообще без блокировок, явных или неявных, либо без применения сугубо специфичных механизмов эта задача не решается. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2011, 17:22 |
|
||
|
Эмуляция autoincrement + паралельные запросы
|
|||
|---|---|---|---|
|
#18+
авторА по какому принципу происходит вставка полей с одинаковым group_id? Т.е. откуда происходит информация о том, что какие-то записи от носятся к одной группе? Эта система для хранения истории изменений записей. То есть group_id - это одна запись, для которой есть несколько версий из которых только одна актуальная. Когда добавляется новая запись - добавляется строка с новым group_id, когда запись изменяется - добавляется строка с существующим group_id. авторВо-первых, зачем "куча"? Будет применено для многих таблиц, не считал точно сколько, но не меньше 10. авторВо-вторых, это же одно удовольствие использовать очевидный вариант:) Почему "захламлять" БД "записями" можно, а "таблицами" нельзя? Да вообщем-то не хочется захламлять не записями не таблицами :) А еще очень не хочется это все потом переделывать, если всплывет более красивое решение :) авторУверены? Обычным и общепринятым поведением в этом случае является ожидание второй транзакцией снятия блокировки. Не уверен :) Но блокировки, тоже, не желательны, так как может быть автоматическое добавление большого числа записей, да и вообще, блокировки - куча лишних проблем с производительностью. Видимо придется все-таки делать дополнительные таблицы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2011, 04:51 |
|
||
|
Эмуляция autoincrement + паралельные запросы
|
|||
|---|---|---|---|
|
#18+
Рубик3 Будет применено для многих таблиц, не считал точно сколько, но не меньше 10. Опять Вы про каких-то "много таблиц":) Я же говорю, что таблица может быть одна. Еще раз: Вам принципиально, будет у Вас group_id в конкретной "таблице с записями" 1,2,3 или 1,3,6? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2011, 10:15 |
|
||
|
Эмуляция autoincrement + паралельные запросы
|
|||
|---|---|---|---|
|
#18+
Рубик3 Видимо придется все-таки делать дополнительные таблицы. А может быть таблицУ, а не таблицЫ:) В которой можно хранить ОДНУ ЗАПИСЬ. Все зависит от реальной нагрузки. Одна таблица с одним атрибутом и одной записью. Вот и весь хлам:) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2011, 10:22 |
|
||
|
Эмуляция autoincrement + паралельные запросы
|
|||
|---|---|---|---|
|
#18+
Рубик3 Но блокировки, тоже, не желательны, так как может быть автоматическое добавление большого числа записей, да и вообще, блокировки - куча лишних проблем с производительностью. Видимо придется все-таки делать дополнительные таблицы. Блокировки при извлечении значения "идентификатора группы" все равно будут. В решении с одной таблицей, одним атрибутом и одной записью нет никаких "ключей", что, может быть, повысит производительность. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2011, 10:42 |
|
||
|
Эмуляция autoincrement + паралельные запросы
|
|||
|---|---|---|---|
|
#18+
БредятинаОпять Вы про каких-то "много таблиц":) Я же говорю, что таблица может быть одна. Еще раз: Вам принципиально, будет у Вас group_id в конкретной "таблице с записями" 1,2,3 или 1,3,6? Это, конечно чуть быстрее, чем определять максимальное значение group_id, но в целом не решает проблему - нужны те же транзакции, блокировки. Хотя, одна лишняя таблица лучше 10-ти, но это не добавляет понятности. С третьей таблицей, где одно поле-ключ с заполнением group_id как-то логичнее и может даже в некоторых случаях будет что туда сунуть дополнительно. БредятинаБлокировки при извлечении значения "идентификатора группы" все равно будут. В решении с одной таблицей, одним атрибутом и одной записью нет никаких "ключей", что, может быть, повысит производительность. Вставка с автоинкрементом все-равно будет быстрее чем транзакция на select и udate с блокировкой, пусть даже в очень маленькой таблице. Какие-то блокировки есть, конечно, и на автоинкремент, но мне кажется, что они значительно более оптимизированы, чем такие транзакции и все-таки позволяют выполнять параллельные insert-запросы. В общем, я кажется уже принял решение, спасибо всем за ответы и разъяснения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2011, 16:19 |
|
||
|
|

start [/forum/topic.php?fid=32&msg=37061085&tid=1542350]: |
0ms |
get settings: |
7ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
413ms |
get topic data: |
9ms |
get forum data: |
3ms |
get page messages: |
35ms |
get tp. blocked users: |
1ms |
| others: | 222ms |
| total: | 711ms |

| 0 / 0 |
