Я пытаюсь создать простую базу данных предметов, используя 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
соответствует тому, что я ищу.
Будем благодарны за любые материалы.
Заранее спасибо.
РЕДАКТИРОВАТЬ 29.11.2010
Вот подробный список моих вещей
--------------------------------------
http://wow.allakhazam.com/ihtml?27718
Aldor Defender's 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's Bryanite of Extended Cost Copying
Gems
Item Level 10
gem test enchantment
--------------------------------------
РЕДАКТИРОВАТЬ # 2
- Эти 10 примеров не являются репрезентативными для всех 35316 данных, которые я собрал.
- NeckMiscellaneous означает, что предмет относится к обеим категориям: «Neck» и «Misc».
- Уникальный означает, что только один элемент может быть использован для персонажа.
- Не читайте слишком много в "Действие", это просто описание квеста
- Когда предмет говорит: «Надеть: увеличить силу атаки на 28», это просто означает +28 к силе атаки персонажа игрока. Это +15 к ловкости.
- Всего имеется 241884 записей атрибутов элемента «один ко многим», что составляет 241884/35316 ~ = 8 средних атрибутов на элемент. Также данные добываются с веб-сайта в гигантский текстовый файл. НЕТ «правильно сформированной» информации для определения типа или категории предмета. Таким образом, если слово «меч» появляется в 3-й или 4-й строке, оно автоматически классифицируется как меч.
- Предмет может меняться при каждом новом обновлении игры.
- Нет универсального атрибута, доступного для элемента, кроме `name`
- Данные об элементе доступны через веб-приложение. Неясно, что вы подразумеваете под битами и векторами?
- Регулярное выражение используется на этапе интеллектуального анализа данных для очистки специального символа и поиска определенного ключевого слова для классификации элементов. Также для извлечения имени и значения атрибута. Например, +15 к ловкости будет иметь строковую ловкость, извлеченную как имя атрибута, и 15 как значение. (Я не очень разбираюсь в вопросах 6 и 6.1. Слог здесь обозначает журнал сервера? Перевести регулярные выражения в 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''s Legplates', 'Binds when picked up', '0'
'251', 'Aldor Defender''s Legplates', 'Legs', '0'
'251', 'Aldor Defender''s Legplates', 'Plate', '0'
'251', 'Aldor Defender''s Legplates', 'Armor', '802'
'251', 'Aldor Defender''s Legplates', 'Strength', '21'
'251', 'Aldor Defender''s Legplates', 'Agility', '14'
'251', 'Aldor Defender''s Legplates', 'Stamina', '21'
'251', 'Aldor Defender''s Legplates', 'Item Level', '99'
'251', 'Aldor Defender''s Legplates', 'Equip: Improves hit rating by @@.', '14'
Атрибут со значением 0 означает, что имя атрибута представляет тип элемента. 'Equip: Improves hit rating by @@.', '14'
@@ здесь заполнитель, обработанный вывод в браузере будет 'Equip: Improves hit rating by 14.'