2008-09-03 58 views
27

我曾經與禁止使用SQL視圖的架構師合作過。他的主要原因是,對於一個毫無思想的編碼人員來說,視圖太容易不必要地涉及到連接的表格,如果編碼人員更努力地嘗試,可以完全避免。隱含地說,他鼓勵通過複製粘貼來代碼重用,而不是在視圖中封裝。SQL Server視圖,祝福還是詛咒?

該數據庫有近600個表,並且高度規範化,所以大多數有用的SQL必須是冗長的。

幾年後,我可以看到至少有一個禁令的壞結果 - 我們有數百個密集,冗長的存儲過程瀕臨不可維護。

回想起來,我會說這是一個糟糕的決定,但是您對SQL視圖有什麼經驗?你覺得它們對性能不好嗎?任何其他想法,當他們是否合適?通過複製和粘貼

重用通過創建一個視圖代碼

他是令人鼓舞的代碼重用:

回答

29

有一些很好用的意見;我已經用它們進行了很多調整,並將更少的標準化信息暴露出來,或者將多個選擇的UNION結果顯示爲單個結果集。

很明顯,任何編程工具都可能被錯誤地使用,但我不能想到任何時候,根據我的經驗,從性能角度來看,調整不好的視圖會導致任何類型的缺陷,並且他們可以通過顯式提供調整選擇和避免複製SQL代碼的重複可能是重要的。順便說一下,我從來不是一個建築「規則」的粉絲,他們是建立在讓開發者不受傷害的基礎上的。這些規則通常會產生意想不到的副作用 - 我工作的最後一個地方不允許在數據庫中使用NULL,因爲開發人員可能會忘記檢查null。這最終迫使我們在所有針對數據庫構建的軟件中都要求「1/1/1900」日期和整數默認爲「0」,並且引入了由開發​​人員引起的一系列錯誤,這些錯誤是在NULL值爲合適值的地方工作的。

+7

+1,但我遇到過設計不好的情況導致可怕表現的情況。情況是SQL2K有兩個視圖執行工會,然後在第三個視圖中加入。在這個特定情況下,性能降低了1000倍。 – BlackWasp 2009-02-23 22:18:30

+0

遇到此問題。我們正在爲有性能問題的公司提供諮詢服務。我們也給他們一個基於PDA的解決方案,以配合他們現有的系統。他們對每張桌子都有一個觀點。他們對系統使用的每個查詢都有一個視圖。而且他們希望我們能夠爲我們基於PDA的系統訪問其數據庫所用的每個查詢分別提供一個視圖。我告訴他們這是一個可怕的想法。我應該繼續他們的做事方式嗎?我可以將此作爲單獨的問題發佈在SO上。 – 2012-04-11 12:37:17

19

你已經回答了你自己的問題。如果視圖執行效果不佳,那麼追蹤起來要比在幾個地方執行相同的性能不佳的代碼要容易得多。

5

我目前的數據庫完全充斥着無數個不超過5行的小表。那麼,我可以指望他們,但它很混亂。這些表只是保持常量類型的值(想想枚舉),並可以很容易地組合成一個表。然後我製作了一些視圖,模擬了我刪除的每個表格,以確保向後緊湊。工作很好。

1

我們使用所有簡單數據導出到csv文件的視圖。這簡化了編寫一個程序包並將sql嵌入到程序包中的過程,該程序變得繁瑣且難以調試。

使用視圖,我們可以執行視圖並準確查看導出的內容,沒有死鎖或未知。它極大地幫助解決了不正確的數據導出問題,並隱藏了視圖背後的任何複雜連接。當然,我們使用一個來自基於TERMS的系統的非常古老的遺留系統,該系統導出到sql,所以連接比平常複雜一點。

3

視圖對臨時查詢很有用,DBA在後臺需要快速訪問數據以查看系統正在發生的情況時在後臺執行此操作。

但它們可能對生產代碼不利。部分原因在於,由於where子句可能不同,因此很難調整,所以您需要使用視圖的索引是不可預知的。另外,對於使用視圖的單個查詢,您通常會返回比實際需要更多的數據。這些查詢中的每一個都可以分別收緊和調整。

對於數據分區情況下視圖的具體用途可能非常有用,所以我並不是說他們應該完全避免。我只是說如果一個視圖可以被一些存儲過程所取代,那麼沒有視圖就會更好。

4

和所有的力量一樣,意見有它自己的陰暗面。但是,對於編寫不良執行代碼的人來說,您不能責怪他們的觀點。此外,視圖可以限制某些列的暴露並提供額外的安全性。

0

讓我們來看看,如果我能想出一個蹩腳的比喻......

「我不需要十字螺絲起子。我隨身攜帶一個平頭和研磨機!」

失控意見將導致長期的痛苦。首先,調試和修改單個視圖定義比發佈修改後的代碼更容易。

4

迄今尚未提及的一件事是使用視圖爲最終用戶提供特別報告或類似數據的邏輯圖。

這樣做有兩個優點:

  1. 爲了讓用戶以單一的「表」中的數據,他們預計而是需要相對非技術用戶制定出潛在的複雜的連接(因爲數據庫是歸一化)
  2. 它提供了一種手段來允許某種程度的自組織訪問而不將數據或結構暴露給最終用戶。

