Консультация № 171069
05.08.2009, 08:39
0.00 руб.
0 6 1
Уважаемые эксперты.
В mysql создал таблицу, в которой одно из полей типа INT назначено ключевым, ему назначен атрибут AUTOINCREMENT.
Сначала я добавил несколько записей, потом удалил некоторые из них. Потом добавил их снова. Проблема в том, что ключевое поле в моей таблице принимает значения:
1
2
3
8
20
21
22
23
50
...

Что произойдет, когда значение ключевого поля благодаря автоинкременту перейдет границу 32768?

Обсуждение

Неизвестный
05.08.2009, 11:02
общий
это ответ
Здравствуйте, Warobushek.

На самом деле у типа INT граница не 32768 (SMALLINT 2 байта), а 2 147 483 647 (4 байта), если вам и этого не хватит то можно использовать 8ми байтовый BIGINT (граница 9 223 372 036 854 775 808 )

http://php-mysql.h1.ru/m_number.php
Неизвестный
05.08.2009, 12:49
общий
Действительно с диапазоном я напутал, но все же что произойдет когда будет выход за диапазон? можно ли как нибудь заполнить пробелы в значениях ключа?
Неизвестный
05.08.2009, 12:58
общий
Warobushek:
Вот тут ничего сказать не могу... Я никогда не достигал границы инта... Проведи эксперимент: поставь на инкремент TINYINT и вбивай. До границы там недалеко, вот и у видишь наглядно.
Неизвестный
10.08.2009, 19:08
общий
не в курсе с MS SQL и MySQl, а в MS Access при сжатии базы данных максимальное значение автоинкремента берется по фактическому максимальному значению в базе, т.е. если записи с кодами 48, 49,50 и 51 удалены и они были последними, то новой строке будет присвоено значение 48.
в своих программах я стараюсь не использовать автоинкремент - присваиваемое значение не зависит от пользователя. поэтому просто ищу максимальное значение ( а еще лучше первое неиспользуемое, но тогда нужно начинать сканирование и поиск с 1 - долго, но в таком случае возможно использование и удаленных значений ) и присваиваю новой записи следующее. это удобно, когда значения вносятся сразу в несколько таблиц и это ключевое поле является для других таблиц главным.
ну а по поводу используемого формата числового поля, то здесь все зависит от конкретных задач. у меня есть таблицы, в которых ключевое поле типа байт - 255 значений. но если задача поставлена не конкретно и есть шанс переполнения, то лучше перестраховаться. в этом случае тип INT с его 2млрд значений подойдет. ну а использование 4 байт для записи поля в настоящее время неактуально - дисковое пространство практически неограничено.
как пример, могу привести реальную работающую в настоящее время у нас задачу, которая писалась под i286 на Foxprox. там ключевое поле создано из трех символов. в обработку идет код этих символов. в итоге, если отбросить управляющие символы и использовать начиная с пробела ( код 20H ) , то первый код будет " !" ( 20H 20H 21H ) и общее количество вариантов ограничено 224*224*224=11239424. это было сделано из-за того, что Foxprox хранит числа в явном виде, т.е. для записи числа 11млн потребовалось бы 8 байт дискового пространства, а не 3. в условиях 20-ти мегабайтных винчестеров выигрых ощутим.
Неизвестный
10.08.2009, 19:11
общий
а ошибка, в теории, выскочит простая - "Переполнение"
Неизвестный
11.09.2009, 21:41
общий
Warobushek:
можно сделать проще.. если на этот ключ нет ссылок больше из других таблиц, то просто снимаем с этого поля атрибут автоинкримента, после чего задаём ему NULL (например)
UPDATE NYTABLE SET POLE_ID = NULL; COMMIT;
после чего опять назначаем ему атрибут автоинкримента - сформируется сам, заполнив последовательность без пропусков.
Если есть ссылки на данное поле, то сложнее, хотя и тут методом шаманских действий можно решить вопрос.
Но.. честно говоря, в реальной базе достич такого значения при вашей жизни весьма не просто думаю.. :)
Если писать каждую секунду, то потребуется 292 471 208 677,54 лет а если допустить что пишется 100 раз в секунду (фантистика не выполнимая), то это будет 2 924 712 086,78 лет.. Вы уверены что переживете этот период?

Форма ответа