Sql Server來龍去脈系列之四 數據庫和文件


    在討論數據庫之前我們先要明白一個問題:什么是數據庫?
    數據庫是若干對象的集合,這些對象用來控制和維護數據。一個經典的數據庫實例僅僅包含少量的數據庫,但用戶一般也不會在一個實例上創建太多的數據庫。一個數據庫實例最多能創建32767個數據庫,但是按照實際情況,一般設計是不會達到這個限制值。
    為了更明顯地說明數據庫,數據庫包含了以下屬性和功能:
    *. 它是很多對象的集合,比如表、視圖、存儲過程、約束。對象集合的最大值是2(31) - 1(超過2百億)。一般對象的數量在幾百至一萬。
    *. 它維持擁有的用戶account、roles、schemas以及security;
    *. 它擁有系統表去控制數據庫目錄;
    *. 它擁有自己的事務日志並且管理自己的事務;
    *. 它有自己的范圍大小, 從2MB到524272T;
    *. 它能自動或者手動的增長或者收縮;
    *. 它能和其他同一數據庫實例的其他數據庫進行內聯查詢操作;
系統數據庫
    當安裝一個數據庫,Sql Server自動會創建4個數據庫:master、model、tempdb、msdb。但很多人都不知道還有第五個隱藏的數據庫,通過常規的sql指令是看不到這個數據庫的。它更像一個資源數據庫,真實名稱叫做mssqlsystemresource。接下來分別介紹這幾個數據庫:
    1)master。master由系統表組成,用來跟蹤整個服務安裝器和被用戶創建的其他數據庫。雖然每個數據庫都包含有系統目錄,用來維持數據庫包含的對象信息,但是master包含的系統目錄還維持了磁盤空間、文件分配、系統配置、登陸賬號、當前實體包含的數據庫等等。
    你應該習慣經常備份master數據庫。因為很多操作,例如創建數據庫、改變配置、修改登錄賬號等都會寫入到master中,所以當你執行這些操作后要經常備份。
    2)model。model是一個簡單的模板數據庫。當用戶創建一個數據庫,sql server拷貝一份model到新數據庫的基礎表中。例如,你想新建一個數據庫默認包含某些對象或者權限,你可以把這些對象或者權限放到model中,新建的表會繼承model。
    3)tempdb。tempdb被作為一個工作區。在sql server 數據庫中它也是唯一的,如果重啟了數據庫它會重新創建。它被用戶用來創建臨時表,在執行查詢和排序時作為工作表保存中間結果,維持行版本信息,實現靜態游標和keyset游標的主鍵。因為tempdb數據庫每次啟動會重新創建,所以你在它里邊創建的任何對象以及權限都會丟失。如果你像把某些對象保存在tempdb中,你可以編寫存儲過程創建對象,每次啟動數據庫時執行該存儲過程。
    4)mssqlsystemresource(資源數據庫)。mssqlsystemresource是一個隱藏的數據庫,存儲可執行系統對象,像存儲過程、函數。為什么該數據庫是不可見的?微軟創建它是用來快速並且安全的做數據庫更新。因為沒有人能獲取它,沒有人能改變它。通過任何預覽數據庫的方法去查看該數據都是無效的,例如從sys.databases 或者 executing
sp_helpdb。也不會顯示在SQL Server M Studio的樹結構上。但是,它始終還是需要存儲在磁盤上。
    你可以在目錄C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\
