IMO you should think about how you are going to use the data when you design the database. You shouldn't be scared of joins, they are a fundamental part of how a relational database works.
You say items have attributes which can vary with the type of item. In some applications this could be a reason to split the items into different tables but in this particular case I don't think that is the way to go because the attributes aren't really core to the application.
What I would instead do is split the attributes into primary attributes that are present for every item, are stored directly in the items table have special meaning to the code (price, date listed, description etc) and extended attributes which can be created merely by adding database records.
So the way I would struture this is something like.
categoryid (primary key, autoincrement)
parentcategoryid (self refferential foreign key, null represents a top-level category)
itemid (primary key, autoincrement)
categoryid (foreign key referencing categories table)
attributeentryid (primary key, autoincrement)
attributetypeid (foreign key referencing attributetypes table
itemid (foreign key referencing items table)
value (probablly a largeish varchar)
If you want to be able to have an item in multiple categories you may want to get rid of the categoryid in the items table (or maybe use it for a primary category) and create a linking table.