SQLite: могу ли я изменить порядок вставки строк с помощью таблицы AUTOINCREMENT?

У меня есть список элементов RecyclerView, который использует базу данных SQLite для хранения данных, введенных пользователем. Я использую традиционный столбец _id как INTEGER PRIMARY KEY AUTOINCREMENT. Если я правильно понимаю, новые вставленные строки в базе данных добавляются ниже существующих строк, а новый ROWID берет самый большой из существующих ROWID и увеличивает его на +1. Поэтому при поиске с помощью курсора последней вставки придется просмотреть весь набор строк, чтобы добраться до нижней части базы данных. Например, после 10 вставок курсор должен искать вниз от 1, 2, 3,..., пока не дойдет до строки 10.

Чтобы избежать длительного поиска всего набора ROWID, есть ли способ добавить новые вставки в верхнюю часть базы данных, а не в нижнюю? Таким образом, поиск курсором последней вставки с использованием moveToFirst() будет очень быстрым, поскольку курсор остановится на первой строке, которую он ищет, в верхней части базы данных. Курсор будет искать 10, 9, 8,... 3,2,1 и, следовательно, поиск будет очень быстрым, поскольку он остановится на 10, первой строке в верхней части базы данных.


person AJW    schedule 24.01.2018    source источник
comment
Вы предполагаете, что все запросы к базе данных используют линейный поиск, упорядоченный в порядке возрастания по ROWID?   -  person dan04    schedule 25.01.2018


Ответы (2)


Вы слишком много думаете о внутреннем устройстве базы данных. Индексы предназначены для такого рода оптимизации.

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

person Sidias-Korrado    schedule 24.01.2018
comment
Хорошо я понял. Однако я новичок в SQLite и Android, поэтому мне придется изучить ваше предложение, так как я понятия не имею, как его реализовать. - person AJW; 24.01.2018

Во-первых, если вас беспокоят накладные расходы, используйте рекомендуемый вариант INTEGER PRIMARY KEY, а не INTEGER PRIMARY KEY AUTOINCREMENT. Оба приведут к уникальному идентификатору, последний имеет накладные расходы в соответствии с: -

Ключевое слово AUTOINCREMENT накладывает дополнительную нагрузку на ЦП, память, дисковое пространство и дисковый ввод-вывод, и его следует избегать, если это не является строго необходимым. Обычно в этом нет необходимости. Автоинкремент SQLite


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

Как правило, НО не обязательно, нет гарантии, что значение увеличится на 1.

AUTOINCREMENT использует таблицу sqlite_seqeunce, в которой есть одна строка для каждой таблицы, в которой хранится самый высокий последний использованный порядковый номер вместе с именем таблицы. Следующим порядковым номером будет это значение +, вероятно, 1, ЕСЛИ ТОЛЬКО самый высокий идентификатор строки не больше значения в таблице sqlite_sequence.

Без AUTOINCREMENT следующая последовательность будет с наивысшим идентификатором строки +, вероятно, 1.

АВТОИНКРЕМЕНТ гарантирует большее число. Без AUOINCREMENT можно использовать меньшее число (НО только до тех пор, пока число не будет больше 9223372036854775807). Если AUTOINCREMENT будет использовать большее число, то произойдет исключение SQLITE_FULL.

Опять же, что касается rowid и поиска: -

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


Чтобы избежать длительного поиска всего набора ROWID, есть ли способ добавить новые вставки в верхнюю часть базы данных, а не в нижнюю?

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

person MikeT    schedule 25.01.2018