2008-12-02 70 views
2

首先,讓我先說這個問題,說我是一個非常可怕的數據建模師。我知道只夠危險。MySQL複合PK與可空的FKs

我正在構建的表有四個外鍵,其中兩個引用同一個表。這是該表的創建語句。

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_reputation_log_userfk_reputation_log_user1。每一個聲譽事件都有一個提供者,但只有一些有一個接收者。我會這個FK可以爲空,但我不知道該怎麼做,或者如果它甚至「允許」。

我還玩弄了讓所有FK列成爲主鍵的一部分,以便對重複的日誌條目進行數據庫級保護的想法 - 但由於PK列必須爲NOT NULL,所以這不起作用。

如果您需要更多的細節,請在評論中註明。謝謝!

(是的,這是一個信譽系統從什麼,所以也沒有太多不同)

回答

4
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 
    . . . 

是的,你可以有NULL與它聲明的外鍵約束的列。列上的NOT NULL約束與該列上的任何外鍵約束無關。

外鍵意味着如果該列有非NULL值,那麼該值必須存在於由外鍵約束引用的表的主鍵中。

編輯:至於你的UNIQUE要求,你是否知道你可以聲明一個UNIQUE約束可空列。列可能包含NULL(與主鍵約束不同)。這是標準的SQL行爲,並受MySQL支持。

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

我沒有意識到這一點,但非常感謝您的幫助! – 2008-12-02 19:31:06