Гарантировано ли увеличение номера AutoNumber (приращения) в Access? - PullRequest
1 голос
/ 20 апреля 2009

Для конкретной таблицы у меня в поле идентификатора установлено значение AutoNumber (Увеличение). Если я добавлю 5 строк в эту таблицу в быстрой последовательности, будет ли гарантировано, что у каждой будет больший идентификатор, чем у последней? Например, восстанавливается ли когда-либо автонумерация с 1, если некоторые более ранние значения были удалены?

Ответы [ 9 ]

3 голосов
/ 20 апреля 2009

К сожалению, даже приложения Microsoft не являются безошибочными. Но это способ, которым он предназначен для работы, и я не видел, чтобы он потерпел неудачу; и не слышал об этом, если не считать намеренной или случайной подрывной деятельности.

Только не ожидайте, что в нем будет строка для каждого целочисленного значения. В дополнение к удаленным строкам он будет использовать числа для операций добавления, которые не выполняются.

3 голосов
/ 20 апреля 2009

Единственный раз, когда у меня возникали проблемы с автонумерами Access, это когда по ошибке я устанавливал значение поля ключа автонумерации на число ниже текущего максимума, используя запрос на добавление. Пробелы в нумерации создавались путем удаления записей. Доступ позволяет принудительно ввести значение в поле автонумерации, и иногда (не всегда, и я не знаю, почему) автонумерация сбрасывается до меньшего числа. В конце концов, когда записи были добавлены, я столкнулся с ошибками «дубликата ключа». Кроме этого, у меня никогда не было проблем за многие годы.

Есть несколько ответов на этот вопрос, в которых говорится о величине приращения. Насколько я знаю, поле имени автонумера Access может быть установлено только в «Увеличение» (на 1) или «Случайное», и нет никакого способа установить числовое приращение, отличное от 1. Если я ошибаюсь, просим я.

2 голосов
/ 22 апреля 2009

Дэвид У. Фентон писал: «Поле Jet Autonumber не является полем идентификации. Это только длинное целое поле со специальным значением по умолчанию. Это значение по умолчанию может быть INCREMENT или RANDOM, но так как это только значение по умолчанию , вы можете добавить любое длинное целое значение в поле, если оно не нарушает индекс. "

Это немного запутано. Синтаксис ACE / Jet SQL имеет ключевое слово IDENTITY (COUNTER, AUTOINCREMENT), но не имеет ключевого слова AUTONUMBER. Очевидно, что ACE / Jet IDENTITY является IDENTITY!

Но то, что я хочу рассмотреть здесь (слишком долго для комментария), является искажением того, что это «только длинное целое поле со специальным значением по умолчанию».

Рассмотрим этот DDL ACE / Jet SQL (синтаксис режима запросов ANSI-92):

CREATE TABLE Test2_IDENTITY
(
   ID_identity_1 IDENTITY NOT NULL, 
   ID_identity_2 IDENTITY NOT NULL, 
   data_column INTEGER
);

При выполнении происходит сбой с сообщением «Результирующей таблице не разрешено иметь более одного поля AutoNumber». Очевидно, что здесь происходит нечто иное, чем «специальное значение по умолчанию».

Ключевое слово IDENTITY создает автономное число (при отсутствии лучшего термина) с алгоритмом увеличения для генерации значений. IDENTITY нельзя использовать для создания автономного номера со случайным алгоритмом или разновидностью идентификатора GUID (идентификатора репликации). Для этих других случаев вам действительно необходимо использовать «специальное значение по умолчанию», например,

CREATE TABLE TestAutonumbers 
(
   ID_identity IDENTITY NOT NULL, 
   ID_random INTEGER DEFAULT GenUniqueID() NOT NULL, 
   ID_guid UNIQUEIDENTIFIER DEFAULT GenGUID() NOT NULL, 
   data_col INTEGER
);

Если вы используете такую ​​технологию, как ADOX, для проверки свойств этой таблицы (информационной схемы), вы обнаружите, что только для столбца, созданного с ключевым словом IDENTITY, свойство Autoincrement имеет значение true, а для COLUMN_HASDEFAULT этого столбца установлено значение false, а COLUMN_DEFAULT - ноль. Так что если столбец IDENTITY имеет «специальное значение по умолчанию», то движок не сообщает.

В отличие от IDENTITY, с этими другими разновидностями автонумера нет явного ограничения на таблицу, например, это отлично работает:

CREATE TABLE Test2_Autonumbers
(
   ID_random_1 INTEGER DEFAULT GenUniqueID() NOT NULL, 
   ID_random_2 INTEGER DEFAULT GenUniqueID() NOT NULL, 
   ID_guid_1 UNIQUEIDENTIFIER DEFAULT GenGUID() NOT NULL, 
   ID_guid_2 UNIQUEIDENTIFIER DEFAULT GenGUID() NOT NULL, 
   data_col INTEGER
);

Что-то, чего я не знаю, это то, существует ли «специальное значение по умолчанию», эквивалентное GenUniqueID() и GenGUID() для создания столбца с автоинкрементом, используя DEFAULT и без использования ключевого слова IDENTITY (или его синонимов ). Если кто-то знает так или иначе, пожалуйста, дайте мне знать.

Кстати, вышеупомянутое сообщение об ошибке говорит о том, что я ошибался, считая «Автономер» термином доступа. Похоже, что на уровне механизма ACE / Jet 'Autonumber' является синонимом не ключевого слова для IDENTITY (то есть, автоинкрементным автоматическим номером аромата), но не является синонимом для других разновидностей autonumber.

