1 SQL Server中的索引

            索引是與表或視圖關聯的磁盤上結構,可以加快從表或視圖中檢索行的速度。索引包含由表或視圖中的一列或多列生成的鍵。這些鍵存儲在一個結構(B 樹)中,使 SQL Server 可以快速有效地查找與鍵值關聯的行。

            表或視圖可以包含以下類型的索引:

            聚集索引

            聚集索引根據數據行的鍵值在表或視圖中排序和存儲這些數據行。索引定義中包含聚集索引列。每個表只能有一個聚集索引,因為數據行本身只能按一個順序排序。

            只有當表包含聚集索引時,表中的數據行才按排序順序存儲。如果表具有聚集索引,則該表稱為聚集表。如果表沒有聚集索引,則其數據行存儲在一個稱為堆的無序結構中。

            每個表幾乎都對列定義聚集索引來實現下列功能:

            1、可用于經常使用的查詢。

            2、提供高度唯一性。

            在創建聚集索引之前,應先了解數據是如何被訪問的。考慮對具有以下特點的查詢使用聚集索引:

            使用運算符(如 BETWEEN、>、>=、< 和 <=)返回一系列值。

            使用聚集索引找到包含第一個值的行后,便可以確保包含后續索引值的行物理相鄰。例如,如果某個查詢在一系列采購訂單號間檢索記 錄,PurchaseOrderNumber 列的聚集索引可快速定位包含起始采購訂單號的行,然后檢索表中所有連續的行,直到檢索到最后的采購訂單號。

            返回大型結果集。

            使用 JOIN 子句;一般情況下,使用該子句的是外鍵列。

            使用 ORDER BY 或 GROUP BY 子句。

            在 ORDER BY 或 GROUP BY 子句中指定的列的索引,可以使數據庫引擎 不必對數據進行排序,因為這些行已經排序。這樣可以提高查詢性能。

            聚集索引不適用于具有下列屬性的列:

            頻繁更改的列

            這將導致整行移動,因為數據庫引擎 必須按物理順序保留行中的數據值。這一點要特別注意,因為在大容量事務處理系統中數據通常是可變的。

            寬鍵

            寬鍵是若干列或若干大型列的組合。所有非聚集索引將聚集索引中的鍵值用作查找鍵。為同一表定義的任何非聚集索引都將增大許多,這是因為非聚集索引項包含聚集鍵,同時也包含為此非聚集索引定義的鍵列。 非聚集索引

            非聚集索引具有獨立于數據行的結構。非聚集索引包含非聚集索引鍵值,并且每個鍵值項都有指向包含該鍵值的數據行的指針。

            從非聚集索引中的索引行指向數據行的指針稱為行定位器。行定位器的結構取決于數據頁是存儲在堆中還是聚集表中。對于堆,行定位器是指向行的指針。對于聚集表,行定位器是聚集索引鍵。

            在 SQL Server 2005 中,可以向非聚集索引的葉級別添加非鍵列以跳過現有的索引鍵限制(900 字節和 16 鍵列),并執行完整范圍內的索引查詢。

            非聚集索引與聚集索引具有相同的 B 樹結構,它們之間的顯著差別在于以下兩點:

            1、基礎表的數據行不按非聚集鍵的順序排序和存儲。

            2、非聚集索引的葉層是由索引頁而不是由數據頁組成。

            設計非聚集索引時需要注意數據庫的特征:

            更新要求較低但包含大量數據的數據庫或表可以從許多非聚集索引中獲益從而改善查詢性能。

            決策支持系統應用程序和主要包含只讀數據的數據庫可以從許多非聚集索引中獲益。查詢優化器具有更多可供選擇的索引用來確定最快的訪問方法,并且數據庫的低更新特征意味著索引維護不會降低性能。

            聯機事務處理應用程序和包含大量更新表的數據庫應避免使用過多的索引。此外,索引應該是窄的,即列越少越好。

            一個表如果建有大量索引會影響 INSERT、UPDATE 和 DELETE 語句的性能,因為所有索引都必須隨表中數據的更改進行相應的調整。

            唯一索引

            唯一索引確保索引鍵不包含重復的值,因此,表或視圖中的每一行在某種程度上是唯一的。

            聚集索引和非聚集索引都可以是唯一索引。

            包含性列索引

            一種非聚集索引,它擴展后不僅包含鍵列,還包含非鍵列。

            索引涵蓋

            指查詢中的SELECT與WHERE子句的所用列同時也屬于非聚集索引的情況。這樣就可以更快檢索數據,因為所有信息都可以直接來自于索引頁,從而SQL Server可以避免訪問數據頁。加上獨立的索引文件組,可以用最快速度訪問數據。

            請看如下表示例:

            A.創建簡單非聚集索引 以下示例為 Purchasing.ProductVendor 表的 VendorID 列創建非聚集索引。 

           

                USE AdventureWorks;
            GO
            CREATE INDEX IX_ProductVendor_VendorID
            ON Purchasing.ProductVendor (VendorID);
            GO

            B. 創建簡單非聚集組合索引

            以下示例為 Sales.SalesPerson 表的 SalesQuota 和 SalesYTD 列創建非聚集組合索引。 

           

                CREATE NONCLUSTERED INDEX IX_SalesPerson_SalesQuota_SalesYTD
            ON Sales.SalesPerson (SalesQuota, SalesYTD);
            GO

            C. 創建唯一非聚集索引

            以下示例為 Production.UnitMeasure 表的 Name 列創建唯一的非聚集索引。該索引將強制插入 Name 列中的數據具有唯一性。 

           

                USE AdventureWorks;
            GO
            CREATE UNIQUE INDEX AK_UnitMeasure_Name
            ON Production.UnitMeasure(Name);
            GO

            無論何時對基礎數據執行插入、更新或刪除操作,SQL Server 2005 數據庫引擎都會自動維護索引。隨著時間的推移,這些修改可能會導致索引中的信息分散在數據庫中(含有碎片)。當索引包含的頁中的邏輯排序(基于鍵值)與數 據文件中的物理排序不匹配時,就存在碎片。碎片非常多的索引可能會降低查詢性能,導致應用程序響應緩慢。這個時候,我們需要做得就是重新組織和重新生成索 引。重新生成索引將刪除該索引并創建一個新索引。此過程中將刪除碎片,通過使用指定的或現有的填充因子設置壓縮頁來回收磁盤空間,并在連續頁中對索引行重 新排序(根據需要分配新頁)。這樣可以減少獲取所請求數據所需的頁讀取數,從而提高磁盤性能。

            可以使用下列方法重新生成聚集索引和非聚集索引:

            帶 REBUILD 子句的 ALTER INDEX。此語句將替換 DBCC DBREINDEX 語句。

            帶 DROP_EXISTING 子句的 CREATE INDEX。

            示例如下:

            A. 重新生成索引

          以下示例將重新生成單個索引。  
                USE AdventureWorks;
            GO
            ALTER INDEX PK_Employee_EmployeeID ON HumanResources.Employee
            REBUILD;
            GO

            B.重新生成表的所有索引并指定選項
            下面的示例指定了 ALL 關鍵字。這將重新生成與表相關聯的所有索引。其中指定了三個選項。 
                ALTER INDEX ALL ON Production.Product
            REBUILD WITH (FILLFACTOR = 80, SORT_IN_TEMPDB = ON,
            STATISTICS_NORECOMPUTE = ON);
            GO

                2 Oracle 中的索引
            索引是Oracle使用的加速表中數據檢索的數據庫對象。
            下面的情況,可以考慮使用索引:
            1) 大表
            2) 主鍵(自動索引)
            3) 單鍵列(自動索引)
            4) 外鍵列(自動索引)
            5) 大表上WHERE子句常用的列
            6) ORDER BY 或者GROUP BY子句中使用的列。
            7) 至少返回表中20%行的查詢
            8) 不包含null值的列。
            Oracle中的索引包含有如下幾種類型:
            B*樹索引:這是Oracle中最常用的索引,它的構造類似于二叉樹,能根據鍵提供一行或一個行集的快速訪問,通常只需要很少的讀操作就能找到正確的行。B*樹索引由兩列組成,第一列是ROWID, 它是行的位置;第二列是正被索引列的值。

            圖:典型的B*樹索引布局

            這個樹底層的塊稱為葉子節點(leaf node) 或(leaf block),其中分別包含各個索引鍵以及一個rowid(它是指向所索引的行)。葉子節點之上的內部塊稱為分支塊(branch block),這些節點用于實現導航。例如,如果想在索引中找到值20,要從樹頂開始,找到左分支,我們檢查這個塊,并發現需要找到范圍"20..25" 的塊,這個塊將是葉子塊,其中會指示包含數20的行。索引的葉子節點實際上構成了一個雙向鏈表。一旦發現要從葉子節點中的那里開始,執行值的有序掃描 (index range scan)就會很容易,我們就不必再在索引結構中導航:而只需根據葉子節點向前或向后掃描就可以了。

            B*樹的特點之一是:所有葉子塊都應該在樹的同一層上,這一層稱之為索引的高度, 它說明所有從索引的根塊到葉子塊的遍歷都會訪問同樣數目的塊。也就是說,對于形如"SELECT INDEX_column FROM TABLE WHERE INXDEX_column =:X"的索引,要達到葉子塊來獲取第一行,不論使用的:X值是什么,都會執行同樣數目的I/O,由此可見B*樹的B代表的是balanced,所謂的"Height balanced"。大多數B*樹索引的高度都是2或3,即使索引中有數百萬行記錄也是如此,這說明,一般而言,在索引中找到一個鍵只需要2到3次I/O , 這確實不錯。

            B*樹是一個極佳的通用索引機制,無論是大表還是小表都很適用,隨著底層表大小增長,獲取數據的性能僅會稍有惡化。

            比如,我們為customers表建立一個常見的B*樹索引: 

           

                CREATE INDEX IDX_Cus_City on customers(city)

            B*樹索引有以下子類型:

            復合索引

            復合索引也是一種B*樹索引,它由多列組成。當我們擁有使用兩列或超過兩列的頻繁查詢時,就使用B*樹復合索引,而其所使用的兩列或多列在 where子句中and邏輯操作符連接。因為復合索引中列的順序很重要,所以確信以最有效的索引能排列他們,可以參考用作列排序的下面的兩個準則 :

            1) 前導列應該是查詢中使用最頻繁的列。

            2) 前導列應該是選擇最多的列,這意味著它比后面的列具有更高的基數。

            復合索引在下列情況中具有優勢:

            1)假定在WHERE子句中頻繁使用下面的條件:order_status_id = 1 和order_date = ‘dd-mon-yyyy’。如果為每一列創建一個索引,那么為了搜索列的值,兩個索引都要被讀取,但是如果為兩列都創建一個復合索引,那么只有一個索引 被讀取,這樣無疑比兩個索引要求更少的I/O

            2) 使用前面例子中同樣的條件,如果創建一個復合索引,將更快地檢索行,因為你正在排除了所有order_status_id 不是1的行,從而減少了搜索order_date的行數。

            反向鍵索引

            B*樹索引的另一個特點是能夠將索引鍵“反轉”。首先,你可以問問自己“為什么想這么做?” B*樹索引是為特定的環境、特定的問題而設計的。實現B*樹索引的目的是為了減少“右側”索引中對索引葉子塊的競爭,比如在一個Oracle RAC 環境中,某些列用一個序列值或時間戳填充,這些列上建立的索引就屬于“右側”(right-hand-side)索引。

            RAC 是一種Oracle 配置,其中多個實例可以裝載和打開同一個數據庫。如果兩個實例需要同時修改同一個數據塊,它們會通過一個硬件互連(interconnect)來回傳遞這 個塊來實現共享,互連是兩個(或多個)機器之間的一條專用網絡連接。如果某個利用一個序列填充,這個列上有一個主鍵索引 ,那么每個人插入新值時,都會視圖修改目前索引結構右側的左塊(見本文圖一,其中顯示出索引中較高的值都放在右側,而較低的值放在左側)。如果對用序列填 充的列上的索引進行修改,就會聚集在很少的一組葉子塊上。倘若將索引的鍵反轉,對索引進行插入時,就能在索引中的所有葉子鍵上分布開(不過這往往會使索引 不能得到充分地填充)。

            反向鍵索引創建語句語法如下: 

           

                CREATE INDEX index_name on table_name(column_name) REVERSE ;

            降序索引

            降序索引(descending index)是oracle 8i引入的,用以擴展B*樹索引的功能,它允許在索引中以降序(從大到小的順序)存儲一列。在oracle8i及以上版本中,DESC關鍵字確實會改變創建和使用索引的的方式。

            我們可以這樣創建降序索引

           

                CREATE INDEX IDX_jobs_title on hr.jobs (job_title DESC);
            SET autotrace traceonly EXPLAIN;
            SELECT * FROM hr.jobs
            WHERE job_title Between 'a' AND 'ZZZZZZZZZZZ ';  Execution Plan
            ----------------------------------------------------------
            0 SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1 Bytes=33)
            1 0 FILTER
            2 1 TABLE ACCESS (BY INDEX ROWID) OF 'JOBS' (Cost=1 Card=1 B
            ytes=33)
            3 2 INDEX (RANGE SCAN) OF 'IDX_JOBS_TITLE' (NON-UNIQUE) (C
            ost=2 Card=1)               
            SQL> SELECT * from hr.jobs
            2 WHERE job_title between 'a' and 'ZZZZZZZZZZZ ';
            Execution Plan
            ----------------------------------------------------------
            0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=33)
            1 0 FILTER
            2 1 TABLE ACCESS (FULL) OF 'JOBS' (Cost=2 Card=1 Bytes=33)
            SQL> DROP INDEX IDX_jobs_title ;
            SQL> CREATE INDEX IDX_jobs_title on hr.jobs (job_title );
            SQL> Select * FROM hr.jobs
            2 Where job_title between 'a' and 'ZZZZZZZZZZZ ';
            Execution Plan
            ----------------------------------------------------------
            0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=33)
            1 0 FILTER
            2 1 TABLE ACCESS (FULL) OF 'JOBS' (Cost=2 Card=1 Bytes=33)

            位圖索引

            位圖索引(bitmap index)是從Oracle7.3 版本開始引入的。目前Oracle企業版和個人版都支持位圖索引,但標準版不支持。位圖索引是為數據倉庫/在線分析查詢環境設計的,在此所有查詢要求的數據在系統實現時根本不知道。位圖索引特別不適用于OLTP 系統,如果系統中的數據會由多個并發會話頻繁地更新,這種系統也不適用位圖索引。

            位圖索引是這樣一種結構,其中用一個索引鍵條目存儲指向多行的指針;這與B*樹結構不同,在B*樹結構中,索引鍵和表中的行存在著對應關系。在位圖索引中,可能只有很少的索引條目,每個索引條目指向多行。而在傳統的B*樹中,一個索引條目就指向一行。

            B*樹索引一般來講應當是選擇性的。與之相反,位圖索引不應是選擇性的,一般來講它們應該“沒有選擇性“。如果有大量在線分析查詢,特別是查詢 以一種即席方式引用了多列或者會生成諸如COUNT 之類的聚合,在這樣的環境中,位圖索引就特別有用 。位圖索引使用 CREATE BITMAP INDEX index_name ON table_name(column_name1,column_name2) TABLESPACE tablespace_name命令語法創建。

           

           

           

           

          SQL Server查詢優化技術及索引

          From: http://www.cnblogs.com/lovewindy/archive/2005/02/19/105959.html

           

          在《數據庫原理》里面,對聚簇索引的解釋是:聚簇索引的順序就是數據的物理存儲順序,而對非聚簇索引的解釋是:索引順序與數據物理排列順序無關。正式因為如此,所以一個表最多只能有一個聚簇索引。

          不過這個定義太抽象了。在SQL Server中,索引是通過二叉樹的數據結構來描述的,我們可以這么理解聚簇索引:索引的葉節點就是數據節點。而非聚簇索引的葉節點仍然是索引節點,只不過有一個指針指向對應的數據塊。如下圖:


          非聚簇索引

           


          聚簇索引


          聚簇索引與非聚簇索引的本質區別到底是什么?什么時候用聚簇索引,什么時候用非聚簇索引?

          這是一個很復雜的問題,很難用三言兩語說清楚。我在這里從SQL Server索引優化查詢的角度簡單談談(如果對這方面感興趣的話,可以讀一讀微軟出版的《Microsoft SQL Server 2000數據庫編程》第3單元的數據結構引論以及第6、13、14單元)。


          一、索引塊與數據塊的區別

          大家都知道,索引可以提高檢索效率,因為它的二叉樹結構以及占用空間小,所以訪問速度塊。讓我們來算一道數學題:如果表中的一條記錄在磁盤上占用1000字節的話,我們對其中10字節的一個字段建立索引,那么該記錄對應的索引塊的大小只有10字節。我們知道,SQL Server的最小空間分配單元是“頁(Page)”,一個頁在磁盤上占用8K空間,那么這一個頁可以存儲上述記錄8條,但可以存儲索引800條。現在我們要從一個有8000條記錄的表中檢索符合某個條件的記錄,如果沒有索引的話,我們可能需要遍歷8000條×1000字節/8K字節=1000個頁面才能夠找到結果。如果在檢索字段上有上述索引的話,那么我們可以在8000條×10字節/8K字節=10個頁面中就檢索到滿足條件的索引塊,然后根據索引塊上的指針逐一找到結果數據塊,這樣IO訪問量要少的多。


          二、索引優化技術

          是不是有索引就一定檢索的快呢?答案是否。有些時候用索引還不如不用索引快。比如說我們要檢索上述表中的所有記錄,如果不用索引,需要訪問8000條×1000字節/8K字節=1000個頁面,如果使用索引的話,首先檢索索引,訪問8000條×10字節/8K字節=10個頁面得到索引檢索結果,再根據索引檢索結果去對應數據頁面,由于是檢索所有數據,所以需要再訪問8000條×1000字節/8K字節=1000個頁面將全部數據讀取出來,一共訪問了1010個頁面,這顯然不如不用索引快。

          SQL Server內部有一套完整的數據檢索優化技術,在上述情況下,SQL Server的查詢計劃(Search Plan)會自動使用表掃描的方式檢索數據而不會使用任何索引。那么SQL Server是怎么知道什么時候用索引,什么時候不用索引的呢?SQL Server除了日常維護數據信息外,還維護著數據統計信息,下圖是數據庫屬性頁面的一個截圖:

          從圖中我們可以看到,SQL Server自動維護統計信息,這些統計信息包括數據密度信息以及數據分布信息,這些信息幫助SQL Server決定如何制定查詢計劃以及查詢是是否使用索引以及使用什么樣的索引(這里就不再解釋它們到底如何幫助SQL Server建立查詢計劃的了)。我們還是來做個實驗。建立一張表:tabTest(ID, unqValue,intValue),其中ID是整形自動編號主索引,unqValue是uniqueidentifier類型,在上面建立普通索引,intValue 是整形,不建立索引。之所以掛上一個沒有索引的intValue字段,就是防止SQL Server使用索引覆蓋查詢優化技術,這樣實驗就起不到作用了。向表中錄入10000條隨機記錄,代碼如下:

           

          CREATE TABLE [dbo].[tabTest] (
           
          [ID] [int] IDENTITY (11NOT NULL ,
           
          [unqValue] [uniqueidentifier] NOT NULL ,
           
          [intValue] [int] NOT NULL 
          ON [PRIMARY]
          GO

          ALTER TABLE [dbo].[tabTest] WITH NOCHECK ADD 
           
          CONSTRAINT [PK_tabTest] PRIMARY KEY  CLUSTERED 
           (
            
          [ID]
           )  
          ON [PRIMARY] 
          GO

          ALTER TABLE [dbo].[tabTest] ADD 
           
          CONSTRAINT [DF_tabTest_unqValue] DEFAULT (newid()) FOR [unqValue]
          GO

          CREATE  INDEX [IX_tabTest_unqValue] ON [dbo].[tabTest]([unqValue]ON [PRIMARY]
          GO

          declare @i int
          declare @v int

          set @i=0
          while @i<10000
          begin
              
          set @v=rand()*1000    
              
          insert into tabTest ([intValue]values (@v)
              
          set @i=@i+1
          end

           

          然后我們執行兩個查詢并查看執行計劃,如圖:(在查詢分析器的查詢菜單中可以打開查詢計劃,同時圖上第一個查詢的GUID是我從數據庫中找的,大家做實驗的時候可以根據自己數據庫中的值來定):



          從圖中可以看出,在第一個查詢中,SQL Server使用了IX_tabTest_unqValue索引,根據箭頭方向,計算機先在索引范圍內找,找到后,使用Bookmark Lookup將索引節點映射到數據節點上,最后給出SELECT結果。在第二個查詢中,系統直接遍歷表給出結果,不過它使用了聚簇索引,為什么呢?不要忘了,聚簇索引的頁節點就是數據節點!這樣使用聚簇索引會更快一些(不受數據刪除、更新留下的存儲空洞的影響,直接遍歷數據是要跳過這些空洞的)。

          下面,我們在SQL Server中將ID字段的聚簇索引更改為非聚簇索引,然后再執行select * from tabTest,這回我們看到的執行計劃變成了:

          SQL Server沒有使用任何索引,而是直接執行了Table Scan,因為只有這樣,檢索效率才是最高的。


          三、聚簇索引與非聚簇索引的本質區別

          現在可以討論聚簇索引與非聚簇索引的本質區別了。正如本文最前面的兩個圖所示,聚簇索引的葉節點就是數據節點,而非聚簇索引的頁節點仍然是索引檢點,并保留一個鏈接指向對應數據塊。

          還是通過一道數學題來看看它們的區別吧:假設有一8000條記錄的表,表中每條記錄在磁盤上占用1000字節,如果在一個10字節長的字段上建立非聚簇索引主鍵,需要二叉樹節點16000個(這16000個節點中有8000個葉節點,每個頁節點都指向一個數據記錄),這樣數據將占用8000條×1000字節/8K字節=1000個頁面;索引將占用16000個節點×10字節/8K字節=20個頁面,共計1020個頁面。

          同樣一張表,如果我們在對應字段上建立聚簇索引主鍵,由于聚簇索引的頁節點就是數據節點,所以索引節點僅有8000個,占用10個頁面,數據仍然占有1000個頁面。

          下面我們看看在執行插入操作時,非聚簇索引的主鍵為什么比聚簇索引主鍵要快。主鍵約束要求主鍵不能出現重復,那么SQL Server是怎么知道不出現重復的呢?唯一的方法就是檢索。對于非聚簇索引,只需要檢索20個頁面中的16000個節點就知道是否有重復,因為所有主鍵鍵值在這16000個索引節點中都包含了。但對于聚簇索引,索引節點僅僅包含了8000個中間節點,至于會不會出現重復必須檢索另外1000個頁數據節點才知道,那么相當于檢索10+1000=1010個頁面才知道是否有重復。所以聚簇索引主鍵的插入速度要比非聚簇索引主鍵的插入速度慢很多。

          讓我們再來看看數據檢索的效率,如果對上述兩表進行檢索,在使用索引的情況下(有些時候SQL Server執行計劃會選擇不使用索引,不過我們這里姑且假設一定使用索引),對于聚簇索引檢索,我們可能會訪問10個索引頁面外加1000個數據頁面得到結果(實際情況要比這個好),而對于非聚簇索引,系統會從20個頁面中找到符合條件的節點,再映射到1000個數據頁面上(這也是最糟糕的情況),比較一下,一個訪問了1010個頁面而另一個訪問了1020個頁面,可見檢索效率差異并不是很大。所以不管非聚簇索引也好還是聚簇索引也好,都適合排序,聚簇索引僅僅比非聚簇索引快一點。


          結語

          好了,寫了半天,手都累了。關于聚簇索引與非聚簇索引效率問題的實驗就不做了,感興趣的話可以自己使用查詢分析器對查詢計劃進行分析。SQL Server是一個很復雜的系統,尤其是索引以及查詢優化技術,Oracle就更復雜了。了解索引以及查詢背后的事情不是什么壞事,它可以幫助我們更為深刻的了解我們的系統。

           

           

          SQL Server基礎知識之:設計和實現視圖

          設計和實現視圖可謂是數據庫物理設計中的一個非常重要的步驟。從一般意義上說,設計和實現視圖應該遵循下面的一些建議和原則。

          以下內容摘在文檔,我對某些重點進行了補充說明(紅色部分)

        1. 只能在當前數據庫中創建視圖。 但是,如果使用分布式查詢定義視圖,則新視圖所引用的表和視圖可以存在于其他數據庫甚至其他服務器中。
          • 分布式視圖是可行的,但隨著SQL Server本身能力的提高,例如SQL Server 2005開始支持表分區等技術之后,分布式視圖應該盡量少用。
          • 所謂分布式視圖的一個最大的問題就是將表物理上分開在多個數據庫甚至服務器中,這增加了維護和查詢的難度
        2. 視圖名稱必須遵循標識符的規則,且對每個架構都必須唯一。 此外,該名稱不得與該架構包含的任何表的名稱相同。
          • 一個可以借鑒的做法是:在視圖名稱之前添加一個前綴 vw
        3. 您可以對其他視圖創建視圖。Microsoft SQL Server 允許嵌套視圖。但嵌套不得超過 32 層。 根據視圖的復雜性及可用內存,視圖嵌套的實際限制可能低于該值。
          • 一般不建議超過2層
        4. 不能將規則或 DEFAULT 定義與視圖相關聯。
        5. 不能將 AFTER 觸發器與視圖相關聯,只有 INSTEAD OF 觸發器可以與之相關聯。
          • 除非萬不得已,一般不建議使用觸發器
        6. 定義視圖的查詢不能包含 COMPUTE 子句、COMPUTE BY 子句或 INTO 關鍵字。
          • 很多朋友不知道:COMPUTER和COMPUTER BY語句僅僅用于一些特殊場合,用于生成總計行。大致有如下的效果

          image

          該特性不能用于視圖,但可以直接用于查詢

           

        7. 定義視圖的查詢不能包含 ORDER BY 子句,除非在 SELECT 語句的選擇列表中還有一個 TOP 子句。
          • 這個很有意思,如果要訪問所有的呢,還必須是寫TOP 100 PERCENT
        8. 定義視圖的查詢不能包含指定查詢提示的 OPTION 子句。
        9. 定義視圖的查詢不能包含 TABLESAMPLE 子句。
          • 關于TABLESAMPLE語句,大家可能也比較陌生,這是一個用于對數據進行抽樣的。它和TOP語句不同,TOP語句是有固定大小的,而TABLESAMPLE返回的數據,可能多,可能少,甚至可能沒有
          • 我之前有一篇文章講述這個語法 http://www.cnblogs.com/chenxizhang/archive/2009/05/19/1460040.html
        10. 不能為視圖定義全文索引定義。
        11. 不能創建臨時視圖,也不能對臨時表創建視圖。
          • 在SQL Server 2005中,可以通過CTE(Common Table Expression)來實現該功能
          • 之前的版本,大致的做法是使用臨時表,表變量,函數等等
        12. 不能刪除參與到使用 SCHEMABINDING 子句創建的視圖中的視圖、表或函數,除非該視圖已被刪除或更改而不再具有架構綁定。 另外,如果對參與具有架構綁定的視圖的表執行 ALTER TABLE 語句,而這些語句又會影響該視圖的定義,則這些語句將會失敗。
          • 如果未使用 SCHEMABINDING 子句創建視圖,則對視圖下影響視圖定義的對象進行更改時,應運行 sp_refreshview。 否則,當查詢視圖時,可能會生成意外結果
          • 強烈建議對某些非常重要的視圖,添加SCHEMABINDING 子句。

          image

        13. 盡管查詢引用一個已配置全文索引的表時,視圖定義可以包含全文查詢,仍然不能對視圖執行全文查詢。
        14. 下列情況下必須指定視圖中每列的名稱:
          • 視圖中的任何列都是從算術表達式、內置函數或常量派生而來。
          • 視圖中有兩列或多列原應具有相同名稱(通常由于視圖定義包含聯接,因此來自兩個或多個不同表的列具有相同的名稱)。
          • 希望為視圖中的列指定一個與其源列不同的名稱。 (也可以在視圖中重命名列。) 無論重命名與否,視圖列都會繼承其源列的數據類型。

            若要創建視圖,您必須獲取由數據庫所有者授予的此操作執行權限,如果使用 SCHEMABINDING 子句創建視圖,則必須對視圖定義中引用的任何表或視圖具有相應的權限。

            默認情況下,由于行通過視圖進行添加或更新,當其不再符合定義視圖的查詢的條件時,它們即從視圖范圍中消失。 例如,創建一個定義視圖的查詢,該視圖從表中檢索員工的薪水低于 $30,000 的所有行。如果員工的薪水漲到 $32,000,因其薪水不符合視圖所設條件,查詢時視圖不再顯示該特定員工。 但是,WITH CHECK OPTION 子句強制所有數據修改語句均根據視圖執行,以符合定義視圖的 SELECT 語句中所設條件。 如果使用該子句,則對行的修改不能導致行從視圖中消失。 任何可能導致行消失的修改都會被取消,并顯示錯誤。

           

        15. 作者: 王德田 發表于 2011-03-07 16:37 原文鏈接

          評論: 0 查看評論 發表評論


          最新新聞:
          · 疑似中國黑客入侵澳大利亞議會計算機系統(2011-03-29 12:05)
          · 蘋果開發者大會1599美元天價門票搶購一空(2011-03-29 12:04)
          · 樂淘網CEO畢勝:今年近七成廣告預算投向搜索(2011-03-29 11:58)
          · Facebook聘請時代華納高管提升廣告服務(2011-03-29 11:57)
          · “萬能膠之父”逝世 曾被奧巴馬頒科技獎(2011-03-29 11:56)

          編輯推薦:Java之父詹姆斯·高斯林加盟Google

          網站導航:博客園首頁  我的園子  新聞  閃存  小組  博問  知識庫

          posted on 2011-03-07 16:37 sanmao 閱讀(2254) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           

          常用鏈接

          留言簿(5)

          隨筆分類

          隨筆檔案

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 林周县| 清流县| 大丰市| 怀集县| 赤壁市| 凤冈县| 龙口市| 通海县| 石家庄市| 遂宁市| 仁寿县| 静宁县| 株洲县| 渭南市| 民乐县| 汾阳市| 晋江市| 永丰县| 清流县| 绥滨县| 修武县| 政和县| 庐江县| 化德县| 肃南| 麻江县| 邓州市| 金湖县| 紫金县| 呼和浩特市| 黄梅县| 离岛区| 衡阳市| 普兰店市| 当涂县| 崇左市| 台东市| 满洲里市| 板桥市| 黔东| 舒兰市|