MST

星途 面试题库

面试题:MySQL触发器在复杂Schema关系维护中的应用

有一个银行数据库Schema,包含账户表(accounts)、交易记录表(transactions)以及余额变更记录表(balance_changes)。当在transactions表插入一条新的交易记录时,需要通过触发器实现:如果是存款交易,更新accounts表中的账户余额,并在balance_changes表记录余额增加情况;如果是取款交易,先检查账户余额是否足够,若足够则更新账户余额并记录余额减少情况,若不足则抛出异常并回滚操作。请写出实现该功能的MySQL触发器代码,并阐述在这种复杂Schema关系下使用触发器的注意事项。
34.5万 热度难度
数据库MySQL

知识考点

AI 面试

面试题答案

一键面试

MySQL触发器代码

DELIMITER //

CREATE TRIGGER update_account_balance
AFTER INSERT ON transactions
FOR EACH ROW
BEGIN
    DECLARE current_balance DECIMAL(10, 2);
    -- 获取当前账户余额
    SELECT balance INTO current_balance FROM accounts WHERE account_id = NEW.account_id;
    
    IF NEW.transaction_type = '存款' THEN
        -- 更新账户余额
        UPDATE accounts SET balance = current_balance + NEW.amount WHERE account_id = NEW.account_id;
        -- 记录余额增加情况
        INSERT INTO balance_changes (account_id, change_type, change_amount, change_date)
        VALUES (NEW.account_id, '增加', NEW.amount, NOW());
    ELSEIF NEW.transaction_type = '取款' THEN
        IF current_balance >= NEW.amount THEN
            -- 更新账户余额
            UPDATE accounts SET balance = current_balance - NEW.amount WHERE account_id = NEW.account_id;
            -- 记录余额减少情况
            INSERT INTO balance_changes (account_id, change_type, change_amount, change_date)
            VALUES (NEW.account_id, '减少', NEW.amount, NOW());
        ELSE
            SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '账户余额不足';
        END IF;
    END IF;
END //

DELIMITER ;

使用触发器的注意事项

  1. 性能影响
    • 触发器会在特定事件发生时自动执行,每一次触发都会带来额外的开销。在高并发环境下,如果触发器逻辑复杂,可能会影响数据库的整体性能。例如在上述例子中,每次插入交易记录都要查询账户余额,更新账户表和插入余额变更表,这些操作如果在大量并发插入时,可能导致数据库响应变慢。
  2. 维护难度
    • 触发器增加了数据库逻辑的复杂性。由于触发器的代码与表结构紧密耦合,当表结构或业务逻辑发生变化时,触发器也需要相应修改。例如,如果accounts表中balance字段的数据类型发生变化,触发器中获取和更新余额的代码都需要调整。此外,多个触发器之间可能存在相互依赖关系,这进一步增加了维护的难度。
  3. 可移植性
    • 不同数据库系统对触发器的支持和语法存在差异。例如MySQL、Oracle和SQL Server的触发器语法就不完全相同。如果项目有数据库迁移的需求,基于MySQL编写的触发器可能无法直接在其他数据库系统中使用,需要进行大量的修改。
  4. 调试困难
    • 触发器在数据库层面执行,其执行过程不像应用程序代码那样容易调试。如果触发器出现错误,排查问题可能比较困难。例如,上述代码中如果SIGNAL抛出的异常没有在应用层正确捕获,很难直接定位到是触发器中余额不足的问题。