2

我在当前架构为的应用程序中有一个表:

CREATE TABLE quotes
(
  id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  quote_request_id INT UNSIGNED NOT NULL,
  quote_amount DECIMAL(12, 2) NOT NULL,
  accepted TINYINT UNSIGNED NOT NULL DEFAULT 0,
  FOREIGN KEY (quote_request_id) REFERENCES quote_requests(id)
) Engine=InnoDB;

我想强制执行一个约束,使得对于给定的报价请求只能接受一个报价 - 即,如果它尝试修改表以便两个或多个具有相同quote_request_id值的行将具有accepted值,则 UPDATE 或 INSERT 查询应该失败1.

这在 MySQL 中可能吗?强制执行约束,例如外键、除主键以外的列的唯一性等工作正常,我可以找到有关将 UNIQUE 约束应用于多个列的信息,但我找不到有关涉及多个列的更复杂约束的任何信息。

4

3 回答 3

1

如果您想在没有触发器的情况下执行此操作,您可以添加另一个表,其中仅存储接受的报价 - 您可以accepted从表中删除该列quotes

CREATE TABLE quotes
(
  id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  quote_request_id INT UNSIGNED NOT NULL,
  quote_amount DECIMAL(12, 2) NOT NULL,
  --- accepted TINYINT UNSIGNED NOT NULL DEFAULT 0,             --- removed
  FOREIGN KEY (quote_request_id) REFERENCES quote_requests(id)
  UNIQUE KEY (quote_request_id, id)               --- needed for the FK below
) Engine=InnoDB;

CREATE TABLE quotes_accepted
(
  id INT UNSIGNED NOT NULL PRIMARY KEY,
  quote_request_id INT UNSIGNED NOT NULL,
  UNIQUE KEY (quote_request_id),            --- this ensures there is only one
                                            --- accepted quote per request
  FOREIGN KEY (quote_request_id, id) 
    REFERENCES quotes(quote_request_id, id)
) Engine=InnoDB;
于 2012-07-23T08:22:13.387 回答
0

你的意思是你想要UNIQUE这样的:

UNIQUE `quote_accepts` (`quote_request_id`, `accepted`)

其中,对于一对重复的quote_request_id& acceptedINSERT将失败。

于 2012-07-13T08:42:05.350 回答
0

由 a_horse_with_no_name 回答,但在评论中无法接受:

“我认为如果不恢复到 MySQL 中的触发器,这是不可能的,因为 MySQL 不支持部分索引。”

于 2012-07-23T08:11:58.767 回答