2013-04-27 36 views
0

相當theoritical的問題,但在一個較長的發展長期重要:MySQL的程序開發,而不是發送大查詢

方案A(一般情況):

  • 我建立我的查詢客戶端側,並將它們發送到服務器。 (由PHP,Perl,任何)
  • 優點:更快的開發,因爲查詢字符串只建立在客戶端,並且可以很容易修改(代碼必須在客戶端修改)。 CRUD可以很容易地開發OO(面向對象)。
  • 缺點:如果查詢更大,更相似,我必須發送長查詢字符串,如果重複,我應該更好地準備它們以節省網絡負載。 (例如執行大量INSERT語句的導入腳本/應用程序)。

方案B:

  • 我創造了一些常用的程序,以獲取或我的表,其中有一些通用的輸入參數創建數據,並通過他們建立查詢字符串在服務器上側。
  • 優點:我發送一個簡短的查詢字符串到服務器的參數,低網絡負載。
  • 缺點:開發需要更長的時間,創造概念來推廣查詢,客戶必須瞭解程序及其版本。

意見?這是真的還是假的,我總結的是什麼?有人有過這方面的經驗?

+1

您是否考慮過任何一種情況下的安全問題? – jsalonen 2013-04-27 22:46:11

+0

不是真的在第一輪計劃中......但通過程序過濾以避免mysql注入也是一個好主意,我猜...因爲通過過程包裝所有輸入參數可能是一個簡單的開發增強,或者不? – StrictLine 2013-04-28 13:17:37

+0

@ALL ANSWERER:我的想法是生成數據庫操作代碼(ALTER TABLE,CREATE PROCEDURE等),併爲(網絡)應用工程師提供管理後端界面來設計它們。在這種情況下,可維護性在情景A和情景B中具有相同的複雜度級別,但是抽象的位置和級別是不一樣的...... – StrictLine 2013-04-28 13:39:29

回答

2

如果你正在開發一個應用程序,那麼 - 在最終狀態 - 我認爲應用程序中的唯一查詢應該是類似於select <list of columns> from view where <whatever>的東西,唯一的數據操作語句應該是對返回適當錯誤的存儲過程的調用消息傳遞給應用程序。

換句話說,您想爲應用程序開發一個API。 SQL提供了一個API(insert/update/delete),但我不認爲原始SQL適用於大多數數據庫應用程序。

在開發過程中,我更加靈活。可能需要在應用程序方面進行復雜的查詢以快速解決某些問題。他們應該只是被遷移到數據庫中。

爲什麼?主要原因是可維護性,並在多個方面。通過將所有查詢訪問包裝到視圖中,可以保護應用程序免受基礎數據結構的更改。畢竟,事情發生了變化,用戶需求也在增長,有時數據模型必須反映這一點。

其次,DBA可以在一個地方看到所有查詢。這爲數據庫和查詢的改進,整合,簡化和優化打開了空間。

將所有數據操作放入存儲過程允許您在沒有觸發器的情況下實現業務規則。觸發器可能非常棘手,尤其是當您開始在實現業務規則的多個表之間使用級聯觸發器時。這也允許應用程序端日誌記錄和更易理解的錯誤消息。

此外,使用視圖和存儲過程提供了相當自然的防範SQL注入 - 不完全,但很多。但是在許多數據庫中,您可以防止用戶直接修改表,同時通過存儲過程爲用戶提供修改權限。

+1

我還補充說sprocs可以更好地控制數據訪問和審計。我經常將數據庫配置爲拒絕對應用程序用戶的直接表訪問,而是強制它調用使用提升特權的sprocs,但只有在檢查任何訪問限制並執行適當的審計日誌記錄後才能使用。 – eggyal 2013-04-27 23:43:21

+0

不錯的指南,我真的很感激。每個角度都是我需要考慮的。 – StrictLine 2013-04-28 13:18:45

2

恕我直言的理由使用存儲過程是不是在查詢字符串的所有大小:即使是一個很長的查詢字符串會產生微不足道的網絡開銷,而不是在獲取階段,如果返回的數據。

而且這還不是談論查詢的實際執行的:我還沒有看到一個MySQL服務器,由網絡帶寬,而不是磁盤或CPU的約束。

什麼存儲過程,給你的是更高的抽象水平:如果你的存儲過程稱爲CreateFoo()GetFooById(),您的應用程序並不需要知道,一個foo如何存儲在您的數據庫(包括所有的關係古怪)。

這對維護很有好處,最重要的是它對健壯性有好處:如果您不需要了解foo中涉及的表結構,那麼您的應用程序就沒有機會將其擰緊 - 例如,忘記一個聯接表等。

在本質上,這意味着,你的數據庫需要信任你的應用程序少。在許多情況下,應用程序永遠沒有權限直接操縱表 - 它們可能只有調用存儲過程(例如銀行業務)

也就是說,存儲過程不是銀色的子彈。爲工作使用正確的工具,常識和良好的睡眠似乎對幫助很大。

+0

不幸的是,我不能將答案標記爲好答案,但是無論如何我都會提升您的聲譽。 – StrictLine 2013-04-28 13:29:16

+0

CreateFoo()和GetFooById()的例子是我爲了提供更好的抽象而想到的。 – StrictLine 2013-04-28 13:31:13

0

您最初假設的兩個主要缺陷。

  1. 事實上,每個HTTP請求都帶有很多帶有它的HTTP標頭,高達幾千字節。所以,查詢不會成爲太大的負擔。與多個插入相同:一個小的「INSERT INTO t SET」對於字面值對來說只是一個可以忽略的開銷。field = value,field = value你可以以任何方式在HTTP請求中擁有。
  2. 您是否考慮過任何一種情況下的安全問題?

而且,JFYI:

我創造了一些常用的程序,以獲取或我的表,其中有一些通用的輸入參數創建數據,並通過他們建立查詢字符串在服務器上方

這就是至少有99%的PHP/MySQL網絡應用程序(坦率地說,網站)的作品。可能是他們這樣做的原因。

+0

1.好吧,你說得對。在INSERT語句的情況下,我不會獲得速度,但是在抽象層完全在服務器端實現後,我不必費心建立鏈接表的查詢 - 如果表格已標準化。 例如CreateFoo('thisgoesintotable1','thisgoesintotable2'); – StrictLine 2013-04-28 13:57:14

相關問題