MSSQL\Binn上查看到該數據庫文件,包含兩個文件: mssqlsystemresource.mdf(60MB)、mssqlsystemresource.ldf(0.5MB)。你可以通過兩種方式查看它的內容。最簡單的是停止數據庫,拷貝兩個文件,重啟數據庫,通過附加文件的方式創建一個新的數據庫。或者你可以用CREATE DATABASE FOR ATTACH語法創建一個拷貝數據庫。
    CREATE DATABASE resource_COPY
    ON (NAME = data, FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\binn
    \mssqlsystemresource_COPY.mdf'),
    (NAME = log, FILENAME =
    'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\binn\mssqlsystemresource_COPY.ldf')
    FOR ATTACH;
    5)msdb。msdb被用作sql server代理服務,形成計划活動(例如備份、復制任務)、服務中間者(為sql server
提供可靠的信息)。為了備份 ,msdb支持jobs、alerts、log shipping、poliecies、數據庫郵件以及損壞頁的恢復等。但我們一般是不會操作該數據庫的。
數據庫文件
    一個數據庫文件不外乎就是一個操作系統文件。針對於數據庫文件,sql server有備份策略,邏輯策略是映射成操作系統文件、物理策略例如磁盤驅動器。一個數據庫至少分割成兩個文件也可以多個。一個是數據文件(例如索引和分配的頁),一個是事務日志文件。
    數據庫文件包含三種類型:
    1)關鍵數據文件。必須有有一個關鍵數據文件用來存儲數據,擴展名為.mdf。
    2)第二數據文件。可以有零個或者多個,擴展名為.ndf。
    3)日志文件。至少一個日志文件,包含必要的信息用來恢復數據庫中的所有事物。擴展名為.ldf。
    
    每個數據庫文件包含五個屬性 :邏輯文件名、物理文件名、初始大小、最大尺寸、增長值。我們可以通過元數據視圖sys.database_files查看這些熟悉,每個文件包含一行數據。例如我創建一個數據庫Sample。然后執行在Sample數據庫中執行以下sql語句:
    select * from sys.database_files;
    查看到的結果:
 
   關鍵列說明:
type 
File type:
0 = Rows (includes full-text catalogs upgraded to or created in
SQL Server 2008)
1 = Log
2 = FILESTREAM
3 = Reserved for future use
4 = Full-text (includes full-text catalogs from versions earlier than
SQL Server 2008)
name
The logical name of the fi le
physical_name 
Operating-system fi le name
size
Current size of the fi le, in 8-KB pages.
0 = Not applicable
For a database snapshot, size refl ects the maximum space that the snapshot
can ever use for the fi le.
max_size
Maximum fi le size, in 8-KB pages:
0 = No growth is allowed.
–1 = File will grow until the disk is full.
268435456 = Log fi le will grow to a maximum size of 2 terabytes.
growth
0 = File is a fi xed size and will not grow.
>0 = File will grow automatically.
If is_percent_growth = 0, growth increment is in units of 8-KB pages,
rounded to the nearest 64 KB.
If is_percent_growth = 1, growth increment is expressed as a whole number
percentage.
 
  創建數據庫
    創建數據庫最簡單的方法是使用Management Stdudio對象瀏覽器創建。它等同於CREATE DATABASE指令。並不是所有的用戶都可以創建數據庫,創建數據庫必須要有相應的權限,具體哪些權限可以創建數據庫?包括任何擁有sysadmin角色、任何有CONTROL or ALTER權限、任何有CREATE DATABASE權限的sysadmin或者
dbcreator角色。
    當創建了新數據庫,SQL Server拷貝model數據庫。如果你有一個定制的對象想包含在你創建的新數據庫里,你應該首先創建該對象在model數據數據庫中。你也可以在model總設置默認數據庫參數,新建數據庫都會繼承這些參數。model數據庫包含53個對象:45個系統表、6個對象(用戶sql數據)、1張表(幫助管理change tracking)。你可以在 sys.objects查看這些對象,執行sql:
select * from sys.objects  
    可以查看到具體的數據:
    
 
    一個新的用戶數據庫不能小於3MB(包括日志文件)。並且主數據文件的大小不能小於model數據庫的主數據文件大小。創建數據庫時,盡可能地使用默認值創建。因此創建一個數據庫的簡單sql語句如下:
    CREATE DATABASE newdb;
    執行該語句后,newdb數據庫擁有默認的大小、newdb和newdb_log兩個邏輯名稱、物理文件newdb.mdf和newdb_log.ldf被創建在默認的文件夾。
    接下來給出一個完成的創建數據庫語句:
