Link to home
Start Free TrialLog in
Avatar of DrDamnit
DrDamnitFlag for United States of America

asked on

Optional Foreign Keys in MySQL?

In the table below, I need to be able to create an opportunity with just opportuntys_name at first because we may not yet know how we are quoting it to or even what they want. We  just know they want something.


CREATE TABLE IF NOT EXISTS `mcdb2`.`opportunitys` (
  `opportunitys_id` INT NOT NULL AUTO_INCREMENT,
  `opportunitys_ts_created` INT NULL,
  `opportunitys_name` VARCHAR(45) NULL,
  `opportunitys_amount` DOUBLE NULL,
  `opportunitys_quoted_by` INT(11) NOT NULL,
  `opportunitys_quoted_by_company` INT(11) NOT NULL,
  `opportunitys_ts_received` INT NULL,
  `opportunitys_ts_due_by` INT NULL,
  `opportunitys_ts_next_followup` INT NULL,
  `opportunitys_supplier` INT NOT NULL,
  `opportunitys_stage` INT NOT NULL,
  `opportunitys_quoted_to` INT(11) NOT NULL,
  `opportunitys_quoted_to_company` INT(11) NOT NULL,
  `opportunitys_company` INT(11) NOT NULL,
  PRIMARY KEY (`opportunitys_id`, `opportunitys_quoted_by`, `opportunitys_quoted_by_company`, `opportunitys_supplier`, `opportunitys_stage`, `opportunitys_quoted_to`, `opportunitys_quoted_to_company`, `opportunitys_company`),
  INDEX `fk_opportunitys_contacts1_idx` (`opportunitys_quoted_by` ASC, `opportunitys_quoted_by_company` ASC),
  INDEX `fk_opportunitys_suppliers1_idx` (`opportunitys_supplier` ASC),
  INDEX `fk_opportunitys_stages1_idx` (`opportunitys_stage` ASC),
  INDEX `fk_opportunitys_contacts2_idx` (`opportunitys_quoted_to` ASC, `opportunitys_quoted_to_company` ASC),
  INDEX `fk_opportunitys_companys1_idx` (`opportunitys_company` ASC),
  CONSTRAINT `fk_opportunitys_contacts1`
    FOREIGN KEY (`opportunitys_quoted_by` , `opportunitys_quoted_by_company`)
    REFERENCES `mcdb2`.`contacts` (`contacts_id` , `contacts_company`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_opportunitys_suppliers1`
    FOREIGN KEY (`opportunitys_supplier`)
    REFERENCES `mcdb2`.`suppliers` (`suppliers_id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_opportunitys_stages1`
    FOREIGN KEY (`opportunitys_stage`)
    REFERENCES `mcdb2`.`stages` (`stages_id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_opportunitys_contacts2`
    FOREIGN KEY (`opportunitys_quoted_to` , `opportunitys_quoted_to_company`)
    REFERENCES `mcdb2`.`contacts` (`contacts_id` , `contacts_company`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_opportunitys_companys1`
    FOREIGN KEY (`opportunitys_company`)
    REFERENCES `mcdb2`.`companys` (`companys_id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB

Open in new window


Right now, when I try to create the record, I am getting this error:
This opportunity could not be created. You have a database error: (1452) Cannot add or update a child row: a foreign key constraint fails (`mcdb2`.`opportunitys`, CONSTRAINT `fk_opportunitys_contacts1` FOREIGN KEY (`opportunitys_quoted_by`, `opportunitys_quoted_by_company`) REFERENCES `contacts` (`contacts_id`, `contacts_company`)

Open in new window


How do I re-arrange this table definition so that I still keep the foreign key reference, but it doesn't reject an insertion when those references are blank (to be entered at a later time)?
Avatar of Guy Hengel [angelIII / a3]
Guy Hengel [angelIII / a3]
Flag of Luxembourg image

you could create a "dummy" record in the referenced tables, which could be used for all of these "prospect" records.
I usually use the PK value of 0, for example, for such a dummy record, and use a default value of 0 in the FK fields.
ASKER CERTIFIED SOLUTION
Avatar of DrDamnit
DrDamnit
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
yes, that also works. but there are quite some people that have some arguments about avoiding the "NULL" value, especially as the indexing impacts on using NULL values (and later searching for those NULL values) is normally not optimal.
Avatar of DrDamnit

ASKER

This actually works out better. The dummy company and the dummy contact are ID: 1, which is actually better to test for when looking to see what's been done with the record.