Здравствуйте, есть таблица, id генерируется базой данных, после удаления строки образуется провал пример:
ID name
1 vlad
2 sergey
3 ivan
5 tolik
8 gesha
как этого избежать и можно ли это исправить в существующей таблице?
Благодарю всех за помощь!
у меня генерируется случайное число и программа должна из базы доставать запись с этим айдишником, при этом провале на весь экран ошибки выскакивают, бывает даже много ошибок.Хотелось бы всё по фен-шую
Если вам нужно выбрать случайную запись из таблицы, поручите это СУБД, так будет по фен-шую.
PostgreSQL и SQLite:
SELECT * FROM table_name ORDER BY RANDOM() LIMIT 1
MySQL:
SELECT * FROM table_name ORDER BY RAND() LIMIT 1
MS SQL Server:
SELECT TOP 1 * FROM table_name ORDER BY NEWID()
Oracle:
SELECT * FROM (SELECT column FROM table_name ORDER BY dbms_random.value) WHERE rownum = 1
Да, по id вы не сможете с уверенностью забирать запись, так как могут быть дыры. Их не надо "заделывать", это основа структуры SQL, почитайте. Считаю, что все колонки-велосипеды с номерами "без дыр" - огромный костыль. Как вы будете обновлять их номера при удалении самой первой записи, если их всего под миллион? 999999 запросов update
?
Предлагаю, следующее. Не проще ли сразу получать рандомную запись из таблицы?
Cursor randomCursor = db.query(DB_TABLE, new String[] { /* тут все колонки */ }, null, null, null, null, "RANDOM()", "1");
if(cursor != null && cursor.getCount() > 0) {
randomCursor.moveToFirst();
}
//берем из курсора данные рандомной записи
Если записей очень много, то операция может занять много времени. Подойдет для мелких таблиц. В случае работы с большими данными, я думаю, что лучше будет передавать массив не всех колонок, а только колонки с айдишником (BaseColumns._ID
). А потом уже по полученному рандомному id
через where
выполнить второй запрос, уже получив все колонки. Примерно так:
Cursor randomId = db.query(DB_TABLE, new String[] { BaseColumns._ID }, null, null, null, null, "RANDOM()", "1");
if(randomId != null && randomId.getCount() > 0) {
//удалено. Курсор и так содержит одну запись
//randomCursor.moveToFirst();
int id = randomId.getInt(BaseColumns._ID);
Cursor randomRow = db.query(DB_TABLE, new String[] { /* а вот тут уже все колонки */ }, BaseColumns._ID + "=?", new String[] { Integer.toString(id) }, null, null, null);
//в курсоре randomRow лежит рандомная запись, получаем значения в колонках и используем
}
Я думаю что так правильнее и будет быстрее, если это не так, поправьте меня в комментариях
А для чего это исправлять? Ты добавляешь запись в таблицу, она получает уникальный номер. Инкремент сделал +1. Ты удаляешь эту запись - инкремент не изменился.
Если ты запариваешься по этому поводу, то:
Но этот план, он нецелесообразен.
Предлагаю вот такой вариант:
Вытаскиваем список id в массив типа int[]
Генерируем уникальное число от 0 до int[].size - 1
По индексу вытаскиваем id
Делаем запрос к БД.
Такой подход защищает от пробелов в id по крайней мере если в этот момент времени не было delete row
Я сериализовал класс и отправил его по сети от сервера к клиентуКлиент должен восстановить состояние класса
Некорректно выполняется поиск элементов из списка, при вводе какого либо значенияЕсть элемент, но в поиске его не находит