I have a problem with my database design. I am making a browsergame as a small project to help improve my overall understanding of websites and database design.
Of course I wouldn't post here if I wouldn't have tried to find the solution myself(It is one of those things where searching the question it finds other questions, like the "how to create a many 2 many table")
Situation:
There are buildings/researches which are all realized over the database(to prevent a lot of hardcoding)
CREATE TABLE IF NOT EXISTS `structType` (
`idStructType` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(30) NOT NULL,
`idRace` int(11) NOT NULL,
UNIQUE (name),
FOREIGN KEY (idRace) REFERENCES race(idRace),
PRIMARY KEY (idStructType)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Some of those buildings and researches have a tech tree of course.
Here's where my problem starts: A Structure can have multiple structures as a requirement as well as multiple researches.
It also goes the other way around:
Researches also can have buildings/other researches as a requirement.
So I started to create "many-to-many"-resolving groups like this one:
CREATE TABLE IF NOT EXISTS `structtypeReqStructtype` (
`idStructType` int(11) NOT NULL,
`idStructType_required` int(11) NOT NULL,
`level` int(11) NOT NULL,
UNIQUE (idStructType, idStructType_required, level),
FOREIGN KEY (idStructType) REFERENCES structType(idStructType),
FOREIGN KEY (idStructType_required) REFERENCES structType(idStructType)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
This in the end leaves me with 4 tables only for the techtree between structures and researches, let alone ships and defenses and it feels like bad design to me.
There almost has to be a better way to do this. Would be very glad to get a little help in which direction I should take the thought process.
This is a pretty open ended question, but here are some thoughts:
I think the design which might be the cleanest would be a table that contains all 'buildables', including research items. This might just be a cost, a builder (a link to the buildables table), a name, and an ID.
You can add an extender table on top of this. You make a 'structure' table which references one 'buildable', and adds any extra fields 'structure' needs.
Finally, you can make a 'prerequisite' table. This has two buildable IDs, one for the buildable in question, one for the required item. Now you don't have separate requisite tables for structToResearch, structToStruct, researchToStruct and researchToResearch.
TL:DR; Make a base table that the many to many relationship meaningfully applies to. Make per type specific tables that hold a foreign key to the base table.