Всем привет! Несколько дней бьюсь над идентификацией предметов, в общем есть БД в ней таблица character и таблица item, в которой записываются все внутриигровые предметы принадлежащие character, как их лучше связать?
Традиционно это был пул числовых идентификаторов, типа Owner="ИД_Персонажа" и ITEM="ИД_Предмета", но встает вопрос об уникальности идентификаторов.
Т.е. если в бд предметы 1,2,3 и 2 предмет будет уничтожен, то останутся 1,3 а идентификатор 2 будет освобожден, так вот как бы мне его использовать дальше, учитывая что сервер может быть перезагружен и ему нужно как-то его узнать, соответственно циклы не прокатят, слишком дорого
Что нибудь подскажите
Или проще связывать их по имени персонажа? не затратно ли это будет?
А четырех миллиардов свободных идентификаторов уже не хватает, да?
Это кривовато. Нужны идентификаторы вида 4000-5000, для обозначения "областей" предметов. одна область - оружее, другая броня и тп
>Нужны идентификаторы вида 4000-5000, для обозначения "областей" предметов. одна область - оружее, другая броня и тп
вот это кривовато
дополнительная таблица не нужна, у предмета поле owner и индекс по этому полю - будет достаточно
тип предмета задавать отдельным полем.
поменял флаг согласно содержанию
Неуникальный ключ INTEGER owner_id NOT NULL - владелец предмета. По нему делается выборка из базы что в сумке и в банке (сумки расположенные в городе) игрока. В MySQL создаётся через CREATE INDEX (см. гуглпоиск по фразе "mysql create index") либо строчку INDEX внутри описания таблицы (да MySQL такие затейники, 37 способов сделать индекс).
Поле INTEGER item_database_id NOT NULL (не уникальное) - код предмета - содержит код в базе данных описаний предметов.
Поле INTEGER container_id NOT NULL (не уникальное) или можно назвать inventory_id - определяет где лежит предмет: сумка1, сумка2, ..., банк1, банк2, ..., шлем, броня, плечи, трусы, сапоги, меч левый, меч правый/щит.
Уникальный ключ INTEGER item_id NOT NULL PRIMARY KEY - целое число код предмета в базе. По нему создаётся предмет в игровом мире и делаются все операции вплоть до уничтожения предмета. Сумка игрока содержит именно эти ключи. Уникальность предмета проверяется по этому ключу. В MySQL создаётся через CREATE UNIQUE INDEX (см. гуглпоиск по фразе "mysql create unique index") или аттрибут поля PRIMARY KEY
У автора проблемы с пониманием реляционной модели данных и SQL. Можно почитать пару глав какой-нибудь умной книги.
Я вообще не об этом спрашиваю. Я не спрашиваю как мне спроектировать БД. Я спрашиваю каким мне образом хранить и пользоваться пулом уникальных идентификаторов.
Мне нужно создать пул уникальных идентификаторов и их использовать. Я не до конца понимаю каким лучше образом этот пул сделать, проверка на существование идентификатора, его занятость
ну раз тебе нужны костыли взамен стандартных средств субд, держи:
создавай и регулярно(раз в час/день сам подбирай) обновляй списки свободных айди по категориям предмета. при добавлении предмета бери первый из этого списка и удаляй его. можно также при удалении предмета добавлять его в соответствующий список свободных.
зы. как-то так делали в еве, но потом долго ругались.
а BIGINT UNSIGNED NOT NULL AUTO_INCREMENT не поможет?
Все предлагают либо самые очевидные решения, либо отвечают на свой собственный вопрос.
Всем спасибо. Больше за топиком не слежу.
cr3a70r
> Т.е. если в бд предметы 1,2,3 и 2 предмет будет уничтожен, то останутся 1,3 а
> идентификатор 2 будет освобожден, так вот как бы мне его использовать дальше,
> учитывая что сервер может быть перезагружен и ему нужно как-то его узнать,
> соответственно циклы не прокатят, слишком дорого
У автора непонимание принципов уникальных монотонно растущих ключей.
Сажи топику ;)
Пойдет?
public final class IDGenerator { private int index , length; private int[ ] free; public IDGenerator() {} public final int get() { return this.length == 0 ? this.index++ : this.free[ --this.length ]; } public final void release(final int id) { if ( this.free == null ) this.free = new int[ 16 ]; else if ( this.free.length == this.length ) { final int[ ] t = new int[ this.length + 16 ]; System.arraycopy( this.free , 0 , t , 0 , this.length ); this.free = t; } this.free[ this.length ] = id; this.sort( this.length++ ); } private final void sort(final int idx) { if ( idx == 0 ) return; if ( this.free[ idx ] > this.free[ idx - 1 ] ) { final int t = this.free[ idx ]; this.free[ idx ] = this.free[ idx - 1 ]; this.free[ idx - 1 ] = t; this.sort( idx - 1 ); } } public final void clear() { this.length = this.index = 0; } public final void dispose() { this.clear( ); this.free = null; } }
cr3a70r
> cr3a70r
возьми 64битный идентификатор. и генерируй последовательно и не парься.
Даже если предположить что в секунду будишь генерировать 4294967296 ID тебе 64бит хватит на 136.+лет.
+ по ID можно восстановить последовательность появления ID.
Тема в архиве.