CREATE DATABASE Archive
    ON
    PRIMARY
    ( NAME = Arch1,
    FILENAME =
    'c:\program files\microsoft sql server\mssql.1\mssql\data\archdat1.mdf',
    SIZE = 100MB,
    MAXSIZE = 200MB,
    FILEGROWTH = 20MB),
    ( NAME = Arch2,
    FILENAME =
    'c:\program files\microsoft sql server\mssql.1\mssql\data\archdat2.ndf',
    SIZE = 10GB,
    MAXSIZE = 50GB,
    FILEGROWTH = 250MB)
    LOG ON
    ( NAME = Archlog1,
    FILENAME =
    'c:\program files\microsoft sql server\mssql.1\mssql\data\archlog1.ldf',
    SIZE = 2GB,
    MAXSIZE = 10GB,
    FILEGROWTH = 100MB);
   
    數據庫文件的擴展可以使用FILEGROWTH 自動實現,FILEGROWTH 定義使用的單位包括TB、GB、MB、KB或者%,屬性MAXSIZE限制問價你的最大值。
    設置文件為自增長有優點也有缺點。例如,你設置文件按照10%自動增長,如果一個應用試圖插入一行並且沒有空余的空間,數據庫開始自動按10%的比例擴大,但這個過程也需要花費大量時間,可能導致插入超時,寫數據失敗。
    數據庫文件也可以自動縮減。這個功能可以使用DBCC SHRINKDATABASE指令操作:
    DBCC SHRINKDATABASE (database_name, 20%)
    上面的語句表示如果數據庫占用空間減小了20%以上,自動執行縮減20%。
    DBCC SHRINKFILE指令允許你縮減當前數據庫的文件。舉個例子,一個數據文件的70%正在使用,使用 DBCC SHRINKFILE縮減5MB,但最終文件縮減成7MB而不是5MB。
    這里我們在說說 DBCC SHRINKFILE,該指令縮減一個數據庫里邊的所有文件,但必須注意的是,縮減不允許任何文件小於數據它自身的最小值。這個最小值是數據庫初始化時的大小。如果你需要縮減一個數據庫小於它的最小值,可以使用DBCC SHRINKFILE 縮減數據庫文件到指定大小。這個指定的大小變成最新的最小值。
數據庫文件分組(filegroup)
   你可以為一個數據庫分組數據文件到一個“文件分組”里邊,它有利於分配和管理。有些時候,你可以通過把數據索引指定到特別的分組從而提升性能。包含主數據文件的分組叫做主文件分組。一個數據庫有且僅有一個主文件分組,但你可以通過freelancer關鍵字創建多個用戶定義的分組。
    這里必須要說明下主文件分組primary filegroup和主文件的區別:
    (1)當我們創建一個數據庫時,首先看到的就是主文件,一般擴展名為.mdf。主文件一個特殊的功能就是指向master數據庫(可通過目錄視圖sys.database_files查看屬於數據庫的文件)。
    (2)主文件分組包含主文件以及其他沒有放置到其他分組的文件。
數據庫文件分組有什么用呢?舉個簡單的例子,你的數據庫由一個大小為120G的文件組成,如果你考慮恢復這個數據庫,你不得不騰出120G的空間才能恢復整個數據庫。但如果我們創建數據庫在若干個小文件上,可以增加恢復時的靈活性。
    創建FILEGROUP可通過以下指令:
  
 CREATE DATABASE Sales
ON PRIMARY
( NAME = salesPrimary1,
FILENAME =
'c:\program files\microsoft sql server\mssql.1\mssql\data\salesPrimary1.mdf',
SIZE = 100,
MAXSIZE = 500,
FILEGROWTH = 100 ),
( NAME = salesPrimary2,
FILENAME =
'c:\program files\microsoft sql server\mssql.1\mssql\data\salesPrimary2.ndf',
SIZE = 100,
MAXSIZE = 500,
FILEGROWTH = 100 ),
FILEGROUP SalesGroup1
( NAME = salesGrp1Fi1e1,
FILENAME =
    'c:\program files\microsoft sql server\mssql.1\mssql\data\salesGrp1Fi1e1.ndf',
    SIZE = 500,
    MAXSIZE = 3000,
    FILEGROWTH = 500 ),
    ( NAME = salesGrp1Fi1e2,
    FILENAME =
    'c:\program files\microsoft sql server\mssql.1\mssql\data\salesGrp1Fi1e2.ndf',
    SIZE = 500,
    MAXSIZE = 3000,
    FILEGROWTH = 500 ),
    FILEGROUP SalesGroup2
    ( NAME = salesGrp2Fi1e1,
    FILENAME =
    'c:\program files\microsoft sql server\mssql.1\mssql\data\salesGrp2Fi1e1.ndf',
    SIZE = 100,
    MAXSIZE = 5000,
    FILEGROWTH = 500 ),
    ( NAME = salesGrp2Fi1e2,
    FILENAME =
    'c:\program files\microsoft sql server\mssql.1\mssql\data\salesGrp2Fi1e2.ndf',
    SIZE = 100,
    MAXSIZE = 5000,
    FILEGROWTH = 500 )
    LOG ON
    ( NAME = 'Sales_log',
    FILENAME =
    'c:\program files\microsoft sql server\mssql.1\mssql\data\saleslog.ldf',
    SIZE = 5MB,
    MAXSIZE = 25MB,
    FILEGROWTH = 5MB );
   
