2016-03-08 3 views
2

Я создал таблицу sqlite tmp с идентификаторами столбцов, именем.sqlite rowid после удаления строк

CREATE TABLE if not exists tmp (
      id    INTEGER PRIMARY KEY, 
      name   TEXT NOT NULL); 

Я вставил в него 5 рядов.

Когда я запускаю запрос выбора с помощью столбца rowid, он выводит ниже вывод.

select rowid,id,name from tmp; 

rowid id name 
1  1  a 
2  2  b 
3  3  c 
4  4  d 
5  5  e 

Теперь я удаляю строки с идентификаторами 3 и 4 и снова запускаю запрос.

rowid id name 
1  1  a 
2  2  b 
5  5  e 

Теперь моя проблема не в сборе, а в восстановлении.

Даже после вакуума он все еще не сбрасывает rowid, он по-прежнему дает выше выход.

выход, который я хочу

rowid id name 
1  1 a 
2  2 b 
3  5 e 

Может кто-нибудь помочь мне в достижении выше выхода?

Благодаря

+1

Цель идентификатора состоит в идентификации строки. Это невозможно, если вы меняете идентификаторы. –

ответ

1

Я полагаю, вы уже знаете немного о rowid, так как вы спрашиваете о его взаимодействии с командой VACUUM, но это может быть полезной информацией для будущих читателей:

rowid является a special column available in all tables (если вы не используете WITHOUT ROWID), используемый внутри sqlite. Предполагается, что A VACUUM перестроит таблицу, чтобы уменьшить фрагментацию в файле базы данных и may change the values of the rowid column. Двигаемся дальше.

Пожалуйста, сформулируйте Ваши вопросы относительно: rowid: действительно специальный. Настолько особенный, что если у вас есть INTEGER PRIMARY KEY, он становится псевдонимом для столбца rowid. Из документов на rowid:

За одним исключением отмечено ниже, если таблица ROWID имеет первичный ключ, который состоит из одного столбца и объявленный тип этого столбца является «Integer» в любой смеси верхнего и нижнего case, , тогда столбец становится псевдонимом для rowid. Такой столбец обычно называют «целым первичным ключом». Столбец PRIMARY KEY становится целым первичным ключом, если объявленное имя типа точно «INTEGER». Другие имена целых типов, такие как «INT» или «BIGINT» или «SHORT INTEGER» или «UNSIGNED INTEGER», приводят к тому, что столбец первичного ключа ведет себя как обычный столбец таблицы с целочисленным сродством и уникальный индекс, а не как псевдоним для rowid.

Это делает ваш первичный ключ быстрее, чем это было бы в противном случае (по-видимому, потому что нет никакого поиска от первичного ключа к rowid):

Данные для RowId таблиц хранится в виде B- Структура дерева, содержащая одну запись для каждой строки таблицы, используя значение rowid в качестве ключа. Это означает, что получение или сортировка записей по rowid выполняется быстро. Поиск записи с определенным значением rowid или для всех записей с rowids в указанном диапазоне составляет примерно в два раза быстрее как аналогичный поиск, сделанный путем указания любого другого PRIMARY KEY или индексированного значения.

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

Следовательно, эта маленькая заметка в VACUUM docs:

Команда VACUUM может изменить ROWID'а те записи в любых таблицах , которые не имеют явную INTEGER PRIMARY KEY.

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

Чтобы избежать наложения спектров, и ухудшить производительность, вы можете использовать INT вместо INTEGER при определении ключа:

ПЕРВИЧНЫЙ столбец KEY только становится в качестве первичного ключа, если имя объявленного типа точно "INTEGER". Другие имена целочисленного типа, такие как «INT» или «BIGINT» или «SHORT INTEGER» или «UNSIGNED INTEGER», заставляют столбец первичного ключа вести себя как обычный столбец таблицы с целочисленным сродством и уникальный индекс, а не как псевдоним для rowid ,

+0

Я действительно не хочу запускать вакуум, но я попытался с помощью вакуума, как говорят некоторые блоги. Я просто хочу получить окончательный результат с новыми rowids, как я уже упоминал в вопросе. Не имеет значения, должен ли я запускать вакуум или какой-либо другой трюк. Вы знаете какой-либо другой способ достичь этого, кроме изменения типа столбца в INT? – user1108687

+0

Но * почему * вам нужен идентификатор: s, чтобы изменить? Я не понимаю, почему это было бы полезно для вас. –

+0

Мне нужен старый идентификатор для нового сопоставления идентификаторов. Поэтому после удаления я хочу обновить идентификаторы строк. После этого идентификаторы строк будут новыми идентификаторами без отверстий, а старые идентификаторы будут в фактическом столбце «id». – user1108687

1

Я нашел решение для некоторых случаев. Я не знаю почему, но это сработало. 1.Введите столбец «id» на любое другое имя (не PRIMARY KEY) или удалите этот столбец, потому что у вас уже есть «rowid».

CREATE TABLE if not exists tmp (
      my_i    INTEGER NOT NULL, 
      name   TEXT NOT NULL); 

2.Insert 5 строк в нем.

выберите rowid, * from tmp;

rowid my_i name 
1  1  a 
2  2  b 
3  3  c 
4  4  d 
5  5  e 

3.Удалить строки с помощью rowid 3 и 4 и выполнить запрос еще раз.

DELETE FROM tmp WHERE rowid = 3; 
DELETE FROM tmp WHERE rowid = 4; 
select rowid,* from tmp; 
rowid my_i name 
1  1  a 
2  2  b 
5  5  e 

4.Run SQL

VACUUM; 

5.Run SQL

select rowid,* from tmp; 

Выход:

rowid my_i name 
1  1 a 
2  2 b 
3  5 e 
Смежные вопросы