iT邦幫忙

2

⚙️ 從 MVC 到單一架構的選擇:EIP 系統效能優化紀錄

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20250614/2015510301hxaE82WX.png

🔄 查詢策略與開發工具的實務經驗分享

在維護企業內部 EIP 系統的過程中,曾經歷幾次明確的架構轉向與效能瓶頸。這篇文章記錄我實際參與與理解的系統演進過程,從 MVC 架構的調整,到查詢策略與資料存取的選擇,背後其實反映的是不同開發階段的取捨與策略。


🏗 初期採用 MVC 架構,但效能瓶頸浮現

一開始,系統是以 ASP.NET 的 MVC 架構開發。這種做法確實有結構分明的好處,開發與維護也更容易分工。不過在實務操作中,我們注意到幾個效能痛點:

  • Controller 處理流程冗長,對於即時性的簽核系統來說稍嫌遲緩
  • 單純呈現表格資料時,仍需經過 MVC 的路由與 ViewModel 包裝
  • 某些畫面會額外載入許多預設元件與套件,拖慢回應時間

為了讓流程更輕巧,團隊決定在非核心流程中改用 WebForm 與簡化結構:一頁中直接撰寫資料查詢與畫面處理邏輯。


🧠 查詢策略:一次查整包 vs 每筆查詢的抉擇

早期系統中,為了保持物件封裝清晰,我們曾採用「逐筆查詢」的作法。每筆列表資料都會轉為一個物件實例,並對資料庫執行一筆 SELECT 查詢,例如顯示 100 筆申請資料就執行 100 次 SQL。

這個作法帶來以下缺點:

  • 整體查詢速度明顯變慢,尤其在高併發場景下特別明顯
  • 每次 HTTP 請求造成大量 DB 開銷,伺服器資源耗盡
  • 難以做分頁或總筆數統計,因為查詢分散不集中

後來調整為「一次查整包」的方式,只對主列表執行一次 SQL 查詢:

SELECT id, name, status, created_at FROM flow_request WHERE ...

若使用者點選「查看詳細資料」才個別查詢,稱為「延遲查詢」策略。

📌 仍適合採用逐筆查詢的情境:

使用條件 建議查詢方式
資料筆數少(例如 < 20 筆) 逐筆查詢
每筆需額外格式處理或封裝 逐筆封裝清晰
即時更新(如帳戶餘額) 每次查詢取得最新資料
記憶體有限或需串流 逐筆查詢搭配迴圈

我們也保留了如 GetRequestDetailById(id) 這類的查詢方法,用於導出或進階查詢,達到彈性與效能間的平衡。


🗃️ DAL vs DBHelper:從安全性與相容性選擇

系統中有兩套資料存取物件:

  • DAL(舊):直接組 SQL,無參數綁定,易除錯但有 SQL injection 風險。
  • DBHelper(新):支援參數化查詢,支援 Oracle/MSSQL/MySQL,安全性較高。

儘管 DBHelper 較佳,但舊模組仍大量使用 DAL,因此我們建立 SafeDAL 類別進行輸入過濾。


🔐 密碼管理機制:正向加密與資料表設計

密碼採用不可逆的雜湊(如 SHA256)儲存,登入時會將輸入密碼雜湊後與資料庫中 password_hash 比對。

🧪 登入驗證流程:

  1. 使用者輸入帳號與密碼。
  2. 後端執行 SHA256 加密。
  3. 與資料庫 password_hash 比對。

✅ 好處:

  • 資料外洩也無法還原原始密碼。
  • 資料表簡潔(僅需一欄)。
  • 管理簡單、權責分離(不需解密)。

🔁 重設密碼時會將其設為預設值(如 9999),加密後存入,使用者下次登入會強制修改。

📌 延伸建議:

  • 增加 last_changed, retry_count, is_locked 等欄位加強安全。
  • 採用 salt 雜湊避免 rainbow table 攻擊。

📌 流程設計:臨時表搭配歷史表

送審資料先寫入 flow_approver_temp,流程完成後再移至 flow_approver_his

✅ 好處:

  • 降低歷史表寫入負擔,避免鎖表
  • 可回滾、流程彈性更高
  • 除錯容易,流程未完成前可清除 temp 資料

🏢 部門設定的彈性設計:虛擬部門與部門移動

部門結構會影響簽核流程與主管遞補,我們從 ERP 同步部門資料後,也提供以下彈性:

🌿 虛擬部門使用情境:

  • 一個部門多位主管:如研發部有三位組長。
  • 流程獨立分流:使用虛擬部門管理流程歸屬。

📌 實作方式:

  • 標記 is_virtual = Y
  • 將其掛在正式部門下,但流程邏輯獨立處理
總公司
└─ 研發部(實體)
    ├─ 研發一組(虛擬)
    ├─ 研發二組(虛擬)

🔄 部門調整:

  • 後台可手動拖曳調整部門層級
  • 會連動更新員工部門與流程簽核節點
  • 歷史流程仍保留原結構不變

🛡️ 並記錄調整 log,可一鍵還原前層級。


🧩 UI 呈現策略:原生 HTML vs .NET 控制項

我們在呈現請假流程狀態時,使用自訂 HTML,而非 GridView 等控制項:

<table>
  <tr>
    <td>節點名稱</td>
    <td>簽核人</td>
    <td>狀態</td>
  </tr>
</table>

✅ 優點:

  • 無 ViewState,頁面更輕巧
  • 彈性高,格式控制容易
  • 效能佳,渲染速度快

⚠️ 缺點:

  • 事件需手寫 JavaScript
  • 邏輯與畫面耦合較高

🛠️ Visual Studio 除錯技巧

維護大型 WebForm 專案時,我通常採「由畫面反查邏輯」的方式:

  1. 先在畫面上找控制項 ID,如 gvFlow, btnSubmit
  2. Ctrl + Shift + F 搜尋使用位置
  3. F12 跳至事件處理函式

這樣可以快速找到核心程式碼,不需讀完整支程式。


✅ 適合詢問 GPT 的 Prompt

我的系統原本採用 MVC 架構,但效能不佳,轉為單一頁面是否更合適?
如何改善逐筆查詢造成的效能瓶頸?是否能改成延遲查詢?
我使用 DAL 串接資料庫,但沒有參數化查詢,要如何降低 SQL injection 風險?
在 ASP.NET WebForm 中,手刻 HTML 與使用控制項各有什麼利弊?

圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言