Mysql - 觸發器/視圖

来源:http://www.cnblogs.com/elvinle/archive/2016/12/27/6224930.html
-Advertisement-
Play Games

觸發器在之前的項目中, 應用的著實不多, 沒有辦法的時候, 才會去用這個. 因為這個東西在後期並不怎麼好維護, 也容易造成紊亂. 我最近的項目中, 由於資料庫設計(別人設計的)原因, 導致一些最簡單功能, 查詢起來, 都很麻煩和複雜. 牽涉表非常多, 表與表之間又互有部分關係. 我想說, 這是我見過 ...


觸發器在之前的項目中, 應用的著實不多, 沒有辦法的時候, 才會去用這個. 因為這個東西在後期並不怎麼好維護, 也容易造成紊亂.

我最近的項目中, 由於資料庫設計(別人設計的)原因, 導致一些最簡單功能, 查詢起來, 都很麻煩和複雜. 牽涉表非常多, 表與表之間又互有部分關係. 我想說, 這是我見過的最糟糕的資料庫設計了. 最後沒辦法, 公司架構師給了觸發器的解決方案.

一、觸發器

在項目中, 我新建了一張關係表, 把一些必要的, 有效的關係, 通過觸發器的方式, 更新到一張表中, 併在這張表裡面建了索引. 然後讀取數據的時候, 就通過連接這張關係表, 去得到最後的有效數據. 看上去, 有點類似於讀寫分離的趕腳, 不過這並不是多台資料庫伺服器間的.

由於工作的關係, 我不能使用項目中的資料庫來做記錄, 那就自己搞幾個表來玩玩吧. 先建三張表

CREATE TABLE `tch_teacher` (
    `Id` INT (11) NOT NULL AUTO_INCREMENT,
    `Sex` SMALLINT (6) DEFAULT NULL,
    `BId` VARCHAR (36) DEFAULT NULL,
    `No` VARCHAR (20) DEFAULT NULL,
    `Name` VARCHAR (30) DEFAULT NULL,
    `IsDeleted` bit (1) DEFAULT b '0' PRIMARY KEY (`Id`),
    KEY `Index_Sex` (`Sex`) USING BTREE,
    KEY `Index_BId` (`BId`) USING BTREE
) ENGINE = INNODB AUTO_INCREMENT = 21 DEFAULT CHARSET = latin1;

CREATE TABLE `tch_contact` (
    `Id` INT (11) NOT NULL AUTO_INCREMENT,
    `TId` INT (11) DEFAULT NULL,
    `QQ` VARCHAR (15) DEFAULT NULL,
    `Weixin` VARCHAR (50) DEFAULT NULL,
    `Phone` VARCHAR (15) DEFAULT NULL,
    PRIMARY KEY (`Id`),
    KEY `Index_TId` (`TId`) USING BTREE
) ENGINE = INNODB AUTO_INCREMENT = 11 DEFAULT CHARSET = latin1 COMMENT = '聯繫方式表';

CREATE TABLE tch_all (
    Id INT NOT NULL,
    Sex SMALLINT,
    BId VARCHAR (36),
    NO VARCHAR (20),
    NAME VARCHAR (30),
    QQ VARCHAR (15),
    Weixin VARCHAR (50),
    Phone VARCHAR (15)
) COMMENT '完整表';

 

我這裡就通過觸發器的方式, 來維護tch_all這張表. 例子不好, 主要是介紹功能, 見諒.

delimiter $
drop trigger if EXISTS tg_insert_all;
create trigger tg_insert_all after insert on tch_teacher for each ROW
BEGIN
  insert into tch_all(Sex,BId,NO,NAME) values(new.sex, new.bid, new.no, new.name);
end $
delimiter;

1. 語法

create trigger 觸發器名 before/after insert/update/delete on 表名 for each row

begin

end

 

1. 觸發時機 before/after

這裡的觸發器, 觸發的時機是在tch_teacher表數據插入之後. 也就是說, tch_teacher插入成功了之後, 才會向tch_all表插入數據. 這裡有一個點需要註意下. 在tch_teacher插入成功後, 向tch_all插入的時候報錯, 那麼tch_teacher的新插數據就回被回滾.

有插入後觸發, 自然就有插入前觸發, 只需要將after改成before即可. 

before觸發, 則會先想tch_all插入數據, 再向tch_teacher插入數據. 插入過程中, 不管哪一步失敗, 都會回滾數據. 所以不需要擔心, 觸發不成功的情況下, 會不會造成冗餘或者錯誤數據.

 

2. 觸發方式 insert/update/delete

觸發方式, 有插入/修改/刪除 時觸發. 例子中我只寫了插入觸發別的兩種方式的使用方法是和這個一樣的.

 

3. 原數據引用  old/new

這裡有一個問題, 我修改了數據, 那麼我怎麼引用他們呢? 既然修改了數據, 那肯定是有 修改前數據和修改後新數據 的引用的, 

這裡直接使用 old 來指向修改前的數據, new 指向修改後的數據. 這裡的指向, 是指向的tch_teacher中的數據, 不是tch_all的數據.

 

4. 註

例子中, 我只用了一句話, 例子嘛, 簡單就好. 其實在實際使用過程之中, 不會是這麼簡單的. 舉個例子說吧.

