I am trying to make a simple item database using MySQL for a game. Here is what my 3 tables would look like
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
My problem with this design is that value
column in item_attributes
table needs to use varchar
data type, since the value's data can be int
, char
, varchar
. I think this is a bad approach because I would not be able to quickly sort my items based on particular attributes. It would also suffer performance hit when a query such as get items with attribute strength that has value between 15 and 35 is processed.
Here is my potential fix. I simply added a data_type
column to the attributes
table. So it would look something like this
attributes (attribute lookup table) attributeId | attributeName | data_type --------------------------------------------------- 01 | strength | int 09 | type | char 08 | intellect | varchar
Then I would add 3 more columns to item_attributes
table, int
, char
, varchar
. Here is how the new item_attributes
table would look like.
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
So now if I were to sort items based on its strength
attribute, I would use int
column. Or search for an item based on its description, I would search the varchar
column.
I still, however, believe my design is a bit weird. Now I would have to look up the data_type
column in attribute
table and dynamically determine which column in item_attributes
table is relevant to what I am looking for.
Any inputs would be greatly appreciated.
Thanks in advance.
EDIT 11/29/2010 Here is a detailed list of my items
-------------------------------------- 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 --------------------------------------
EDIT #2
- These 10 examples are not representative of all 35316 items data that I have collected.
- NeckMiscellaneous means that item is in both categories of `Neck` and `Misc`.
- Unique means the only one item can be used on character.
- Don’t read too much into the “Action”, they are just quest description
- When an item says `Equip: increase attack power by 28` it just means +28 attack power on the player character. It is the same as +15 agility.
Here is an example how a query looks like
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'
The list order is here to keep track of which attribute should be listed first. For formatting purpose
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;
The above view produces the following with
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'
An attribute with value 0 means the attribute name represents the item type. 'Equip: Improves hit rating by @@.', '14'
@@ is place holder here, a processed output on a browser will be 'Equip: Improves hit rating by 14.'