具有可为空FKs的MySQL复合PK

具有可为空FKs的MySQL复合PK,mysql,database-design,foreign-keys,data-modeling,nullable,Mysql,Database Design,Foreign Keys,Data Modeling,Nullable,首先,让我先说明一下我是一个非常糟糕的数据建模师。我只知道会很危险 我正在构建的表有四个外键,其中两个引用同一个表。下面是该表的create语句 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

首先,让我先说明一下我是一个非常糟糕的数据建模师。我只知道会很危险

我正在构建的表有四个外键,其中两个引用同一个表。下面是该表的create语句

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;
我在这篇文章中关注的索引是
fk_声誉_日志_用户
fk_声誉_日志_用户1
。每个声誉事件都有一个给予者,但只有一些事件有一个接受者。我希望这个FK可以为空,但我不知道怎么做,或者它是否被允许

我还考虑过让所有FK列都成为主键的一部分,以便对重复的日志条目提供数据库级别的保护,但这不起作用,因为PK列必须不为NULL

如果您需要更多详细信息,请在评论中说明。谢谢

(是的,这是为了一个与SO没有太大区别的声誉体系)

是的,您可以在声明了外键约束的列中设置
NULL
。列上的
notnull
约束独立于该列上的任何外键约束

外键意味着,如果列具有非NULL值,则该值必须存在于外键约束引用的表的主键中

edit:至于您的
UNIQUE
要求,您是否知道可以对可空列声明
UNIQUE
约束。该列可能包含
NULL
s(与主键约束不同)。这是标准的SQL行为,MySQL支持这种行为

  . . .
  PRIMARY KEY (`id`),
  CONSTRAINT UNIQUE (`giver_user_id`, `receiver_user_id`, 
                     `review_id`, `reputation_event_id`),
  . . .
  . . .
  PRIMARY KEY (`id`),
  CONSTRAINT UNIQUE (`giver_user_id`, `receiver_user_id`, 
                     `review_id`, `reputation_event_id`),
  . . .