Pregunta

En primer lugar, permítanme comenzar esta pregunta diciendo que realmente soy un modelador de datos bastante terrible. Sé lo suficiente como para ser peligroso.

La tabla que estoy construyendo tiene cuatro claves externas, dos de las cuales hacen referencia a la misma tabla. Aquí está la declaración de creación para esa tabla.

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;

Los índices que me interesan para esta publicación son fk_reputation_log_user y fk_reputation_log_user1 . Cada evento de reputación tiene un donante, pero solo algunos tienen un receptor. Me gustaría que este FK sea anulable, pero no sé cómo hacerlo, o si incluso está "permitido".

También jugué con la idea de hacer que todas las columnas FK formen parte de la clave primaria para tener protección a nivel de base de datos contra entradas de registro duplicadas, pero eso no funcionará ya que las columnas PK no deben ser NULAS.

Si necesita más detalles, indíquelo en los comentarios. Gracias!

(Sí, esto es para un sistema de reputación no muy diferente de lo que SO tiene)

¿Fue útil?

Solución

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í, puede tener NULL en una columna con una restricción de clave externa declarada. La restricción NOT NULL en una columna es independiente de cualquier restricción de clave externa en esa columna.

Una clave externa significa que si la columna tiene un valor no NULL, entonces ese valor debe existir en la clave primaria de la tabla a la que hace referencia la restricción de clave externa.

edit: En cuanto a su requisito de UNIQUE , ¿sabe que puede declarar una restricción UNIQUE en columnas anulables? La columna puede contener NULL s (a diferencia de la restricción de clave principal). Este es el comportamiento estándar de SQL y es compatible con MySQL.

  . . .
  PRIMARY KEY (`id`),
  CONSTRAINT UNIQUE (`giver_user_id`, `receiver_user_id`, 
                     `review_id`, `reputation_event_id`),
  . . .
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top