很多時候, 由於數據重要性, 不會直接刪除數據. 而是選擇更新數據狀態來表示其已不再使用. 這裡就用 isdeleted來表示, 0表示能用, 1表示不再使用.

當我更新tch_teacher的isdeleted的值為1的時候, 觸發修改觸發器, 在觸發器中, 我就需要判斷 new.isdeleted的值, 從而選擇是否刪除關係表中的數據.

delimiter $
DROP TRIGGER IF EXISTS tg_update_all ; 
CREATE TRIGGER tg_update_all AFTER UPDATE ON tch_teacher FOR EACH ROW
BEGIN
IF new.isdeleted = 1 THEN
    DELETE FROM tch_all WHERE id = old.id ;
ELSE
    UPDATE tch_all set sex=new.sex, bid=new.bid, NO=new.NO, NAME=new.NAME where id = old.id;
END IF ;
END$
delimiter ;

到這裡, 我發現好像沒有繼續這個例子的必要了, 好吧, 那就這樣了.

 

二、視圖

視圖的作用: 簡化查詢, 提升查詢速度.

老版本的mysql, 並不支持視圖子查詢, 但是新版本的mysql, 已經能支持了.

就上面這個例子而言, 其實也可以使用視圖的方式, 去解決複雜的邏輯.

單是就查詢性能上來說, 我覺得還是觸發器的方式快一些. 畢竟觸發器維護了一張新表, 而且新表能夠建索引來提升查詢速度. 就是維護起來比較麻煩.

delimiter $
drop view if EXISTS v_all; -- 刪除視圖
create view v_all AS    -- 新建視圖
select tch_teacher.*,tch_contact.QQ,tch_contact.Weixin,tch_contact.Phone from tch_teacher 
left join tch_contact on tch_teacher.Id=tch_contact.TId where tch_teacher.IsDeleted=0 $
delimiter;

這裡我使用到了一個東西:delimiter, 這個在mysql中, 是用來分割的. 

"delimiter $" 到 "$ delimiter;" 之間的東西是獨立的. 所以, 如果將觸發器的腳本和視圖的腳本放在一個腳本中去執行, 是能夠執行的.

如果是單個執行, 就不需要加那個了. 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 普通分頁 數據分頁在網頁中十分多見,分頁一般都是limit start,offset,然後根據頁碼page計算start 這種分頁在幾十萬的時候分頁效率就會比較低了,MySQL需要從頭開始一直往後計算,這樣大大影響效率 我們可以用explain分析下語句,沒有用到任何索引,MySQL執行的行數是16 ...
  • Mysql提供的函數是在是太多了, 很多我都見過, 別說用了. 園子裡面, 有人弄了一個比較全的. MYSQL函數 我這裡會將他寫的完全拷貝下來, 中間會插入一些自己項目中使用過的心得 一、數學函數 數學函數, 說實話, 我暫時還真沒怎麼用過, 就是在系統中做統計的時候, 也沒用過. 能在程式中處理 ...
  • SQLServer定時作業任務:即資料庫自動按照定時執行的作業任務,具有周期性不需要人工干預的特點 創建步驟:(使用最高許可權的賬戶登錄--sa) 一、啟動SQL Server代理(SQL Server Agent) 二、新建作業 三、設置作業常規屬性 四、設置作業步驟 五、設置作業計劃 六、點擊"確 ...
  • 資料庫分為關係型資料庫(關係型資料庫強調的是 表跟表建立在誰跟誰有關係的基礎上進行設計 ;你是他的,他是她的,她是它的;基本最終都能找到一個數據 是誰的。這就是關係型資料庫了) 以前傳統的資料庫都是關係型資料庫 Oracle、SQLServer、Sybase、Informix、access、DB2、 ...
  • 在資料庫操作中, 尤其是碰到一些複雜一些的系統, 不可避免的, 會用到函數/自定義函數, 或者存儲過程. 實際項目中, 自定義函數和存儲過程是越少越好, 因為這個東西多了, 也是一個非常難以維護的地方. 一、自定義函數 1. 例子 mysql提供的函數, 不在這一篇講了, 這裡主要貼一下自定義函數. ...
  • 本文列舉了史上八大MySQL宕機事件原因、影響以及人們從中學到的經驗,文中用地震級數來類比宕機事件的嚴重性和後果,排在最嚴重層級前兩位的是由於亞馬遜AWS宕機故障(相當於地震十級和九級)。一、Percona網站宕機事件震級:3 發生時長:2011年7月11日 持續時長:數日 地點:加州Pleasan ...
  • 最近使用SQL*Plus命令生成html文件,遇到一些有意思的知識點,順便記錄一下,方便以後需要的時候而這些知識點又忘記而捉急。好記性不如爛筆頭嗎! 為什麼要用SQL*Plus生成html文件? 有些人肯定會問,我使用SQL*Plus為什麼要生成html文件呢? SQL*Plus本身就是一個命令工具... ...
  • Redis緩存伺服器是一款key/value資料庫,讀110000次/s,寫81000次/s,因為是記憶體操作所以速度飛快,常見用法是存用戶token、簡訊驗證碼等 官網顯示Redis本身並沒有Windows版本的,微軟官方開發了基於Windows的Redis伺服器:MSOpenTech/redis ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...