修改數據庫
    當我們想修改文件大小時,可執行:
    USE master
    GO
    ALTER DATABASE Test1
    MODIFY FILE
    ( NAME = 'test1dat3',
    SIZE = 2000MB);
    當我們想添加文件分組並設置為默認時,可參考以下語句:
  ALTER DATABASE Test1
    ADD FILEGROUP Test1FG1;
    GO
    ALTER DATABASE Test1
    ADD FILE
    ( NAME = 'test1dat4',
    FILENAME =
    'c:\program files\microsoft sql server\mssql.1\mssql\data\t1dat4.ndf',
    SIZE = 500MB,
    MAXSIZE = 1000MB,
    FILEGROWTH = 50MB),
    ( NAME = 'test1dat5',
    FILENAME =
    'c:\program files\microsoft sql server\mssql.1\mssql\data\t1dat5.ndf',
    SIZE = 500MB,
    MAXSIZE = 1000MB,
    FILEGROWTH = 50MB)
    TO FILEGROUP Test1FG1;
    GO
    ALTER DATABASE Test1
    MODIFY FILEGROUP Test1FG1 DEFAULT;
    GO
數據庫下的引擎
    一個數據庫由用戶創建分配若干空間,用戶對象例如表和索引都存儲在這些空間里。並且這些空間分配在若干個分割系統文件中。
    數據庫被分割成許多邏輯頁(每個頁大小為8KB),每個文件的分頁編號也是連續的從0到n,n的大小也是根據文件的大小來定。你可以使用database ID、file ID以及page number區別任何頁。當你使用ALTER DATABASE擴展文件時,增加的空間附加在文件的末尾。新分配空間的第一個頁便成為n + 1。但你使用 DBCC SHRINKDATABASE或者 DBCC  SHRINKFILE縮減數據庫時,頁編號也是從n到小移除。這樣確保了一個文件的頁編號總是連續的。
    使用CREATE DATABASE創建數據庫時,我們可得到一個唯一的database ID,我們可以通過執行以下語句:
    select * from sys.databases;
    查看新增的數據庫信息。信息包含name、database_id、create date等等。
設置數據引擎
    我們可以在sys.databases目錄視圖中查看數據庫信息:
    SELECT name, database_id, suser_sname(owner_sid) as owner,
    create_date, user_access_desc, state_desc
    FROM sys.databases
    WHERE database_id <= 4
   查詢結果如下:
    
    接下來我們討論一些比較重要的數據庫屬性
    (1)狀態屬性
a.    SINGLE_USER | RESTRICTED_USER | MULTI_USER                        
用來描述用戶訪問數據庫的屬性。
例如:
ALTER DATABASE Sample SET SINGLE_USER; SINGLE_USER表示某一時刻之允許有一個鏈接; 
RESTRICTED_USER表示用戶僅僅擁有dbcreator、sysadmin server角色或者是數據庫db_owner,才可以訪問數據庫;
MULTI_USER表示任意用戶連接。你可以通過SELECT USER_ACCESS_DESC FROM sys.databases WHERE name = '<name of database>'查看數據庫用戶訪問屬性。
b.    OFFLINE | ONLINE | EMERGENCY
數據庫設置成OFFLINE后該數據庫就不能被修改;如果當前有任何用戶鏈接,數據庫也不能設置成OFFLINE。
修改語句如下:
 ALTER DATABASE Sample SET OFFLINE;
