|
|
|
Уникальный номер (нестандартный autoincrement), нужен совет
|
|||
|---|---|---|---|
|
#18+
Нужно реализовать запрос для сохранения записи в таблице. Причем не должно возникать конфликтных ситуаций под нагрузкой. Формат таблицы: cat | id | data... (`cat`, `id`) - уникальный ключ. Например, в таблице такие данные: 1 | 1 | data... 1 | 2 | data... 1 | 3 | data... 1 | 4 | data... 1 | 5 | data... 2 | 1 | data... 3 | 1 | data... 3 | 2 | data... В момент сохранения известен только `cat` , а `id` должен быть получен следующий для данного `cat`. При использовании подзапроса, например, (SELECT max(id) WHERE cat=3) нет гарантий, что не будет конфликта, если одновременно будет выполняться несколько INSERTов разных пользователей. Предполагается, что одновременно может выполняться множество таких запросов :) Есть ли более оптимальное решение этой проблемы? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2010, 19:12:33 |
|
||
|
Уникальный номер (нестандартный autoincrement), нужен совет
|
|||
|---|---|---|---|
|
#18+
myproga, 1. серилизовать доступ к раздатчику ИД -- например сериализе в жаве 2. предпологаю (неплохо бы доказать) что такой вариант будет атомарно-безопасным: insert into ABC values (new_val1, new_val2, (select max(id) from ABC where cat=CAT1) + 1) если будет ругатся про мутируюшую таблицу, то сделать ето в подселекте 3. перестроить схему на использование сквозной нумерации и добавить неосновное поле для порадка внутри категории. Ето поле можно будет подзаполнять потом , например ночью без нагрузки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2010, 19:37:38 |
|
||
|
Уникальный номер (нестандартный autoincrement), нужен совет
|
|||
|---|---|---|---|
|
#18+
myproga, Код: plaintext 1. 2. 3. 4. При вставке NULL в id будет выбрано следующее значение в соответствующей ветке бинарного дерева ключа PK. Работает только с MYISAM! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2010, 19:45:32 |
|
||
|
Уникальный номер (нестандартный autoincrement), нужен совет
|
|||
|---|---|---|---|
|
#18+
Работает только с MYISAM А с InnoDB? перестроить схему на использование сквозной нумерации Только как крайняя мера, если решить иначе не удастся. предпологаю (неплохо бы доказать) что такой вариант будет атомарно-безопасным Собственно, меня безопасность подобного варианта (как я и писал в первом сообщении) и интересует, если нет более оптимальных решений. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2010, 19:52:55 |
|
||
|
Уникальный номер (нестандартный autoincrement), нужен совет
|
|||
|---|---|---|---|
|
#18+
myprogaА с InnoDB?А с InnoDB это даже смысла не имеет, т.к. он транзакционный. Допустим в какой-то транзакции будет вставлена запись, после этого в других транзакциях будут вставлены и закоммичены еще несколько записей. А после этого, вдруг, первая транзакция откатывается. Спрашивается, что тогда делать? Апдейтить все более поздние записи? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2010, 20:44:47 |
|
||
|
Уникальный номер (нестандартный autoincrement), нужен совет
|
|||
|---|---|---|---|
|
#18+
myproga, нтуитивно бы хотелось чтоб етот вариант было атомарным: надо внимательно перечитать здесь. Похоже что в последнем коменте указано что табл1 лочится: http://dev.mysql.com/doc/refman/5.1/en/concurrent-inserts.html ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2010, 20:51:08 |
|
||
|
Уникальный номер (нестандартный autoincrement), нужен совет
|
|||
|---|---|---|---|
|
#18+
miksoft, авторСпрашивается, что тогда делать? Апдейтить все более поздние записи? При откате образуется пропуск в `id`. Ничего обновлять не надо, как и при использовании стандартного autoincrementа. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2010, 20:52:56 |
|
||
|
Уникальный номер (нестандартный autoincrement), нужен совет
|
|||
|---|---|---|---|
|
#18+
myprogamiksoft, авторСпрашивается, что тогда делать? Апдейтить все более поздние записи? При откате образуется пропуск в `id`. Ничего обновлять не надо, как и при использовании стандартного autoincrementа.А тогда какой вообще смысл в этом поле? Используйте штатный AUTO_ICREMENT и считайте что у него просто много пропусков. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2010, 20:55:50 |
|
||
|
Уникальный номер (нестандартный autoincrement), нужен совет
|
|||
|---|---|---|---|
|
#18+
А тогда какой вообще смысл в этом поле? Используйте штатный AUTO_ICREMENT и считайте что у него просто много пропусков. Смысл - в инкрементации `id` начиная с 1 для каждого `cat`. Важен порядковый номер добавленного элемента для конкретного `cat`. Это имеет значение, иначе бы я не писал. javajdbc, По ссылке про MYISAM... Там про insert select из разных таблиц, но теоретически должно так работать и в этом случае. Но пока нет достоверного подтверждения, к сожалению. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2010, 21:16:07 |
|
||
|
Уникальный номер (нестандартный autoincrement), нужен совет
|
|||
|---|---|---|---|
|
#18+
myprogaСмысл - в инкрементации `id` начиная с 1 для каждого `cat`.Транзакция с единицой так же может откатиться. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2010, 21:21:13 |
|
||
|
Уникальный номер (нестандартный autoincrement), нужен совет
|
|||
|---|---|---|---|
|
#18+
miksoft, Транзакция с единицой так же может откатиться. Все это конечно не очень хорошо, но вероятность отката очень низкая . К тому же, любой из добавленных элементов может быть удален в будущем . Если где-то и будет несколько пропусков, то ничего "очень страшного" не случится. Меня больше волнует безопасность одновременного добавления. Достоверной информации о том, не будет ли такого случая, пока нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2010, 21:33:32 |
|
||
|
Уникальный номер (нестандартный autoincrement), нужен совет
|
|||
|---|---|---|---|
|
#18+
myprogaМеня больше волнует безопасность одновременного добавления. Достоверной информации о том, не будет ли такого случая, пока нет.Наложите на эти два поля уникальный индекс и ловите в клиенте исключение. Как поймаете - прибавляйте единицу, подождите случайное время и вставляйте снова. И так по кругу, пока либо не произойдет успешная вставка, либо не исчерапается количество попыток/время. А еще можно блокировать всю таблицу, но это слишком банальный способ :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2010, 21:40:31 |
|
||
|
Уникальный номер (нестандартный autoincrement), нужен совет
|
|||
|---|---|---|---|
|
#18+
miksoft, Наложите на эти два поля уникальный индекс и ловите в клиенте исключение. Как поймаете - прибавляйте единицу, подождите случайное время и вставляйте снова. И так по кругу, пока либо не произойдет успешная вставка, либо не исчерапается количество попыток/время. А еще можно блокировать всю таблицу Очень нерациональные способы :) Тогда мне проще использовать MYISAM и написать примитивную поддержку транзакций :D ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2010, 21:47:29 |
|
||
|
Уникальный номер (нестандартный autoincrement), нужен совет
|
|||
|---|---|---|---|
|
#18+
myprogaТогда мне проще ... написать примитивную поддержку транзакций :DЭто вы сильно заблуждаетесь. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2010, 21:53:08 |
|
||
|
Уникальный номер (нестандартный autoincrement), нужен совет
|
|||
|---|---|---|---|
|
#18+
miksoft, Это вы сильно заблуждаетесь. Может быть, но в эту тему не вникал пока и, думаю, не придется :) Должно быть какое-то простое решение. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2010, 22:00:11 |
|
||
|
Уникальный номер (нестандартный autoincrement), нужен совет
|
|||
|---|---|---|---|
|
#18+
myproga, Думается мне, что средствами MySQL и без общей точки блокировки желаемое не реализуемо. Придется либо использовать внешние средства, либо идти на какой-то компромисс. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2010, 22:43:18 |
|
||
|
Уникальный номер (нестандартный autoincrement), нужен совет
|
|||
|---|---|---|---|
|
#18+
myproga, Я тут задумывал серию статей на тему эмуляции SEQUENCE в MySQL, но по лени оно осталось в недоделанном состоянии - написал только две части из 4-х. Но зато рассмотрел, как работает Innodb со счетчиками в таблицах (попытка сделать подобие вышеописанной фичи MYISAM). Если интересно, то можно ознакомиться здесь: Эмуляция SEQUENCE. / На базе INNODB и транзакций. _ Недостатки: * Другие сессии, которые будут работать с этой строкой, заблокируются в вызове nextval. * Другие сессии, использующие режим изоляции READ COMMITTED, не будут видеть наших изменений до завершения нашей транзакции, но и не будут блокироваться, и вызов nextval вернет то же самое значение, что и в нашей сессии. Т.е., все пользователи нашего генератора последовательностей должны работать в режиме REPEATABLE READ. В режиме READ COMMITTED наша конструкция неработоспособна совсем. Если совсем лениво читать, то скажу, что с транзакционными базами такие конструкции лучше не делать - ненадежно, а то и неработоспособно. Кстати, от пропусков это тоже не избавит. Т.ч. единственно верно - использовать id по назначению - как id, а не как порядковый номер. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2010, 09:49:06 |
|
||
|
Уникальный номер (нестандартный autoincrement), нужен совет
|
|||
|---|---|---|---|
|
#18+
RXL, вот здесь тоже задумывались... там в комментах интересные мысли насчет 1. ALTER TABLE 2.INSERT/DELETE where WHERE s.name = p_name; (как раз если использовать фичу MyIsam указанную выше) Короче - есть плацдарм для экпериментов, все надо тестировать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2010, 13:10:05 |
|
||
|
Уникальный номер (нестандартный autoincrement), нужен совет
|
|||
|---|---|---|---|
|
#18+
Alex_UstinovRXL, вот здесь тоже задумывались... там в комментах интересные мысли насчет 1. ALTER TABLE 2.INSERT/DELETE where WHERE s.name = p_name; (как раз если использовать фичу MyIsam указанную выше) Короче - есть плацдарм для экпериментов, все надо тестироватьМожете поподробнее описать, что вы там разглядели полезного для топикстартера? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2010, 13:17:07 |
|
||
|
Уникальный номер (нестандартный autoincrement), нужен совет
|
|||
|---|---|---|---|
|
#18+
я отвечал RXL по поводу его ссылки. сразу оговорюсь - сам не экпериментировал. Идея навскидку такова (если у ТС InnoDB): создать таблицу-клон MyIsam с primary(cat,id) и доставать id из нее (так как в InnoDB невозможно создать составной PRIMARY) INSERT SELECT Last_Insert_Id(). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2010, 14:54:02 |
|
||
|
Уникальный номер (нестандартный autoincrement), нужен совет
|
|||
|---|---|---|---|
|
#18+
Alex_UstinovИдея навскидку такова (если у ТС InnoDB): создать таблицу-клон MyIsam с primary(cat,id) и доставать id из нее (так как в InnoDB невозможно создать составной PRIMARY) INSERT SELECT Last_Insert_Id().Это будет общая точка блокировки. Имхо, ничем не лучше просто блокировки исходной таблицы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2010, 14:59:37 |
|
||
|
Уникальный номер (нестандартный autoincrement), нужен совет
|
|||
|---|---|---|---|
|
#18+
исходя из топиков ТС выше - речь о InnoDB, для МайИСАМ путь указали. Вот чтобы на клиенте не прибавлять +1 - можно таким макаром генерить для InnoDB. И по сути вопроса. Вы думаете что SEQUENCE в DB2-Oracle-PostgeSQL не тормозят INSERT? Или AUTO_INCREMENT работает без блокировки "самого себя". Дыма без огня не бывает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2010, 15:15:00 |
|
||
|
Уникальный номер (нестандартный autoincrement), нужен совет
|
|||
|---|---|---|---|
|
#18+
Если мы заговорили об Innodb, то не будем забывать про implicit commit! По этой причине отпадает и DDL (ALTER TABLE), и LOCK TABLE. Можно попробовать блокировки с функциями GET_LOCK/RELEASE_LOCK и хранить счетчики в MYISAM табличке. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2010, 15:25:06 |
|
||
|
Уникальный номер (нестандартный autoincrement), нужен совет
|
|||
|---|---|---|---|
|
#18+
RXLЕсли мы заговорили об Innodb, то не будем забывать про implicit commit! По этой причине отпадает и DDL (ALTER TABLE), и LOCK TABLE.LOCK TABLE не совсем отпадает, его можно вынести в начало транзакции. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2010, 15:36:56 |
|
||
|
|

start [/forum/topic.php?fid=47&msg=36515045&tid=1832355]: |
0ms |
get settings: |
6ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
425ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
40ms |
get tp. blocked users: |
1ms |
| others: | 190ms |
| total: | 691ms |

| 0 / 0 |