2 голосов
/ 21 апреля 2009

Неверное утверждение «Если некоторые записи удалены и база данных сжата, следующий идентификатор сбрасывается до самого низкого используемого числа + 1» Это произошло в Jet 3.5, используемой в Access 97, но не в Jet 4.0, используемой в Access 2000.

1 голос
/ 19 декабря 2011

Мой ответ - 3 строки кода VBA!

Set db = CurrentDb
Set tbl = db.TableDefs("your_tbl")
Set current_index = tbl.Indexes.Item("PrimaryKey").DistinctCount
1 голос
/ 21 апреля 2009

Поле Jet Autonumber не является полем идентификации. Это только длинное целое поле со специальным значением по умолчанию. Это значение по умолчанию может быть INCREMENT или RANDOM, но так как это только значение по умолчанию, вы можете добавить любое длинное целое значение в поле, если оно не нарушает индекс.

Инкрементный Autonumber никогда не вернется к 1, за исключением случаев, когда вы удалили все записи и сжали их, или в случае поврежденного начального значения. Последнее часто случалось в ранних версиях Jet 4 (до пакета обновления 6), где начальное значение сбрасывалось, и это приводило ко всем видам проблем, включая поврежденные индексы PK. К счастью, это в конечном итоге было исправлено, и, поскольку Jet является компонентом Windows, вряд ли на каком-либо компьютере будет что-то меньшее, чем Jet 4 с пакетом обновления 8.

Как уже говорилось, вы можете получить отрицательные значения, если инкрементный Autonumber превышает максимальное положительное значение для длинного целого числа, но это будет означать, что в вашей таблице достаточно записей, что вам нужен другой механизм базы данных, или вы неправильно обрабатываете вашу таблицу как временную (т. е. добавляете и удаляете большое количество записей).

Как уже говорили другие, уникальность контролируется не типом данных Autonumber, а индексом. Если вы создали неуникальный индекс, вы можете добавить повторяющиеся значения. Я не представляю, зачем вам поле Autonumber с повторяющимися значениями, но дело в том, что вы можете сделать это, если не добавляете уникальный индекс. Поскольку большинство полей Autonumber используются в качестве суррогатного первичного ключа, они будут иметь уникальный индекс PK, а таблица данных будет записана в порядке PK (кластеризовано). Что касается уникальности, если вы используете Autonumber в качестве суррогатного PK и у вас есть любые естественные ключи в таблице, которые должны быть уникальными (и может быть уникальным, т. Е. Пустые значения не допускаются), вам следует также иметь уникальный индекс для полей естественного ключа (отдельное поле или составной индекс).

1 голос
/ 20 апреля 2009

У меня есть таблица, которая ранее использовалась в реплицированной базе данных. Некоторые из автономных номеров отрицательны, а некоторые очень велики. Это нормально для реплицированной таблицы, поэтому вы не можете быть уверены, что автонумер будет больше, чем предыдущий номер, он может быть отрицательным.

1 голос
/ 20 апреля 2009

Во-первых, ваш столбец IDENTITY (Autonumber in Access) должен иметь значение INTEGER (Long Integer in Access), а не UNIQUEIDENTIFIER (ID репликации в Access), должен использовать алгоритм приращения, а не случайный алгоритм. для генерации новых значений и предположения, что ваши начальное значение и значение приращения соответственно являются значением по умолчанию 1, тогда, если вы удалите все строки в таблице и уплотните базу данных, тогда столбец IDENITTY должен быть повторно заполнен на 1. Если это не так тогда вам может понадобиться установить пакет обновления Jet (http://support.microsoft.com/kb/287756).

Обратите внимание, что, когда максимальное положительное значение для INTEGER (длинное целое число в доступе) будет превышено следующим автоматически сгенерированным значением, оно будет «обернуто» в отрицательный диапазон INTEGER и продолжит циклически проходить через положительные и отрицательные диапазоны, генерирующие дубликаты значений, где это необходимо (если столбец дополнительно не покрыт уникальным ограничением). Действительно, если значение приращения достаточно велико, вы можете гарантировать, что значения будут чередоваться, будучи больше или меньше, чем предыдущее автоматически сгенерированное значение, например, (Синтаксис режима запросов ACE / Jet ANSI-92):

CREATE TABLE Test 
(
   ID INTEGER IDENTITY (0, 2147483647), 
   data_col INTEGER NOT NULL UNIQUE
)
;
INSERT INTO Test (data_col) VALUES (1)
;
INSERT INTO Test (data_col) VALUES (2)
;
INSERT INTO Test (data_col) VALUES (3)
;
INSERT INTO Test (data_col) VALUES (4)
;
INSERT INTO Test (data_col) VALUES (5)
;
INSERT INTO Test (data_col) VALUES (6)
;
INSERT INTO Test (data_col) VALUES (7)
;
INSERT INTO Test (data_col) VALUES (8)
;

Сгенерированные автоматически значения: 0, 2147483647, -2, 2147483645, -4, 2147483643, -6, 2147483641 и т. Д.

0 голосов
/ 20 апреля 2009

Если некоторые записи удалены и база данных сжата, следующий идентификатор сбрасывается до наименьшего использованного числа + 1 - если таблица очищается, следующий идентификатор сбрасывается до 1 после компакта.

...