SELECT state_desc from sys.databases WHERE name = 'Sample';
 c.    READ_ONLY | READ_WRITE
該組屬性設置數據庫讀寫模式,默認是READ_WRITE可讀可寫,READ_ONLY表示只讀,沒有INSERT, UPDATE, or DELETE操作。
例如:
 ALTER DATABASE Sample SET READ_ONLY;
SELECT name, is_read_only FROM sys.databases WHERE name = 'Sample ';
        接下來我們添加一張表,sql語句如下:
        create table Tab1
        (
         id int identity(1, 1) primary key,
         Name nvarchar(100) not null
        )
        執行后,數據庫報錯:Failed to update database "Sample" because the database is read-only。提示用戶數據庫只讀。
    (2)SQL選項
a.    ANSI_NULLS                                                                   如果設置為ON,任何和NULL比較返回UNKNOW;如果設置為OFF,如果兩個都是NULL比較結果為TRUE
 
數據庫快照
    首先說說數據庫快照的功能:數據庫快照可以把數據庫鏡像到reporting server,你不能讀取數據從數據庫mirror中。但是你可以創一個mirror的快照然后讀取它;形成reports而不需要blocking;協調管理和保護用戶錯誤。
    創建快照的語法如下:
      CREATE DATABASE Sample_snapshot ON
     (NAME = N'Sample', FILENAME = N'D:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\Sample_snapshot.mdf')
    AS SNAPSHOT OF Sample;
    說明:Sample是我們之前創建的Sample數據庫邏輯名稱,Sample_snapshot.mdf是快照文件。
    快照文件僅僅包含數據源中變化的數據,每個快照文件Sql Server會在內存中保持一份位圖,標識文件中頁的位置,指明是否數據頁是否拷貝到快照。只要數據頁一旦更新,Sql Server檢查文件的位圖並確定是否需要拷貝頁到快照中。這樣的操作叫做copy-on-write。下圖展示了一個數據庫的快照包含了10%的數據:
    
    當一個進程從快照中讀取數據,它首先訪問位圖確認快照是否包含需要訪問頁數據。請看下圖,我們訪問快照,9頁數據來源於數據源,一頁數據來源於快照。但是通過這種訪問形式,不論當前是什么隔離級別,我們訪問的數據不會有任何的鎖行為。這也是使用快照的一大優勢。
    
    必須注意的是,這些位圖是存儲在緩存中,而不是它自身的文件里邊,因此我們需要的時候都能讀到它。當數據庫重啟后,這些位圖丟失,需要重新啟動構建。
tempdb數據庫
    tempdb和其他數據庫最大的一個區別就是當數據庫重啟后tempdb數據庫會被重新創建,它也像其他數據庫一樣,繼承了model數據庫的特性。某些數據庫選項在tempdb上是無效的,例如OFFLINE以及READONLY。你也不能刪除tempdb。
    像之前內容,恢復是運行在一個創建了快照的數據庫上。我們不能恢復tempdb,因此,我們也不能在tempdb上創建快照。這也意味着,我們不能使用DBCC CHECKDB。
    tempdb里邊包含三種對象:user objects、internal objects、the version store。下面分別介紹這三種對象:
    1)user objects:所有的用戶都有權限創建和使用包括在tempdb里邊的本地以及全局的臨時表。本地和全局臨時名是以#或者##號開頭。默認情況下,用戶是沒有權限使用tempdb創建表的,除非這個表以#或者##作為前綴。
    2)internal Objects:對於一般的工具,內部對象在tempdb中是不可見的,但是它確實存在於數據庫中。它們也沒有羅列在catalog view中,因為它們的元數據僅僅存儲在內存中。internal objects的三個基礎類型分別是:work tables、work files、sort units。當執行一個大的查詢、使用XML或者varchar(MAX)、使用statis或者keyset cursors時都會使用work tables;當在查詢中使用hash operator、joining、aggregating時會使用work files;當在查詢中包含Order by排序時會使用Sort units。Sql Server使用排序構建一個索引,也可能使用排序處理grouping查詢。某些joins類型需要Sql Serve線排序數據再執行join。Sort units被創建在tempdb中去處理這些排序的數據。
    3)Version Store:The verson store用於支持行級別數據版本技術。
     tempdb優化
          由於tempdb被使用在許多Sql Server內部操作,所以你不得不去監視和管理它。接下來的部分將討論它的最佳實踐和監視建議。並且將告訴你一些優化讓tempdb管理對象更高效
           1)日志優化:像你知道的,影響你數據庫的每一個操作都是有日志記錄。在tempdb中,卻不是這樣的。例如,記錄更新操作,僅僅原始數據被記錄,沒有記錄新數據。另外,提交操作和提交的日志記錄是沒有同步到tempdb中,而是同步到其他數據庫。
            2)分配和緩存優化:許多分配優化被使用到所有數據庫,不僅僅tempdb。但是,在操作過程中tempdb中經常有大量的新對象被創建和刪除。因此,tempdb的性能沖擊比其他的用戶數據庫都大。在Sql Server 2008中,分配頁的訪問的高效性決定了有效的自由度;你也看到很少的爭奪在分配頁方面,相對於之前的版本;Sql Server 2008也提供了一個非常高效的查詢算法快速從混合區定位到單個頁面。
     tempdb的空間監視
        Sql Server提供了一些系統視圖提供tempdb的報表信息。最簡單的是sys.dm_db_file_space_usage,它為每個數據文件返回一行數據。該視圖包含的列如下:
