Я пытаюсь создать простую базу данных элементов, используя MySQL для игры. Вот как мои 3 таблицы будут выглядеть как
items itemId | itemName ------------------- 0001 | chest piece 0002 | sword 0003 | helmet
attributes (attribute lookup table) attributeId | attributeName --------------------------------- 01 | strength 02 | agility 03 | intellect 04 | defense 05 | damage 06 | mana 07 | stamina 08 | description 09 | type
item_attributes (junction table) itemId | attributeId | value (mixed type, bad?) ------------------------------------ 0001 | 01 | 35 0001 | 03 | 14 0001 | 09 | armor 0001 | 08 | crafted by awesome elves 0002 | 09 | weapon 0002 | 05 | 200 0002 | 02 | 15 0002 | 08 | your average sword 0003 | 04 | 9000 0003 | 09 | armor 0003 | 06 | 250
Моя проблема с этим дизайном заключается в том, что столбец value
в таблице item_attributes
должен использовать тип данных varchar
, так как данные значения могут быть int
, char
, varchar
. Я думаю, что это плохой подход, потому что я не смог бы быстро сортировать свои объекты на основе определенных атрибутов. Это также пострадает от производительности, когда обрабатывается такой запрос, как получить элементы с силой атрибута, который имеет значение от 15 до 35.
Вот мое потенциальное исправление. Я просто добавил столбец data_type
в таблицу attributes
. Таким образом, это будет выглядеть примерно так.
attributes (attribute lookup table) attributeId | attributeName | data_type --------------------------------------------------- 01 | strength | int 09 | type | char 08 | intellect | varchar
Затем я бы добавил еще 3 столбца в таблицу item_attributes
, int
, char
, varchar
. Вот как выглядит новая таблица item_attributes
.
item_attributes (junction table) itemId | attributeId | value | int | char | varchar ------------------------------------------------------------------------ 0002 | 09 | weapon | null |weapon| null 0002 | 05 | 200 | 200 | null | null 0002 | 02 | 15 | 15 | null | null 0002 | 08 | your average sword | null | null | your average sword
Итак, теперь, если я должен сортировать элементы на основе его атрибута strength
, я бы использовал столбец int
. Или найдите элемент на основе его описания, я бы поискал столбец varchar
.
Я все же, однако, считаю, что мой дизайн немного странный. Теперь мне нужно искать столбец data_type
в таблице attribute
и динамически определять, какой столбец в таблице item_attributes
имеет отношение к тому, что я ищу.
Приветствуются любые входные данные.
Спасибо заранее.
РЕДАКТИРОВАТЬ 11/29/2010 Вот подробный список моих предметов.
-------------------------------------- http://wow.allakhazam.com/ihtml?27718 Aldor Defender Legplates Binds when picked up LegsPlate 802 Armor +21 Strength +14 Agility +21 Stamina Item Level 99 Equip: Improves hit rating by 14. -------------------------------------- http://wow.allakhazam.com/ihtml?17967 Refined Scale of Onyxia Leather Item Level 60 -------------------------------------- http://wow.allakhazam.com/ihtml?27719 Aldor Leggings of Puissance Binds when picked up LegsLeather 202 Armor +15 Agility +21 Stamina Item Level 99 Equip: Increases attack power by 28. Equip: Improves hit rating by 20. -------------------------------------- http://wow.allakhazam.com/ihtml?5005 Emberspark Pendant Binds when equipped NeckMiscellaneous +2 Stamina +7 Spirit Requires Level 30 Item Level 35 -------------------------------------- http://wow.allakhazam.com/ihtml?23234 Blue Bryanite of Agility Gems Requires Level 2 Item Level 10 +8 Agility -------------------------------------- http://wow.allakhazam.com/ihtml?32972 Beer Goggles Binds when picked up Unique HeadMiscellaneous Item Level 10 Equip: Guaranteed by Belbi Quikswitch to make EVERYONE look attractive! -------------------------------------- http://wow.allakhazam.com/ihtml?41118 Gadgetzan Present Binds when picked up Unique Item Level 5 "Please return to a Season Organizer" -------------------------------------- http://wow.allakhazam.com/ihtml?6649 Searing Totem Scroll Unique Quest Item Requires Level 10 Item Level 10 Use: -------------------------------------- http://wow.allakhazam.com/ihtml?6648 Stoneskin Totem Scroll Unique Quest Item Requires Level 4 Item Level 4 Use: -------------------------------------- http://wow.allakhazam.com/ihtml?27864 Brian Bryanite of Extended Cost Copying Gems Item Level 10 gem test enchantment --------------------------------------
EDIT # 2
- Эти 10 примеров не являются репрезентативными для всех данных 35316 элементов, которые я собрал.
- NeckMisc Miscellaneous означает, что элемент находится в обеих категориях `Neck` и` Misc`.
- Уникальный означает, что для символа можно использовать только один элемент.
- Не читайте слишком много в "Action", это просто описание квеста
- Когда элемент говорит "Equip: увеличить силу атаки на 28", это означает, что сила атаки +28 на персонаже игрока. Это то же самое, что и маневренность +15.
- В записи атрибутов элемента-атрибута содержится 241884 атрибута "один-ко-многим", так что примерно 241884/35316 ~ = 8 средних атрибутов на элемент. Также данные извлекаются из веб-сайта в гигантский текстовый файл. Для идентификации типа или категории элементов нет "хорошо сформированной" информации. Поэтому, если слово "меч" появляется на третьей или четвертой строках, оно автоматически классифицируется как меч.
- Элемент может быть изменен при каждом новом обновлении игры.
- Нет универсального атрибута, разделяемого между элементом, кроме `name`
- Данные элемента доступны через веб-приложение. Неясно, что вы подразумеваете под битами и векторами?
- Регулярное выражение используется на этапе разработки данных для очистки специального символа и поиска определенного ключевого слова, чтобы классифицировать элементы. Также для извлечения имени и значения атрибута. Например, +15 гибкость будет иметь гибкость строки, извлеченную как имя атрибута, и значение 15 в качестве значения. (Я не очень разбираюсь в вопросах 6 и 6.1. Slog означает серверный журнал здесь? Переводите регулярные выражения в SQL?)
Диаграмма моделей
Вот пример, как выглядит запрос
select * from itemattributestat where item_itemId=251 item_itemId | attribute_attributeId | value | listOrder ======================================================= '251', '9', '0', '1' '251', '558', '0', '2' '251', '569', '0', '3' '251', '4', '802', '4' '251', '583', '21', '5' '251', '1', '14', '6' '251', '582', '21', '7' '251', '556', '99', '8' '251', '227', '14', '9'
Порядок списка здесь, чтобы отслеживать, какой атрибут должен быть указан первым. Для целей форматирования
create view itemDetail as select Item_itemId as id, i.name as item, a.name as attribute, value from ((itemattributestat join item as i on Item_itemId=i.itemId) join attribute as a on Attribute_attributeId=a.attributeId) order by Item_itemId asc, listOrder asc;
Вышеприведенный вид дает следующее с
select * from itemdetail where id=251; id | item | attribute | value '251', 'Aldor Defender' Legplates', 'Binds when picked up', '0' '251', 'Aldor Defender' Legplates', 'Legs', '0' '251', 'Aldor Defender' Legplates', 'Plate', '0' '251', 'Aldor Defender' Legplates', 'Armor', '802' '251', 'Aldor Defender' Legplates', 'Strength', '21' '251', 'Aldor Defender' Legplates', 'Agility', '14' '251', 'Aldor Defender' Legplates', 'Stamina', '21' '251', 'Aldor Defender' Legplates', 'Item Level', '99' '251', 'Aldor Defender' Legplates', 'Equip: Improves hit rating by @@.', '14'
Атрибут со значением 0 означает, что имя атрибута представляет тип элемента. 'Equip: Improves hit rating by @@.', '14'
@@здесь владелец места, обработанный вывод в браузере будет 'Equip: Improves hit rating by 14.'