即使非臨時報告其有時signicantly更容易提供一個視圖包含relveant數據,整齊地分離的生產數據來自同一演示文稿的報告制度。

1

前一段時間我一直試圖維護使用從意見內置內置意見看法......那是在一個**疼痛代碼,所以我有點過敏意見:)

我通常更喜歡直接使用表格,特別是對於速度是主要問題的Web應用程序。當直接訪問表時,您有機會調整SQL查詢以獲得最佳性能。 「預編譯」/緩存的工作計劃可能是視圖的一個優點,但在許多情況下,即時編譯包含所有給定的參數,並且考慮的條款將導致更快的處理。

但是,這並不完全排除視圖,如果使用得當。例如,如果需要,可以使用一個視圖,將「users」表與「users_status」表連接起來,以獲取每個狀態的文本解釋。但是,如果你不需要解釋:使用「users」表,而不是視圖。一如既往:用你的大腦!

16

不是很大的看法(不記得上次我寫了一個),但也不完全禁止它們。如果您的數據庫允許您在視圖上放置索引,而不僅僅放在桌面上,那麼通常可以提高性能,使其更好。如果您正在使用視圖,請務必查看它們的索引。

我真的只看到了需要爲視圖數據分區和極其複雜的連接是給應用程序(這裏的財務報告,其中從一切相同的數據集開始可能是批判性思維)真正的關鍵。我知道一些報表工具似乎更喜歡存儲過程的視圖。

我是一個很大的支持者,不會在特定實例中返回比您需要的更多記錄或字段,並且過度使用視圖往往會使人們返回比他們需要的更多字段(並且太多情況下,太多聯接)這浪費了系統資源。

我還傾向於看到依賴視圖的人(不是視圖的開發人員 - 只使用視圖的人)往往不能很好地理解數據庫(所以如果不使用它們會導致連接錯誤視圖),對我來說,編寫針對數據庫的良好代碼至關重要。我希望人們瞭解他們要求分貝做什麼,而不是依賴視圖的一些魔術黑盒子。當然這都是個人意見,你的里程可能會有所不同。

布拉姆一樣,我個人還沒有發現它們更容易維護比存儲的特效。

編輯於2010年10月添加: 由於我原本寫這個,我有機會與由沉迷於使用視圖的人設計的幾個數據庫一起工作。更糟糕的是,他們使用調用視圖的視圖(最終達到可以調用的表的數量限制)的視圖。這是一場表演噩夢。花費8分鐘在一個視圖中獲取記錄的簡單計數(*),並花費更長的時間才能獲取數據。如果您使用視圖,請謹慎使用調用其他視圖的視圖。您將構建一個系統,在生產的正常性能負載下很可能無法正常工作。在SQL Server中,您只能索引不調用其他視圖的視圖,因此當您在鏈中使用視圖時最終發生的情況是,必須爲每個視圖構建整個記錄集,直到找到最後一個應用where子句條件。您可能需要生成數百萬條記錄才能看到三條記錄。如果您真的只需加入一次,您可以連接6次同一張表,但在最終結果集中,您可能會返回比您需要的更多的列數。

0

意見已經由從生產數據庫動用公共基於Web的應用一直對我們有幫助在其使用的角色。簡化的安全性是我們看到的主要優勢,因爲數據庫中的表設計可能會將同一表中的敏感數據和非敏感數據組合在一起。一個存儲過程分享了這個優點,但是這個視圖是隻讀的,具有潛在的互操作優勢,對於初級人員來說這是一個不太複雜的事情。

當視圖用於最終用戶的即席查詢此安全抽象的優勢也適用;如果我們有一個適當的,扁平化的數據倉庫來表示我們的數據,這將不是什麼好處。

0

視圖還可以減少複雜的查詢的大小(以同樣的方式存儲的特效可以)。

這樣可以減少網絡帶寬非常繁忙的數據庫。

0

從使用ORM的應用程序立場來看,執行自定義查詢要比在離散映射類型上進行選擇要困難得多(例如,視圖)。例如,如果只需要5個表中有多個(比如30或40)的字段,ORM框架將創建一個實體來表示表。

這意味着即使您只需要實體的一些屬性,ORM框架生成的select查詢也會帶來整個實體的全部榮耀。另一方面,儘管也映射到具有ORM框架的實體,但只會帶來您需要的數據。其次,由於ORM框架將實體映射到表,因此實體之間的關係在客戶端生成(並水合),這意味着查詢必須執行並返回到應用程序,然後這些實體可以在運行時發生應用程序。

一些框架通過從一個巨型選擇中的多個鏈接實體(具有多個連接)返回數據繞過該框架,在一次調用中引入所有相關表的列。框架內部分解巨大的結果集,並在將這些實體返回給調用者應用程序之前構造鏈接實體的邏輯表示。

要點是,視圖是使用ORM的應用程序的救星。另一種方法是手動進行數據庫調用,並手動將結果記錄集傳遞給可用的實體/模型。

雖然這種方法很好,並且肯定會產生結果,但它有許多消極的方面。手動代碼...是手動的;難以維護,實施繁瑣,並且導致開發人員更多地關注數據庫提供者API與邏輯域模型的細節。更不用說,它增加了開發,維護,缺陷表面積等生產時間(其更多的勞動成本)。

因此,對於任何人說視圖不好,請考慮事物的另一面;這些高級和強大的DBA最常不知道的東西。