■ database_id (even though the DBID 2 is the only one used)
        ■ file_id
        ■ unallocated_extent_page_count
        ■ version_store_reserved_page_count
        ■ user_object_reserved_page_count
        ■ internal_object_reserved_page_count
        ■ mixed_extent_page_count
        這些列展示了tempdb中的user objects、internals objects、version store使用空間的情況。執行以下語句:
         select * from sys.dm_db_file_space_usage;
        結果如下圖所示:
        
        這些列展示了user objects、internals objects以及version store是怎樣使用空間的。
 
數據庫安全
    安全對於數據庫用戶的每一個活動都是一個大的考慮點,包括管理員、開發者。數據庫安全架構設計也是理解數據庫或者數據庫對象如何工作的關鍵點。對於安全,Sql Serve 2008有兩個方面的基礎。一個是Securable:一個Securable是一個能授予權限的實體,包括databases、schemas、objects;另外一個是Principal:一個Pirncipal是一個能訪問Securables的實體。對於Pricipal,第一個關鍵是它代表了獨立用戶(像sql server login或者Windows login);第二個關鍵是它代表多用戶(像一個角色或者一個WIndows分組)。
    認證表現了兩個不同的級別。首先,任何用戶想訪問數據庫資源都必須在服務級別授權。為了認證登錄,Sql Server 2008安全提供兩個基礎方法。它們是Windows認證和Sql Server認證。如果是Windows認證,Sql Server登錄策略直接使用Windows策略,允許操作系統驗證Sql Server用戶;如果是Sql Server認證,任何用戶鏈接Sql Server必須提供有效的賬號和密碼。在混合模式下,基於Windows的客戶端可使用WIndows認證。非Windows客戶端或者遠程網絡的連接使用Sql Server認證。另外,當一個用戶配置在數據庫實體(混合模式)安裝時,數據庫連接可一直顯示這個登錄名,例如像sa。這個連接用戶允許使用Window用戶名。
    所有的Pricipal登錄名,不管是windows還是Sql Server認證方式的,都能在目錄視圖ys.server_principals里邊查看到。執行以下語句:
     select * from sys.server_principals;
    查看結果:
 
