Pergunta

Primeiro, deixe-me começar esta questão, afirmando que eu sou realmente um muito terrível modelador de dados. Eu sei apenas o suficiente para ser perigoso.

A tabela que estou construindo tem quatro chaves estrangeiras, duas das quais fazem referência à mesma mesa. Aqui está a declaração criar para essa tabela.

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;

Os índices eu estou preocupado com para este post são fk_reputation_log_user e fk_reputation_log_user1. Cada evento reputação tem um doador, mas apenas alguns têm um receptor. Eu faria como este FK ser anulável, mas eu não sei como fazer isso, ou se é mesmo "permitido".

Eu também brincou com a idéia de fazer tudo o FK colunas parte da chave primária para ter proteção em nível de banco de dados contra entradas de log duplicadas -. Mas isso não vai trabalho desde colunas PK tem que ser NOT NULL

Se você precisar de mais detalhes, por favor, estado que nos comentários. Obrigado!

(Sim, este é um sistema de reputação não muito diferente do que isso tem)

Foi útil?

Solução

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

Sim, você pode ter NULL em uma coluna com uma restrição de chave estrangeira declarou sobre ele. A restrição NOT NULL numa coluna é independente de qualquer chave estrangeira constrangimento (s) em que a coluna.

Um meio de chaves estrangeiras que se a coluna tem um valor diferente de NULL, em seguida, esse valor deve existir na chave primária da tabela referenciada pela restrição de chave estrangeira.

Editar: Quanto à sua exigência UNIQUE, você está ciente que você pode declarar uma restrição UNIQUE em colunas anuláveis. A coluna pode conter NULLs (ao contrário da restrição de chave primária). Este é o comportamento padrão SQL, e é suportado pelo MySQL.

  . . .
  PRIMARY KEY (`id`),
  CONSTRAINT UNIQUE (`giver_user_id`, `receiver_user_id`, 
                     `review_id`, `reputation_event_id`),
  . . .
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top