SQLite - умный способ удалять и добавлять новые объекты - PullRequest
0 голосов
/ 20 марта 2009

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

Например: у меня есть 10 строк, каждая из которых имеет идентификатор - начиная с 0 и заканчивая 9. Когда я удаляю строку из таблицы, скажем - строка № 5, возникает «дыра». А потом я добавляю больше данных, но «дыра» все еще там.

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

Есть ли в sqlite способ сделать это? Или мне нужно вручную управлять удалением и добавлением данных?

Заранее спасибо, Илья.

Ответы [ 4 ]

5 голосов
/ 22 марта 2009

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

SELECT COUNT(*) FROM table_name;

При этом следующий триггер должен «скатываться» на каждый номер ID всякий раз, когда удаление создает дыру:

CREATE TRIGGER sequentialize_ids AFTER DELETE ON table_name FOR EACH ROW
BEGIN
UPDATE table_name SET id=id-1 WHERE id > OLD.id;
END;

Я проверил это на примере базы данных, и он работает так, как рекламируется. Если у вас есть следующая таблица:

id name
1  First
2  Second
3  Third
4  Fourth

И удалить, где id = 2, после этого таблица будет:

id name
1  First
2  Third
3  Fourth

Этот триггер может занять много времени и имеет очень плохие свойства масштабирования (он занимает больше времени для каждой удаляемой строки и каждой оставшейся строки в таблице). На моем компьютере удаление 15 строк в начале таблицы из 1000 строк заняло 0,26 секунды, но это, безусловно, будет больше на iPhone.

3 голосов
/ 22 марта 2009

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

Если вы хотите узнать количество строк, просто используйте:

SELECT count(*) FROM table_name;

Если вы хотите получить доступ к строкам в порядке идентификатора, просто определите это поле, используя ограничение PRIMARY KEY:

CREATE TABLE test (
id INTEGER PRIMARY KEY,
...
);

и получить строки, используя предложение ORDER BY с ASC или DESC:

SELECT * FROM table_name ORDER BY id ASC;

Sqlite создает индекс для поля первичного ключа, поэтому этот запрос выполняется быстро. Я думаю, что вам было бы интересно прочитать о предложениях LIMIT и OFFSET. Лучший источник информации - документация SQLite .

2 голосов
/ 22 марта 2009

Если вы не хотите использовать очень умный, но эффективный подход Стивена Дженнингса, просто запросите немного по-другому. Вместо:

SELECT * FROM mytable WHERE id = ?

Do:

SELECT * FROM mytable ORDER BY id LIMIT 1 OFFSET ?

Обратите внимание, что OFFSET начинается с нуля, поэтому вам может потребоваться вычесть 1 из переменной, с которой вы индексируете.

1 голос
/ 20 марта 2009

Если вы хотите восстановить идентификаторы удаленных строк, то команда VACUUM или прагма могут быть тем, что вы ищете,

http://www.sqlite.org/faq.html#q12

http://www.sqlite.org/lang_vacuum.html

http://www.sqlite.org/pragma.html#pragma_auto_vacuum

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...