Is it possible to have a many to many relationship between two tables, and enforce that all the members of a group are to have a particular attribute in common?
For example, a worker can be in several groups, and a group can have several workers, but all the workers in a group must be on the same site. There are enough workers and sites that I can’t make a new table for each site.
–EDIT–
This is the simplified schema. I’m using mySQL workbench, but I think this is right:
-- -----------------------------------------------------
-- Table `DB`.`Worker`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `DB`.`Worker` (
`workerID` INT NOT NULL ,
`site` VARCHAR(45) ,
PRIMARY KEY (`workerID`) ;
-- -----------------------------------------------------
-- Table `DB`.`Group`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `DB`.`Group` (
`groupID` INT NOT NULL ,
PRIMARY KEY (`groupID`) ;
-- -----------------------------------------------------
-- Table `DB`.`Worker_Group`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `DB`.`workerGroup` (
`workerID` INT NOT NULL ,
`groupID` INT NOT NULL ,
PRIMARY KEY (`workerID`, `groupID`) ,
INDEX `fk_Group` (`groupID` ASC) ,
CONSTRAINT `fk_Worker`
FOREIGN KEY (`workerID` )
REFERENCES `DB`.`Worker` (`workerID` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_Group`
FOREIGN KEY (`groupID`)
REFERENCES `DB`.`Group` (`groupID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION) ;
You do that by using composite foreign keys.
Instead of foreign keying on just one field, you use a foreign key made out of several (two in this case) fields.
Now a group is specific to a site, as is a worker. And when populating the worker:group mapping table you reference the sites of both. This means that a worker can only be in a group with the same site_id.