关系: students (1 can have N) addresses
情景:学生可以拥有多条记录,但只有一条相关记录必须包含current
'字段设置为' Yes
' (其他值为NULL
)因此,下面的查询应始终只返回每位学生一条记录。
SELECT * FROM address WHERE student_id = 5 AND current = 'Yes'
问题: 人们有时会将不止一个记录标记为“是”'在INSERT或UPDATE之后为同一个学生,所以我需要避免它。在MySQL中使用触发器或存储过程的最佳方法是什么?
如果更新地址发生在'地址'表然后这应该在某处运行以将其他记录标记为NULL:UPDATE addresses SET current = NULL WHERE student_id = IN_student_id
如果INSERT发生在&#39;地址&#39;表然后这应该在某处运行以将其他记录标记为NULL:UPDATE addresses SET current = NULL WHERE student_id = IN_student_id AND id <> IN_inserted_id
提前致谢
答案 0 :(得分:3)
如果您需要在修改数据后自动更新某些内容,那么正确的方法就是触发器。请注意,触发器可能会调用存储过程。
但是,您将无法在触发器because中实现所描述的行为:
存储的函数或触发器不能通过调用函数或触发器的语句修改已经使用(用于读取或写入)的表。
实际上,“地址X是当前地址”的信息应该存储在students
表的一列中,作为address
表的外键。因此,保证了单一性。
像这样(fiddle with it here):
CREATE TABLE student (
id INT NOT NULL PRIMARY KEY,
current_address INT,
name VARCHAR(20)
);
CREATE TABLE address (
id INT NOT NULL PRIMARY KEY,
student_id INT NOT NULL,
contents VARCHAR(50) NOT NULL,
CONSTRAINT student_fk FOREIGN KEY student_fk_idx (student_id)
REFERENCES student(id)
);
ALTER TABLE student
ADD CONSTRAINT curraddr_fk_idx
FOREIGN KEY curraddr_fk_idx (id, current_address)
REFERENCES address(student_id, id);
请注意,此结构允许插入students
而不包含“当前地址”。这是因为两个表中至少有一个必须为其外键允许NULL
值(否则我们无法在任一表中添加单行)。如果更有意义,请让address.student_id
改为NULL
,并允许address
为无人地址,直到您创建相应的student
。