Items is the most high loaded part of game database. So you should create the most effective design to handle it. In your case it will be table like this one
create table item (
id long primary key
item_name string
....
item_state_type int
item_state_data varbinary
)
id - it is the key for unique item entity.
item_name - "ring of power"
item_state_type - type of your item. Ordinary or random generated.
item_state_data - serialized custom data. In your case it is an array of custom attributes.
The pair of tables item and item_attributes with keys-and-values isn't a good idea. Operation with one row (in my design) will be converted in operation with ~10 rows in different tables (in key-value design)
For example
id, item_name, item_state_type, item_state_data, owner_town, owner_id
1, "ring of power" , 0, null, 1, null - vendor ordinary item
2, "ring of power" , 1, binary1, 1, null - vendor customized item
3, "ring of power" , 1, binary2, 2, null - vendor customized item in another town
4, "ring of power" , 1, binary1, null, 10 - user1 item
4, "ring of power" , 1, binary2, null, 10 - user2 item
Actually I prefer to store item templates in XML files, but this approach is OK too for simple data model.
item_state_data - serialized custom data. In your case it is an array of custom attributes.
The main idea - you should somehow translate your custom data into one byte array. Or into string.
Example in java + pseudocode.
public void saveItem(ItemDataSet item) {
...
PreparedStatement stmt = getConnection().prepareStatement("insert into item ... ");
ItemSerializer serializer = SerializerFactory.createItemSerializer();
byte[] item_state_data = serializer.serialize(item);
stmt.setBytes(1, avatarInfo);
...
}
public ItemSerializer {
public byte[] serialize(ItemDataSet item) {
DataOutput out = new DataOutputStream(...);
out.writeInt(item.customParams().length);
for (long value : item.customParams()) {
out.writeLong(value);
}
...
return out.toByteArray();
}
public ItemDataSet item deserialize(byte[] bytes) {
DataInputStream in = new DataInputStream(bytes);
ItemDataSet item = new ItemDataSet();
int arrayLength = in.readInt();
for(int i=0;i<arrayLength; i++ ) {
item.addParam( in.readLong);
}
...
return item;
}
}