希格工作室

顯示具有 SQL SERVER 2008 標籤的文章。 顯示所有文章
顯示具有 SQL SERVER 2008 標籤的文章。 顯示所有文章

2012年4月11日 星期三

Linq時代的分頁使用關係 (C#)

       在早期,我們在完成一個網頁表單會使用DataGird這個物件來實現,而DataGird這個物件本身也就支援著分頁的功能了。不過,我們應該都知道DataGird實現分頁的方式就是將資料透過ViewState保留後,再從中篩選要顯示的資料給User來檢閱,也因此在大量資料下,除了會造成資料庫負擔外,更會因為ViewState過大的關係,使得網頁停止回應,導致整個掛掉。

      所以我們會利用資料篩選的方式,只透過回應少量且必要的資料來減低資料庫負擔並提高效能,而通常會透過一連串的SQL語法去達成,至今亦是如此。

      在SQL2000之前,我們可能會透過cursor的方式叫用sp_cursoropen及sp_cursorfetch來達成,而在SQL2005之後多了ROW_NUMBER()這個函數,讓我們方便替每筆資料列做編號,之後只要透過where語法去取用需要的編號範圍,即可達成分頁。

      例如我們有一語法取得資料表的幣別種類並替它編號
SELECT ROW_NUMBER() OVER (ORDER BY [Currency]) AS [ROW_NUMBER], [Currency], [CurrencyName] FROM [dbo].[Currency]
      結果大概長這樣


    如果我們打算將它分成兩頁並取第一頁前5筆時

select * from
( SELECT top 5 ROW_NUMBER() OVER (ORDER BY [Currency]) AS [ROW_NUMBER], [Currency], [ CurrencyName ] FROM [dbo].[Currency] )  AS   a
where [ROW_NUMBER] > 0
    結果自然長這樣
     而至於我為什麼要講那麼多SQL呢,是因為使用Linq有著更令人一目瞭然的寫法,如:
var data = (from i in db.Currency select i).Skip(0).Take(5).ToList();

    好了....解決了(註:Skip是略過幾筆,Take是取得幾筆),當你使用SQL Profiler時會發現,Linq會自動幫你轉成類似語法,來達到資料分頁,不過這其實不是啥了不起的事...,因為這已經好幾年前的舊聞了,我這裡會講這個,主要只是要表達使用Linq後,在背後的執行狀況。

    在VS2005還是VS2008時,DataGird被捨棄了,取而代之的是GridView,而GridView可以搭配著各種DataSource容器,只要指定好DataSourceID,並在畫面上拖拖拉拉後,再將AllowPaging打開,分頁輕輕鬆鬆便做好了!而且更重要的是,透過Profiler去追蹤,你會發現DataSource傳送的SQL語法就是剛才所使用的ROW_NUMBER,簡直棒透了不是?

    這當然也不是新聞。

   問題在於一點,GridView必需搭配DataSource容器才得以自動完成[資料分頁],但是在分散式專案的架構下,想單單靠著指定DataSourceID來完成表單似乎有點難度,故在這情況下只好又做回原來的GridView.DataSource&DataBind()來製作表單,但不知道是不是由於DataSourceID太好用的關係吧?又或著有些人認為GridView搭配Linq會聰明的自己作分頁..?之類的,你可能會看到如下程式碼:

public void Page_Load(object sender, EventArgs e)
  {
     GridView1.DataSource = getData();
     GridView1.DataBind();
  }
  public IEnumerable<TBX> getData()
  {
     var data = from i in DB.Table select i;
     return data;
  }
        然後在介面上設定AllowPaging=true


        這是一個不知道該說什麼好的一件事,似乎會以為這樣就會替你完成[資料分頁]?那當然是不可能的...,GirdView並沒有你想像的聰明,它只會將資料全數取回後送給GridView1,存放在GridView1的ViewState裡,緊接著在裡頭進行著分頁動作,就又回到N年前的DataGird問題裡(即使你用別人開發的控件亦同)。

        要記得一個大原則,只要透過DataSource&DataBind()就代表你放棄好用的工具,所以所有功能你都得自己寫!!

       是故,請好好利用Skip和Take進行分頁吧。

        另外在Google時發現一篇文章,文章裡問道,為何我用Skip&Take後,出來的語法和想像的不大一樣?

       其實這問題很簡單,因為你下的就是告訴它我要先Skip(跳過)再Take(取用),所以出來的資料截取方式當然是要先等資料讀過後,才知道要where和Top哪邊,如果要像此文章裡的想法下,只Top一定數再where範圍的話...。

       只要反過來先Take再Skip就好囉!分頁程式如下:

public List<TheTable> ddd(int PageSize, int PageCount)
{
     Conn db = new Conn();
     var data = from i in conn.TheTable  select i;
     var Take = (PageSize * PageCount);
     var Skip = ( (PageCount - 1) * PageSize);
     return data.Take(Take).Skip(Skip).ToList();
}
之後只要去取用就好囉

public void Button1_Click(object sender, EventArgs e)
{
 GridView1.DataSource = getAList(GridView1.PageSize, int.Parse(PageCount.Text));
 GridView1.DataBind();
}


不過這個方法沒有詳細Debug,防呆做好的話理論上應該不會有問題....吧?
(甚至你想先Take再Take說不定也行?)

2012/4/19:
關於Take Skip,查執行計劃,效率上似乎一樣。

2012年4月7日 星期六

網站效能的追源溯本(Linq)

Linq真好用(廢話)

Linq搭配LinqToxxx or Entity的結合根本好用到不行

用不著寫一堆連線方案,也不用擔心SQL Injection,也不用因為寫SQL語句時,造成的一堆"字"亂七八糟的難維護,甚至連SQL都不用學了。

真是好用的東西

事不宜遲,就來寫個輸入一筆訂單,若存在符合訂單則修改數量,不存在則新增一筆,超過一筆以上則保留數量最多的並刪除其它多餘資料的標準Linq語句吧。



            var dbLink = new db();
            var catchOrder = from o in dbLink.OrderList
                             where o.OrderID == "J001"
                             select o;
            if (catchOrder.Count() == 0)
            {
                var newOrder = new OrderList();
                newOrder.OrderID = "J001";
                newOrder.OrderName = "新訂單01";
                newOrder.Quantity = 10;
                dbLink.OrderList.InsertOnSubmit(newOrder);
            }
            if (catchOrder.Count() == 1)
            {
                foreach (var upd in catchOrder)
                {
                    upd.Quantity = 11;
                }
            }
            if (catchOrder.Count() >= 2)
            {
                var MaxQuantity = catchOrder.Max(m => m.Quantity);
                var delSomeThing = from d in catchOrder
                                   where d < MaxQuantity
                                   select d;
                foreach (var delIt in catchOrder)
                {
                    dbLink.OrderList.DeleteOnSubmit(delIt);
                }
            }
            dbLink.SubmitChanges();


我們姑且不論是什麼情況會有這麼詭異的需求...那不是重點。

基本上類似這樣子的寫法應該很常見,但這語法裡有什麼問題存在?相信應該很容易知道。

Linq因為它是一個你要它做時,它才會動的東西,所以即使你在最開頭寫好了select from....,它並不會做任何事,只是放在那裡,等你找它做事,當只有在count、max....xxx等語句出現或foreach它時,才會與資料做連繫,所以在這一個簡單判斷的語法裡,總共至少需要叫資料庫做至少5~7次以上的動作,會不會太浪費資源了一點?

catchOrder.Count()catchOrder.Max()catchOrder.XXX()太好用了,又容易看懂,如果你覺得這沒什麼,結果瘋狂使用它,去試著想用的人多一點時,會發生什麼事吧?一個人是7次,1000個人就是7千次,千萬不要因為好用而濫用。

     


            var dbLink = new db();
            var catchOrder = from o in dbLink.OrderList
                             where o.OrderID == "J001"
                             select o;
            var bakOrder = catchOrder.ToList();
            int useCount = bakOrder.Count();
            if (useCount == 0)
            {
                var newOrder = new OrderList();
                newOrder.OrderID = "J001";
                newOrder.OrderName = "???01";
                newOrder.Quantity = 10;
                dbLink.OrderList.InsertOnSubmit(newOrder);
            }
            if (useCount == 1)
            {
                foreach (var upd in catchOrder)
                {
                    upd.Quantity = 11;
                }
            }
            if (useCount >= 2)
            {
                var MaxQuantity = bakOrder.Max(m => m.Quantity);
                var delSomeThing = from d in catchOrder
                                   where d < MaxQuantity
                                   select d;
                foreach (var delIt in catchOrder)
                {
                    dbLink.OrderList.DeleteOnSubmit(delIt);
                }
            }
            dbLink.SubmitChanges();

這邊做簡單的調整(但不代表最好,因為更好的有很多,這邊只是減少對資料庫溝通而已)
利用ToList先行將資料取得到記憶體中,接著計取Count保留,若有需要時亦用來計取Max,如此一來對資料庫要求的次數則從最少5~7次降為最少2次,如此便減少與資料庫之間來往,理論上而言效能應是比較好的。(實際情況請依狀況而定)

在撰寫時,最好搭配SQL Profiler瞭解你的Linq到底幹了什麼事。

2012年4月5日 星期四

網站效能的追源溯本(資料庫)

當你的網站慢了的時後,你第一時間會想什麼?

1.伺服器出問題?(IIS掛了?mem爆了?網域解析又出錯了? )
2.這支程式誰寫的?(又是xxx,快把他抓來罵)
3.大概是人太多了
4.大概是資料太多了
5.....
諸如此類的想法

如果這時候好死不死給上頭的知道了,一聲怒下,你就得開始狂查原因,翻遍所有程式,看遍所有server的設定,或狂打電話給中華電信,結果仍百思不得其解,最後上網GOOGLE,找到了許許多多網站調校的方法和建議,這當中往往都是叫你改程式,不然就再安裝新軟體,結果成本就又冒出一堆來了,只好冒死晉見老闆說要改程式(買軟體),然後被老闆白眼一頓後才核準,最後當你如願以償之後,卻發現上頭的還是跟你說一聲"喂!XXX怎麼還是那麼慢?",你可能會哭死

在你花時間改程式,加設備,搬資料,調整javascript,JPG,...,各種延遲載入,修改各介面的Response方式....諸如此類耗時費神的動作前,花個5~20分鐘重新看一下最根本的東西吧

資料庫

基本上我要講的對很多人而言是廢話,但卻又是最容易讓人遺忘的基本,資料庫是讓人塞資料用的,要塞資料一定會佔空間啊,所以你當時在建資料庫時給它多少空間?快滿時的成長空間又是多少?想想你從系統剛上線時到現在的大小差了多少?由此你就會知道你的資料存在硬碟裡到底有多散了...,越散當然越慢啊。

再來你的log檔(ldf)和資料庫檔(mdf)是不是放在同一個實體硬碟?如果是,把管資料庫的抓來痛揍一頓吧。

有無使用檔案群組(file group)功能?如果沒有,趕快用吧;如果有...麻煩看一下用到哪去了?你確定真的有正確使用?

多久沒重建你的索引了?

多久沒"完整"備份你的資料庫了?

最基本的基本...你用什麼東西當你的索引?都是varchar?甚至前面多個n? or table時不時有一堆null?別以為有些人建議varchar和char執行速度沒啥差別,null和非null也可省好多空間...當你增刪修改個N次後,你就又會知道你的資料到底又有多散了...

SQL的服務沒用到的裝了一堆?如MSSQL的Reporting Service之類的有真正用到再裝吧。

還有偶偶錄一下Profiler餵給Database Engine Tuning Advisor看看有啥要改善的吧

等到這些最基本的確定沒問題了,再去思考那些複雜的問題吧,因為資料破碎這種事,就跟燒開水一樣,你不燒它,你就沒水喝,你不燒它,你就沒電用(因為從那個放風箏被電到的人發現電以來,我們發電的方式依舊是燒開水),你不去注意破碎,你永遠被罵。

噓:回資料太多的都是廢話...除非你的DB每個都不知道多少個G...而且又同在一個instance

分享複雜的問題的參考資料:
DB:
網站效能分析操作心法-第8回-從資料庫來調校
網站效能分析操作心法-第9回-從資料庫來調校
OTHER:
快速揪出網站效能不佳的罪魁禍首

2011年11月25日 星期五

令人懷念的MUD -- [AJAX GAME]自製簡易網頁的對戰小遊戲

https://sites.google.com/site/siggblog/sample/ajax-you-xi1

(進入遊戲後請先點素質)

這是我為了瞭解AJAX運作寫的,純網頁無FLASH,應該算即時的猜拳制的對戰,線上隨機找其他活人對戰(不過因為沒人玩,所以我加上電腦)。


會想要寫這個,無非是想用AJAX作什麼,其實網頁遊戲現在多的跟什麼一樣,只是都是用FLASH來做...,目前先試試用AJAX純網頁能做到啥程度,接下來和HTML5結合,看能玩出啥花樣?
但是有很大的問題,就是敝人沒什麼設計天份,也畫不出好看的圖~所以整體介面醜死了...



如果玩過後有什麼意見給我參考或反應(不能玩、沒反應、不平衡、畫面太亂、不會動、網路慢之類的),我會感激不盡的,但是如果要我畫上萌圖當角色之類的,我可能沒辦法~

因為只是一個畫面而已,所以沒有啥故事主題之類的,因此我也沒有替這個小遊戲命名。

在IE、firefox、Chrome測試都沒問題,其它版本未知,但是請勿用IE6...

基本上我想要知道我這種設計是否很吃頻寬,所以如果我網路被撐爆,我可能會關掉這個遊戲...

最後,如果你有意願賞光稍微玩一下的,在這裡說聲謝謝~



以下是說明和注意事項,懶得看的可以跳過

註冊
1.先點擊[註冊]建立帳號,註冊的帳號和暱稱無法與他人重復。
2.帳號最多12位,暱稱最多20個字,Email請盡量輸入能用的。
3.註冊成功後會發送註冊成功的Email(沒收到信也沒關係),密碼無法變更和查詢。

遊戲方式
1.遊戲是以線上找玩家直接對戰的方式
2.進入畫面後,左側可查看資訊,[遊戲資訊]可查看線上人數(約每1分鐘更新一次)。
3.點選[尋找對手]可以開始搜尋並等待其它按下[尋找對手]的玩家(若要停止則再按一次)。
4.當互相找到玩家後,[準備完成]會亮起,決定好你的[對戰指令],及看HP夠不夠後,就可以按下。
5.進攻方式目前分4種:重擊(AK)、刺擊(SK)、防禦(DF)、反擊(BK) (如果你有更好的名詞歡迎告知...)
在戰鬥進行中可以任意變更,來改變戰術,
基本上攻防互剋情況為:
     1.AK>SK>BK>AK
     2.AK和SK打DF時,SK較有利
     3.DF狀態下受到攻擊後,會進行蓄力狀態,當改進行攻擊時傷害會些許提高,最多可蓄10回合(會逐漸消退)。
     4.雙方都DF或BK時,無傷害,DF也不會蓄積。

6.戰鬥大約每兩秒為一回合,進行到一方或雙方HP歸零為止,就算中途關閉瀏覽器也是會打到底。
7.每次參加戰鬥,最少都會有1的EXP,EXP計算以對手等級計算,當比對手等級高時,每多1級少一些的EXP,勝方可獲得全部EXP,敗方則只有1/3,但無論如何,一定有1EXP
8.戰鬥結束後,或未開打前,都可以恢復你的HP值,恢復HP需已EXP作為代價,每100HP要1EXP,但10級以內不用,11~30需求減半,若EXP為0則都不用,不會掉級請放心。

人物狀態
1.人物狀態在畫面左方[人物資訊]裡可查看,當升級時HP,STR,DEF,AGI,DEX會亮起讓玩家提升素質,若點下去就不可返回,請注意。
2.人物狀態分為:
     LV:人物等級,最高99
     HP:血量,每次升級+10滴HP,升級也可用點數提升,每1點+10HP
     STR:力量,直接影響傷害,另外每1點+5HP
     DEF:防禦,降低對手的傷害
     AGI:迴避率(最多80%),及有機率產生額外傷害(最多33%,若在SK時發生,則會再稍微高一些)
     DEX:命中率,提高命中能力,以及些微提升最小/最大傷害值,
     EXP:經驗值
     升級點數:1級時有20點供選擇,每次升級有5點

其它事項
1.發呆大約5分鐘沒作任何動作的話,會被強制登出,此時做任何動作會回到登入畫面。
2.承上,由於沒有寫登出~若已登入卻把整個瀏覽器關掉再開的話,可能要等5分鐘才能再登入
3."理論上"一種瀏覽器只能登入一個帳號,而且已登入的角色不能重復在其它地方再登入
4.升級時HP會補滿,但增加HP時不會恢復HP
5.現階段理論上24HR都能進入遊戲,如果無法登入...大概是被操爆了。
6.增加線上聊天,不過仍有點問題


我自己的暱稱: 希格

2011年9月19日 星期一

SQL SERVER手記 --- SPARSE



USE [tempdb] 
create table tst1 (ss varchar(20) SPARSE,ss1 varchar(20) SPARSE)
CREATE TABLE tst2 (ss varchar(20)       ,ss1 varchar(20) )
go

--select * from tst1 SPARSE 
--go

declare @idx int = 0
while @idx < 100000
begin
insert tst1 values('',null) 
insert tst2 values('',null)
set @idx +=1
end
go

sp_spaceused tst1
go

sp_spaceused tst2
go

drop table tst1,tst2
go



測試輸入10萬筆資料,每筆資料有兩個欄位,長度都為20

有/無(SPARSE)保留區資料區索引區未使用
CHAR都有值6408640080
51285096824
VARCHAR都有值23122288816
1160114488
CHAR都NULL1160114488
51285096824
VARCHAR都NULL1160114488
1160114488
CHAR一邊NULL39763944824
一邊有值51285096824
VARCHAR一邊1928187288
NULL一邊有值1160114488

*有值的部份是填入空白值,而非填滿,故在CHAR時是補滿,而VARCHAR時理應空白。
*欄位裡上面為有使用SPARSE的TABLE,下面為沒使用的TABLE。

在這裡看到,當都是使用CHAR時,若資料欄位都有儲存資料且非有NULL時,所使用的空間會變多,在VARCHAR時亦同,而當CHAR都是NULL時,可以發現佔用的空間明顯變少了,但在VARCHAR時則相等,所以可以發現在VARCHAR為NULL時,有無使用SPARSE似乎都沒有意義,在一邊有值一邊為NULL的情況下,可以發現CHAR的確有省到空間,但是VARCHAR依舊是佔用較多空間。

故使用SPARSE時,由於SPARSE的特性是,若欄位為NULL時將不佔任何空間(不替它保留),但在有資料時則額外佔用空間(聽說是4byte),所以在使用變動欄位(如VARCHAR),除了不會省到任何空間以外,反而可能會膨賬,但在固定欄位時則相反。

2011年9月10日 星期六

SQL2008手記 --- 專有名詞整理

以下是所有曾出現在SQL相關的專有名詞的完整名稱



l   AWE:Address Windowing Extensions
l   BIDS:Business Intelligence Development Studio
l   BOL:Books Online
l   CLR:Common Language Runtime
l   ISV:Independent Software Vendor
l   IFI:Instant File Initialization
l   LUR:Least Recently Used
l   MAXDOP:Maximum Degree of Parallelism
l   MMC:Microsoft Management Console
l   MTF:Microsoft Tape Format
l   NUMA:Non-Uniform Memory Access
l   OLAP:Online Transaction Processing
l   OLTP:Online Analytical Processing 
l   ODBC:Open Database Connectivity
l   RTO:Recovery Time Objective 
l   RPO:Recovery Point Objective
l   SAN:Storage Area Network
l   SMO:SQL Server Management Objects
l   SSD:Solid State Drive
l   SNAC:SQL Native Access Client
l   SSMS:SQL Server Management Studio
l   SSCM:SQL Server Configuration Manager
l   SCC:System Configuration Checker
l   SLAs:Service level agreements
l   TCO:Total cost of ownership
l   TDS:Tabular Data Stream
l   TDE:Transparent Database Encryption
l   VIA:Virtual Interface Adapter
l   VAS:Virtual Address Space
l   VLFs:Virtual Log Files
l   VSS:Shadow Copy Service
l   VDI:Virtual Device Interface
l   WMI:Windows Management Instrumentation
l   XML/A:XML for Analysis

SQL2008手記 --- 規劃你的SQL SERVER 2008

規劃你的SQL SERVER 2008

1.選擇你的作業環境及硬體需求和功能,去配合所需版本。
3.盡量安裝到64位元的作業系統上,以獲得最大支援能力。
4.依你的SQL Server版本,盡量加大你的記憶體空間及速度(SQL是記憶體怪獸,根據預設值,SQL是會將記憶體全部配置給自己使用,有其它程式需要才吐出來給它,所以有多少吃多少,Web以上版本就支援到64GB了而Datacenter版本則是根本無限制。)。
5.正式環境上不要和domain System或其應用程式混裝在同一台機器上(其一原因如上)。
6.SQL Instance最多可以到50組,意思是同一台機器可灌50次相同或不同的SQL Sever版本,但是若沒必要就不需要這麼做。
7.最佳化的硬體分配,將tempdb、Data Files、Transaction Log拆放在與安裝位置不同的實體硬碟裡(額外還有SnapShot[快照]及備份資料)。
8.若有需要,透過File Group再將 Data Files分別切割並存放在不同實體硬體裡(FG有兩種方式,一種是資料表資料分割,一種是資料表分別存放,依需要選擇)
9.若有需要,可將單純只存放SQL Server Data Files的硬碟在規劃時就格式化成64K的檔案配置(因SQL的page是以8K為一單位,Table是以8個連續的page為最小基礎單位的)
10.透過磁碟陣列加快或安全化你的SQL Server資料保存及速度(官方建議為RAID 1,5,10,應該不會有人用RAID 0去存資料吧,快歸快,死了就全死了)。
11.個人覺得別把T-LOG放在SSD,T-LOG這東西是只要有任何活動,它都會直接寫入磁碟,所以I/O次數非常的大,雖然說SSD的寫入限制其實很大,但如果你不希望哪天突然SERVER突然當掉卻找不到原因的話(官方建議置於RAID0+1的環境下)。
12.使用整合式Windows驗證,停用SA(2008預設停用),啟用強式密碼驗證。
13.安裝時決定好你的系統定序(中文版預設Chinese_Taiwan_Stroke_CI_AS,Instance安裝後無法變更),它將決定非數值之排序與大小寫區分及其它。
14.事先決定好基本空間並給予一個合理的預設大小和成長緩衝。
15.設定適當且正確的資料庫及LOG的預期成長,不要使用預設值MB。
16.使用SQL Profiler記錄你的使用者經驗,來改善資料庫規格,以提升效能。
17.完善的備份策略(悲觀的備份策略)
開始前的準備
l預設復原模式(recover mode)最好選擇完整(Full)
l定期進行業完整備份及差異備份
l瞭解Log運作及備份時機
l決定你的備份時間和備份用的裝置(硬碟、磁帶等)
l你能夠承受多少資料的損失?
l何時測試你的備份?
l不要任意變更復原模式,否則每次變更後,必須重做一次完整備份。
l鏡像備份到多個裝置上( MIRROR TO ) , 但此功能在2008上沒有介面,需透過指令設定,最多4個裝置(此為同步備份)。
l備份策略最好包含System Database(tempdb可不備)
操作
1.建立備份裝置(Backup Device)
2.建立要備份的資料庫去對應備份裝置
3.第一次備份請用完整備份(Full Backup),並固定時間進行一次完整備份(如每月一次或每星期一次),或者只做第一次。
4.短區間內可進行自動排程的差異備份(Differential Backup),(如每日一次或兩次)。
5.如遇移轉或問題時,可建立交易記錄的備份(T-Log)。
6.T-Log也可隨時進行備份,在每次Full/Diff備份之間,但無論如何,還原時T-Log只有Full/Diff完後的最後幾次是有用的。
7.建立檔案群組(File Group - FG)並替FG建立各別備份,當FG損壞或誤刪改時,可只針對該FG進行還原而不影響其它DB與資料。
8.備份與還原都要謹記依序備份並依序還原,Full->Diff1->Diff2->Log。
9.有Copy Only的備份模式,僅以指令操作,該使用好處為不會打亂備份的順序。
10.完整備份請在離鋒時期或第一次建置時或壓縮後再操作,因耗用資源與時間較大,會影響正常使用者。
11.使用VERIFYONLY進行備份檔案(或裝置)的完整性驗證。
還原
1.瞭解需要還原的原因,若是災難復原,需先確定災難發生時間,以決定從什麼時間點的備份開始還原以及能救多少的資料。
2.無論如何,災難發生時記得先手動備份T-LOG,並視情況加上參數WITH No_Truncate,不把Log定義為可清除,以便重做
3.復原模式若是簡單(Simple Mode),則不需要救T-Log了,因為無法得知Log的時間點。
4.若損壞的包含System Database,則需先針對損壞的部份還原。
5.還原時記的要依序還原,而且只有最後一個階段才可下WITH Recovery,其它階段需為WITH NoRecovery。
6.STOPMARK -- 在有備份T-Log情況下,若執行過的語法有使用交易(Tran)包起來,並且有給予其別名,亦可當做一還原點,可用來將異常點排除的T-Log還原,但是在還原點以後的資料都會漏失(包含造成異常或正常的語法資料)。
7.還原master  database方式,啟動至Single-User Mode再還原,完畢後切還原樣,重啟服務。
8.model database有問題時,可在sql server啟動加註 –T3608 跳過model database,再還原它。`
9.FileGroup可以分開備份也可以分別還原,T-Log的還原不區分FG,在還原時會自行比對FG資料。
註記:
l   備份雖會清除LOG,但並不會釋放實體硬碟空間。
l   復原模式:簡單(Simple)無法建立Log的還原點;完整(FULL)可建立Log還原點;大量記錄(Bulk-logged)在特定處理大量資料時不記錄Log(DBCC、bcp…)
l   SQL 2008支援Online Backup/Restore
l   有時master database若壞掉,會連登入都有問題,此時只能重建再還原它。
l   2008以後,還原前會強制要求先做一次T-Log備份,除非你下了With Replace
l   還原備份時的內部流程,先刪除DB,複製裝置(Data Copy)裡的資料成為新的DB,執行Recovery的重做(Redo)和不做(Undo)。




以上是整理書上和實務上的經驗。


參考資料:MCTS SQL SERVER 2008 R2


(未完--持續修改)
Copyright by Sigglas 2011