Domanda

Prima di tutto, lasciami prefigurare questa domanda affermando che sono davvero un modellatore di dati piuttosto terribile. Conosco solo abbastanza per essere pericoloso.

La tabella che sto costruendo ha quattro chiavi esterne, due delle quali fanno riferimento alla stessa tabella. Ecco l'istruzione create per quella tabella.

CREATE  TABLE IF NOT EXISTS `abnr`.`reputation_event_log` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  `reputation_event_id` INT NULL ,
  `giver_user_id` INT NULL ,
  `receiver_user_id` INT NULL ,
  `review_id` INT NULL ,
  `giver_point_value` SMALLINT NULL DEFAULT 0 ,
  `receiver_point_value` SMALLINT NULL DEFAULT 0 ,
  `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
  PRIMARY KEY (`id`) ,
  INDEX `fk_reputation_log_user` (`giver_user_id` ASC) ,
  INDEX `fk_reputation_log_user1` (`receiver_user_id` ASC) ,
  INDEX `fk_reputation_log_review` (`review_id` ASC) ,
  INDEX `fk_reputation_log_reputation_event` (`reputation_event_id` ASC) ,
  CONSTRAINT `fk_reputation_log_user`
    FOREIGN KEY (`giver_user_id` )
    REFERENCES `abnr`.`user` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_reputation_log_user1`
    FOREIGN KEY (`receiver_user_id` )
    REFERENCES `abnr`.`user` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_reputation_log_review`
    FOREIGN KEY (`review_id` )
    REFERENCES `abnr`.`review` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_reputation_log_reputation_event`
    FOREIGN KEY (`reputation_event_id` )
    REFERENCES `abnr`.`reputation_event` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;

Gli indici di cui mi occupo per questo post sono fk_reputation_log_user e fk_reputation_log_user1 . Ogni evento di reputazione ha un donatore, ma solo alcuni hanno un ricevitore. Vorrei che questo FK fosse nullable, ma non so come farlo, o se è persino " permesso " ;.

Ho anche giocato con l'idea di rendere tutte le colonne FK parte della chiave primaria per avere una protezione a livello di database contro voci di registro duplicate, ma ciò non funzionerà poiché le colonne PK non devono essere NULL.

Se hai bisogno di maggiori dettagli, ti preghiamo di indicarlo nei commenti. Grazie!

(Sì, questo è per un sistema di reputazione non troppo diverso da quello che ha SO)

È stato utile?

Soluzione

CREATE  TABLE IF NOT EXISTS `abnr`.`reputation_event_log` (
  `id`                  INT NOT NULL AUTO_INCREMENT ,
  `reputation_event_id` INT NULL ,
  `giver_user_id`       INT NOT NULL , -- mandatory giver_user_id
  `receiver_user_id`    INT NULL ,     -- optional receiver_user_id
  . . .

Sì, puoi avere NULL in una colonna con un vincolo di chiave esterna dichiarato su di essa. Il vincolo NOT NULL su una colonna è indipendente da qualsiasi vincolo / i di chiave esterna su quella colonna.

Una chiave esterna significa che se la colonna ha un valore non NULL, allora quel valore deve esistere nella chiave primaria della tabella a cui fa riferimento il vincolo di chiave esterna.

modifica: Per quanto riguarda il requisito UNIQUE , sei consapevole di poter dichiarare un vincolo UNIQUE su colonne nullable. La colonna può contenere NULL s (diversamente dal vincolo della chiave primaria). Questo è un comportamento SQL standard ed è supportato da MySQL.

  . . .
  PRIMARY KEY (`id`),
  CONSTRAINT UNIQUE (`giver_user_id`, `receiver_user_id`, 
                     `review_id`, `reputation_event_id`),
  . . .
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top