管理數據庫安全
    登錄名是數據庫的擁有者,我們可以在sys.databases視圖中查看到SID列,這一列表示登錄的SID,並且這個SID擁有這個數據庫。數據庫的資源被登陸用戶所擁有。像你說看到的,數據庫的所有對象被數據庫Principals擁有。 執行以下語句:
    select d.name, d.database_id, p.name
    from sys.databases d
    inner join sys.server_principals p
    on d.owner_sid = p.sid
    查看結果:
    
    我們可以查到,master數據庫的擁有者為sa登陸名。同時也可以看出數據庫中也有一個叫做sa的Principal。
    每個數據庫都有一個sys.database_principals目錄視圖,通過這個視圖,你可以了解登陸名和數據庫中的用戶對應關系。下面的查詢語句展示了示例數據庫中的用戶和登陸名的映射關系,也展示了每個數據庫用戶的默認對象集合schema。
    sql語句如下:
    select d.name, d.database_id, p.name
    from sys.databases d
    inner join sys.server_principals p
    on d.owner_sid = p.sid
    執行結果如下:
    
    分析:登錄名sa有用戶名稱dbo。dbo是一個特殊的登錄,dbo被sa登錄使用(也被所有的sysadmin角色登錄使用,包括在sys.databases羅列的數據庫的所有登錄)。
 
    數據庫和Schemas有什么關系?在ANSI SQL-92標准里,一個schema被定義作為數據庫對象的集合,這個集合被單個用戶擁有並且在同一個命名空間下。一個命名空間是一些列對象的集合,這個集合中的對象名稱是不能重復的。
    登錄用戶(Principals)和Schemas有什么關系?在Sql Server2008,用戶和schemas是兩個獨立的東西。為了理解它們的不同,我們可以認為權限被授予用戶(Principals),但對象存放在schemas里邊。創建一個新用戶一般默認schema都是dbo。
    默認的Schemas是怎樣的?當你創建一個數據庫時,若干schemas包含在數據庫中。它們包括dbo、INFORMATION_SCHEMA、guest。另外,每個數據庫都有一個叫做sys的schemas,sys提供訪問所有的系統表和視圖。
移動、拷貝數據庫
     你可以通過簡單的存儲過程分離一個數據庫,分離時需要保證該數據庫沒有任何連接。如果存在連接,你可以使用ALTER DATABASE 設置數據庫為SINGLE_USER模式中斷已存在的連接。一旦分離了數據庫,該數據庫在sys.databas、system tables中的記錄被移除。
    分離數據庫的指令為:EXEC sp_detach_db <name of database>。例如我們有一個叫做heavi_case2的數據庫,我們先執行sql:
    select * from sys.databases。結果如下:
    
    現在我們執行分離數據庫指令分離heavi_case2數據庫。sql如下:
    EXEC sp_detach_db heavi_case2;
    然后再查看sys.databases表中的數據。通過結果可以看出heavi_case2已從表中移除。
    
    分離數據庫后,我們考慮怎樣附件數據庫。附件數據庫可以使用CREATE DATABASE和FOR
ATTACH選項。語法如下:
     CREATE DATABASE database_name
    ON <filespec> [ ,...n ]
    FOR { ATTACH
    | ATTACH_REBUILD_LOG }
    需要說明的是,以上語句只需要一個關鍵文件即可,因為關鍵文件已經包含了其他文件的位置。但是如果其他文件在不同的路徑下就需要附加說明。現在我們根據以上語法把數據庫heavi_case2附件到數據庫上,在附加之前我們故意把heavi_case2.ldf文件移至其他目錄下,然后執行以下語句:
    CREATE DATABASE heavi_case2
    ON
    (NAME = heavi_case2,
    FILENAME =
    'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\heavi_case2.mdf'
    )
    FOR ATTACH
    查看執行結果 New log file 'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\heavi_case2_log.ldf' was created.。數據庫直接創建了新的日志文件。考慮一種情況:如果我們想拷貝數據庫並且日志文件很大時,我們可以不要日志文件,附件數據庫時新建日志文件。
    

Sql Server來龍去脈系列目錄結構:

  Sql Server來龍去脈系列之一 目錄篇

  Sql Server來龍去脈系列之二 框架和配置

  Sql Server來龍去脈系列之三 查詢過程跟蹤

  Sql Server來龍去脈系列之四 數據庫和文件

  Sql Server來龍去脈系列之五 日志以及恢復

  Sql Server來龍去脈系列之六 表

  Sql Server來龍去脈系列之七 索引

  Sql Server來龍去脈系列之八 比較特殊的存儲

  Sql Server來龍去脈系列之九 查詢優化

  Sql Server來龍去脈系列之十 計划緩存

  Sql Server來龍去脈系列之十一 事務和並發

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM