MySQL引用父表中的非唯一值

时间:2015-08-11 22:28:05

标签: mysql

我有一个批准标记,并且希望在父表中更改它时填充它,但是我无法弄清楚如何引用子节点中的父节点来降低值。

作为参考,当我将approval的批准更新为reservedTickets中的0时,我希望将预订中的值1填充到reservations。但是,根据我的理解,我无法使用标准的FOREIGN KEYREFERENCE引用reservations,因为approval并非唯一。

在任何人说出任何关于"为什么不在一张桌子上有价值之前"它是在能够更新reservations表的管理员和非管理员更新reservedTickets之间分离关注点。此外,由于FOREIGN KEY必须加入reservedTickets表以跟踪审批,reservations约束中的CREATE TABLE reservations( rid int NOT NULL AUTO_INCREMENT, aid int NOT NULL, approval tinyint(1) NOT NULL, creationTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (rid), FOREIGN KEY (aid) REFERENCES accounts (aid) ON DELETE CASCADE ); CREATE TABLE reservedTickets( rid int NOT NULL, tid int NOT NULL, hid int NOT NULL, approval tinyint(1) NOT NULL, PRIMARY KEY (tid), FOREIGN KEY (rid) REFERENCES reservations (rid) ON DELETE CASCADE, FOREIGN KEY (tid) REFERENCES tickets (tid) ON DELETE CASCADE, FOREIGN KEY (hid) REFERENCES people (hid) ON DELETE CASCADE, FOREIGN KEY (approval) REFERENCES reservations (approval) ON UPDATE CASCADE ); 约束数量很大,这取决于我的起点。

cellpadding="3" cellspacing="3" 

2 个答案:

答案 0 :(得分:1)

我个人避免级联更新,因为引擎在场景后面发生了许多锁定,但如果你真的想要它,你可以对reservations(rid,approval)reservedTickets中的外键有唯一约束。引用它。据我记得Mysql,它带有额外索引的成本,但它可以为您提供所需的内容 另一方面,您可以使用reservation上的触发器实现所需的功能,或者将其留给应用程序(或仅通过负责携带此标志的存储过程来更新表)。

CREATE TABLE reservations(
    rid int NOT NULL AUTO_INCREMENT,
    aid int NOT NULL,
    approval tinyint(1) NOT NULL,
    creationTime TIMESTAMP 
        DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (rid),
    CONSTRAINT UQ_RESERVATION_COMPOSITE UNIQUE(rid, approval),
    ...
);

CREATE TABLE reservedTickets(
    rid int NOT NULL,
    tid int NOT NULL,
    hid int NOT NULL,
    approval tinyint(1) NOT NULL,
    PRIMARY KEY (tid),
    FOREIGN KEY (rid,approval) REFERENCES reservations (rid,approval)
        ON DELETE CASCADE ON UPDATE CASCADE,
    FOREIGN KEY (tid) REFERENCES tickets (tid)
        ON DELETE CASCADE,
    FOREIGN KEY (hid) REFERENCES people (hid)
        ON DELETE CASCADE , ....
);

答案 1 :(得分:0)

并非如此,您不能在非唯一列上使用foreign key,因为您可以在InnoDB中使用foreign key。但是,如果您在{{1}}上自动更新或删除,则会出现此问题,因为数据库会更新所有相同的密钥。

您可以做的是使用prepared statement,它允许您在从预订表等更新时更新批准列。