GreatSQL社區原創內容未經授權不得隨意使用,轉載請聯繫小編並註明來源。 GreatSQL是MySQL的國產分支版本,使用上與MySQL一致。 作者: 亮 文章來源:GreatSQL社區原創 概念介紹 首先需要知道MySQL中觸發器特點,以及表table相關觸發器載入方式 MySQL中單個tri ...
- GreatSQL社區原創內容未經授權不得隨意使用,轉載請聯繫小編並註明來源。
- GreatSQL是MySQL的國產分支版本,使用上與MySQL一致。
- 作者: 亮
- 文章來源:GreatSQL社區原創
概念介紹
首先需要知道MySQL中觸發器特點,以及表table相關觸發器載入方式
- MySQL中單個trigger僅支持單事件觸發即單個觸發器不支持類似insert or update等多事件語法操作,如果需要多事件都能被同一個表觸發,只能分別建立多個對應trigger。
- 觸發器載入首先需要載入觸發器分組列表Trigger_chain,後續再將具體觸發器添加到Trigger_chain內。
- 表table屬性內可包含多個觸發器分組列表Trigger_chain,Trigger_chain用於載入不同類別的觸發器,主要類別有insert、update或delete類型。
- 觸發器分組列表Trigger_chain內m_triggers又可載入多個具體屬於該分組的具體觸發器。
觸發器分組列表Trigger_chain載入過程
1.當打開表table時通過如下函數過程載入觸發器分組列表Trigger_chain
函數open_tables->open_and_process_table->handle_table->add_tables_and_routines_for_triggers
2.跟蹤add_tables_and_routines_for_triggers函數內參數定義
查看TRG_EVENT_MAX定義
enum enum_trigger_event_type {
TRG_EVENT_INSERT = 0,
TRG_EVENT_UPDATE = 1,
TRG_EVENT_DELETE = 2,
TRG_EVENT_MAX
};
查看TRG_ACTION_MAX定義
enum enum_trigger_action_time_type {
TRG_ACTION_BEFORE = 0,
TRG_ACTION_AFTER = 1,
TRG_ACTION_MAX
};
查看函數get_triggers內可知觸發器載入存儲方式是二維數組m_trigger_map內
/// Triggers grouped by event, action_time.
Trigger_chain *m_trigger_map[TRG_EVENT_MAX] [TRG_ACTION_MAX];
- 綜合TRG_EVENT_MAX和TRG_ACTION_MAX以及m_trigger_map可以看出目前MySQL觸發器載入設計方式存在一定的弊端,即TRG_EVENT分組只能按insert、update、delete區分,單次觸發事件只能觸發執行對應分組內的觸發器,對於需要擴展單觸發器同時支持多事件的方式如:insert or update 、update or delete 等方式將需要較大的改造。
觸發器分組列表Trigger_chain添加具體觸發器trigger過程
1.打開過的table其觸發器通過如下函數過程載入
- 函數open_tables->open_table_entry_fini->check_n_load
2.具體載入過程
-
通過函數 check_n_load內調用load_triggers函數從磁碟載入已經建好的觸發器t。
-
然後調用create_trigger_chain函數獲取到前期已經載入的觸發器分組列表Trigger_chain。
-
最後觸發器分組列表Trigger_chain調用add_trigger添加具體觸發器t至分組列表內。
當目標表table有insert、update或delete操作時,即會觸發執行對應分組列表Trigger_chain內相應分組的觸發器。
說明:MySQL在新增和刪除觸發器的操作時都會關閉當前已經打開的table句柄,在下次打開table時會重新load相應的trigger。
Enjoy GreatSQL