Здравствуйте, есть таблица, 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
Сборка персонального компьютера от Artline: умный выбор для современных пользователей