What I have now is table that is "hardcoded" to have a relationship between two of the same table with two foreign keys to that table.
Before 'Relationship' table:
CREATE TABLE IF NOT EXISTS `Item_To_Item` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`item1_id` INT(11) NOT NULL,
`item2_id` INT(11) NOT NULL,
`relationship` ENUM('requires', 'mutually_requires', 'required_by', 'relates', 'excludes') NULL DEFAULT NULL,
`description` VARCHAR(1000) NULL DEFAULT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `fk_Item1_Id`
FOREIGN KEY (`item1_id`)
REFERENCES `Item` (`id`)
CONSTRAINT `fk_Item2_Id`
FOREIGN KEY (`item2_id`)
REFERENCES `Item` (`id`)
So before this had a double many to one reference on the item table to fill the two foreign keys.
There is a need now to expand this relationship to be more general between tables in the db (Enum, Tag, feature etc). So that now Items can relate to items, items can relate to tags, tags can relate to tags etc with the enum relationship value.
What I am thinking for the general table is adding a type table, so each item, tag, etc can be identified, and then restructuring the relationship table to be something like this:
CREATE TABLE IF NOT EXISTS `Relationship` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`relater_id` INT(11) NOT NULL,
`relatee_id` INT(11) NOT NULL,
`relationship` ENUM('requires', 'mutually_requires', 'required_by', 'relates', 'excludes') NULL DEFAULT NULL,
`description` VARCHAR(1000) NULL DEFAULT NULL,
`relater_type_id` INT(11) NULL,
`relatee_type_id` INT(11) NULL,
PRIMARY KEY (`id`),
INDEX `fk_Relatee_Id` (`relatee_id` ASC),
INDEX `fk_Relater_Id` (`relater_id` ASC),
CONSTRAINT `fk_Relater_Id`
FOREIGN KEY (`relater_id`)
CONSTRAINT `fk_Relatee_Id`
FOREIGN KEY (`relatee_id`)
So that now you can identify what type of items are being related by the type_id and table and this can be opened up so any two table ids can go into the Relater and Relatee foreign key columns.
The problem is that I do not know how to have such generality with foreign keys. I believe they can only reference one table so I am not sure how to do what I want with a general key reference. Also, I can see a problem with bidirectional relationships where A mutually Requires B and B mutually Requires A being redundant data. I could block this redundancy in my application, but I would constantly have to check for two sided A to B || B to A. I was wondering the best way to accomplish what I am trying to do. Thank you.
Edit: Maybe using some kind of base type for my (item, feature, tag) could help me?
Edit: I don't think the answer is as simple as inheritance. At least from what I can tell. My problem is that I want to relate two general items no matter the type. I don't want 20 columns that have to be null because it is not that specific type. I just want to be able to pass two ids and therefore two type_ids into the relationship so I can relate any two objects.