Precisa de uma dica sobre o design simples do MySQL db
Estou tentando criar um banco de dados de itens simples usando o MySQL para um jogo. Aqui está a aparência das minhas 3 tabelas
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
Meu problema com esse design é quevalue
coluna emitem_attributes
tabela precisa usarvarchar
tipo de dado, já que os dados do valor podem serint
, char
, varchar
. Eu acho que essa é uma abordagem ruim, porque eu não seria capaz de classificar rapidamente meus itens com base em atributos específicos. Também sofreria um impacto no desempenho quando uma consulta comoobter itens com força de atributo que tenha valor entre 15 e 35 é processado.
Aqui está minha correção em potencial. Eu simplesmente adicionei umdata_type
coluna para oattributes
mesa. Então seria algo parecido com isto
attributes (attribute lookup table) attributeId | attributeName | data_type --------------------------------------------------- 01 | strength | int 09 | type | char 08 | intellect | varchar
Então eu adicionaria mais 3 colunas paraitem_attributes
mesa,int
, char
, varchar
. Aqui está como o novoitem_attributes
tabela seria.
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
Então agora, se eu fosse classificar itens com base em suastrength
atributo, eu usariaint
coluna. Ou pesquise um item com base em sua descrição, eu pesquisaria ovarchar
coluna.
Ainda acredito, no entanto, que meu design é um pouco estranho. Agora eu teria que procurar nodata_type
coluna emattribute
tabela e determinar dinamicamente qual colunaitem_attributes
A tabela é relevante para o que estou procurando.
Qualquer entrada seria muito apreciada.
Desde já, obrigado.
EDIT 29/11/2010 Aqui está uma lista detalhada dos meus itens
-------------------------------------- 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 # 2Esses 10 exemplos não são representativos de todos os dados de 35316 itens que eu coletei.NeckMisc Miscellaneous significa que o item está nas duas categorias de `Neck` e` Misc`.Único significa que o único item pode ser usado no personagem.Não leia muito sobre a "Ação", eles são apenas uma descrição da missãoQuando um item diz 'Equipar: aumenta o poder de ataque em 28' significa apenas +28 de poder de ataque no personagem do jogador. É o mesmo que +15 de agilidade.Há um total de 241884 registros de atributo de item um-para-muitos, de modo que chega a 241884/35316 ~ = 8 atributos médios por item. Além disso, os dados são extraídos do site em um gigantesco arquivo de texto. NÃO há informações "bem formadas" para identificar o tipo ou categoria de um item. Portanto, se a palavra "espada" aparecer na terceira ou na quarta linha, ela será automaticamente categorizada como espada.O item pode ser alterado a cada nova atualização do jogo.Não há atributo universal compartilhado entre o item além de `name`Os dados do item podem ser acessados por meio de um aplicativo Web. Não está claro o que você quer dizer com bits e vetores?A expressão regular é usada durante o estágio de mineração de dados para limpar o caractere especial e procurar por palavra-chave específica para categorizar os itens. Também para extrair o nome e o valor do atributo. Por exemplo, +15 de agilidade teriam a agilidade de cadeia de caracteres extraída como nome do atributo e 15 como valor. (Eu não entendo muito sobre as perguntas 6 e 6.1. Slog significa log do servidor aqui? Traduzir regexes para SQL?)Diagrama do modelo
Aqui está um exemplo de como uma consulta se parece
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'
A ordem da lista está aqui para acompanhar qual atributo deve ser listado primeiro. Para fins de formatação
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;
A vista acima produz o seguinte com
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'
Um atributo com o valor 0 significa que o nome do atributo representa o tipo de item.'Equip: Improves hit rating by @@.', '14'
@@ é o espaço reservado aqui, uma saída processada em um navegador será'Equip: Improves hit rating by 14.'