Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > generation id


Автор: CBEPX4EJIOBEK 19.5.2010, 16:29
как можно менее затратно сгенерировать значение, имея список значений, в который полученное значение не должно входить.
Более частная задача: есть таблица, необходимо написать генератор который бы генерировал значения для id (таблица уже заполнена, есть как id = 1 так и id = 99999 (max 99999))

Автор: amigooo 19.5.2010, 16:46
Код

    private int pointer=1;

    public int getNextId(){
        while(isExist(pointer)){
            pointer++;
        }
        return pointer++;
    }
    
    private boolean isExist(int id){
        if(id>MAX){
            throw new IllegalStateException("No more valid id");
        }        
         return is_exist;//depends on env
    }

Автор: CBEPX4EJIOBEK 19.5.2010, 17:30
ну этот способ очевиден, но вот например если не инкремировать поинт а генерировать рандомно... что быстрее работать будет?

Автор: LSD 19.5.2010, 17:34
Цитата(CBEPX4EJIOBEK @  19.5.2010,  18:30 Найти цитируемый пост)
ну этот способ очевиден, но вот например если не инкремировать поинт а генерировать рандомно... что быстрее работать будет? 

Зависит от соотношения занятых к общему числу ключей и их распределения.


А задача какая? Если генерация ключей для СУБД, то единственно правильный способ, это использовать сиквенс/автоинкремент. Все остально велосипед с квадратными колесам и/или источник гарантированных ошибок.

Автор: CBEPX4EJIOBEK 19.5.2010, 18:46
необходимо генерить ключи для субд... единственное что таблица уже заполнена некоторыми значениями (id без порядка (есть записи с id = 5 и 100 и 899, но нету например записи с id=6, 7, 102)) и не известно с какого момента начинать инкримент или т.п. 

Автор: godvinn 19.5.2010, 18:50
А если при генерации этих чисел, на каждой итерации проверять -  если ли такое чисто в базе, если нет то инсертить.

Автор: amigooo 20.5.2010, 07:45
Цитата(CBEPX4EJIOBEK @ 19.5.2010,  17:30)
ну этот способ очевиден, но вот например если не инкремировать поинт а генерировать рандомно... что быстрее работать будет?

Чем проше тем лучше.
Из вашего условия следует что так или иначе придёться узнавать занятость всех id, инкрементный способ в любом случае позволяет для каждого id сделать только одну проверку.  способ с рандомной генерацией будет так работать в самом лучшем случае, что мало вероятно. Когда 90% id  будет уже заняты попробуйте рандомно попасть в оставшиеся 10%. Я уже не говорю о простоте/скорости операции инкремент по сравнению с генерацией псевдо случайных чисел. 



Автор: lBugl 20.5.2010, 08:20
если таблица досталась в наследство  и её нуна интегрировать в базу, то предлагаю следующее:
создать в базе идентичную таблицу такой же структуры "+" поле автоинкремент (мб праймари кей) и "-" твоё поле (которое как бы является разбросанными ключами). а далее при добавлении в базу записей id будет сам генериться и заполняться...

зы: мб ляпнул чёта не то... =)

Автор: Aikus 20.5.2010, 12:26
Если БД способна сама генерировать id, то лучше порыться в ней. Если не способна (да и такие бывают), думаю можно вычислить наибольшее число, записать его в ту же базу плясать от него:
1. взял значение, которое ты считаешь самым большим
2. прибавил 1
3. записал новое значение
4. сохранил объект

в пп. 2 и 4 надо ещё предусмотреть исключения и их обработку

Автор: LSD 21.5.2010, 12:11
Цитата(Aikus @  20.5.2010,  13:26 Найти цитируемый пост)
Если не способна (да и такие бывают)

Хоть один пример БД (современной) которая не умеет генерировать гарантировано-уникальные ключи.

Цитата(Aikus @  20.5.2010,  13:26 Найти цитируемый пост)
1. взял значение, которое ты считаешь самым большим
2. прибавил 1
3. записал новое значение
4. сохранил объект

5. Получил ошибку, потому как паралельная сессия уже успела занять этот ID smile 


Цитата(lBugl @  20.5.2010,  09:20 Найти цитируемый пост)
если таблица досталась в наследство  и её нуна интегрировать в базу, то предлагаю следующее:
создать в базе идентичную таблицу такой же структуры "+" поле автоинкремент (мб праймари кей) и "-" твоё поле (которое как бы является разбросанными ключами). а далее при добавлении в базу записей id будет сам генериться и заполняться...

Хороший вариант. В любом случае ключи лучше всего генрировать самой СУБД.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)