SQLSERVER將一個文件組的數據移動到另一個文件組


SQLSERVER將一個文件組的數據移動到另一個文件組

 

 

移動數據:

1、有表分區

2、沒有表分區

我這里只討論沒有表分區的情況


例子

比如:你有三個文件組,其中一個是主文件組

測試腳本:

 1 USE master
 2 GO
 3 
 4 
 5 IF EXISTS(SELECT * FROM sys.[databases] WHERE [database_id]=DB_ID('Test'))
 6 DROP DATABASE [Test]
 7 
 8 --1.創建數據庫
 9 CREATE DATABASE [Test]
10 GO
11 
12 USE [Test]
13 GO
14 
15 
16 --2.創建文件組
17 ALTER DATABASE [Test]
18 ADD FILEGROUP [FG_Test_Id_01]
19 
20 ALTER DATABASE [Test]
21 ADD FILEGROUP [FG_Test_Id_02]
22 
23 
24 
25 --3.創建文件
26 ALTER DATABASE [Test]
27 ADD FILE
28 (NAME = N'FG_TestUnique_Id_01_data',FILENAME = N'E:\FG_TestUnique_Id_01_data.ndf',SIZE = 1MB, FILEGROWTH = 1MB )
29 TO FILEGROUP [FG_Test_Id_01];
30 
31 ALTER DATABASE [Test]
32 ADD FILE
33 (NAME = N'FG_TestUnique_Id_02_data',FILENAME = N'E:\FG_TestUnique_Id_02_data.ndf',SIZE = 1MB, FILEGROWTH = 1MB )
34 TO FILEGROUP [FG_Test_Id_02];
35 
36 
37 --4.創建表,這個表的數據存放在[FG_Test_Id_01] 文件組上
38 CREATE TABLE aa(id INT ,cname NVARCHAR(4000)) ON [FG_Test_Id_01] 
39 GO
40 
41 
42 --5.插入數據
43 INSERT INTO [dbo].[aa]
44 SELECT 1,REPLICATE('s',3000)
45 GO 500
46 
47 
48 --6.查詢數據
49 SELECT * FROM [dbo].[aa]
50 
51 
52 --7.創建聚集索引在[FG_Test_Id_02]文件組上
53 CREATE CLUSTERED INDEX PK_ID ON [dbo].[aa]([id]) WITH(ONLINE=ON) ON [FG_Test_Id_02]
54 GO
55 
56 
57 --8.我們查看一下文件組的邏輯文件名
58 EXEC [sys].[sp_helpdb] @dbname = TEST -- sysname
59 
60 
61 
62 --9.收縮一下FG_Test_Id_01文件組文件
63 DBCC SHRINKFILE(FG_TestUnique_Id_01_data,1)
64 
65 
66 --10.你可以選擇drop掉聚集索引,也可以選擇不drop掉聚集索引
67 DROP INDEX PK_ID ON [dbo].[aa]
68 
69 USE master
70 GO
71 DROP DATABASE [Test]

上面的腳本雖然簡單,但是隱藏了非常多的知識點

知識點1:創建了兩個文件組,現在數據庫有三個文件組,包括主文件組,當你不指定任何參數的時候默認創建出來的數據文件是1MB大小

知識點2:插入數據,因為表是創建在[FG_Test_Id_01]文件組上,所以數據都會放在E:\FG_TestUnique_Id_01_data.ndf

1 CREATE TABLE aa(id INT ,cname NVARCHAR(4000)) ON [FG_Test_Id_01] 
2 GO

 

知識點3:創建聚集索引,其實這句話里面包含了幾個動作,在E:\FG_TestUnique_Id_02_data.ndf文件上分配頁面,並把aa表的數據

放進去E:\FG_TestUnique_Id_02_data.ndf文件,其實這里聚集索引成為了移動數據的中介,我在

SQLSERVER聚集索引與非聚集索引的再次研究(上)文章寫到:聚集索引葉子節點就是數據,我們把聚集索引(一定要是聚集索引,非聚集索引不是)

建立在E:\FG_TestUnique_Id_02_data.ndf文件上實際上就是把數據頁面聚集索引頁面移動到E:\FG_TestUnique_Id_02_data.ndf文件里

因為SQLSERVER是沒有 ALTER TABLE aa(id INT ,cname NVARCHAR(4000)) ON [FG_Test_Id_01] 這種語法上

就是說你一旦建表並且表中已經有數據之后,如果你要移動表數據,只能通過聚集索引這個中介來移動表數據

1 CREATE CLUSTERED INDEX PK_ID ON [dbo].[aa]([id]) WITH(ONLINE=ON) ON [FG_Test_Id_02]
2 GO

從下圖可以看出數據都已經移動到E:\FG_TestUnique_Id_02_data.ndf文件上

知識點4:為什麽要加上WITH(ONLINE=ON)??如果你的應用是不能停機的話,加上WITH(ONLINE=ON)就可以在線的創建索引

詳情參考:CREATE INDEX (Transact-SQL)

1 CREATE CLUSTERED INDEX PK_ID ON [dbo].[aa]([id]) WITH(ONLINE=ON) ON [FG_Test_Id_02]
2 GO

 

知識點5:為什麽要收縮[FG_Test_Id_01]文件組文件E:\FG_TestUnique_Id_01_data.ndf

因為數據已經移動到E:\FG_TestUnique_Id_02_data.ndf文件上了,既然已經移到E:\FG_TestUnique_Id_02_data.ndf文件上

為什麽E:\FG_TestUnique_Id_01_data.ndf文件還顯示5MB大小??

大家可以看一下這篇文章:聚集索引表插入數據和刪除數據的方式是怎樣的

我delete了數據,SQLSERVER卻沒有完全釋放空間,其實這里移動數據到別的文件/文件組相當於delete了數據了

但是SQLSERVER並沒有釋放這些空間,所以我需要收縮一下FG_Test_Id_01文件組文件

1 --9.收縮一下FG_Test_Id_01文件組文件
2 DBCC SHRINKFILE(FG_TestUnique_Id_01_data,1)

 

 

知識點6:DBCC SHRINKFILE(FG_TestUnique_Id_01_data,1)

SHRINKFILE的單位是MB,上面的語句就是收縮到1MB大小,其實這里如果E:\FG_TestUnique_Id_01_data.ndf文件有數據的話

並且需要占用2MB大小的空間,那么您使用DBCC SHRINKFILE(FG_TestUnique_Id_01_data,1)這句話只能收縮到2MB大小

並不會收縮到1MB大小的,因為這些數據需要占用空間,你怎麽收縮都收縮不了的,不信的話您們可以測試一下

相關文章:

DBCC SHRINKFILE (Transact-SQL)

user database的initial size和dbcc shrinkfile


總結

雖然移動數據的動作比較簡單,但是知識點挺多的,有些人只知道怎麽做,不知道為什么我覺得這樣不好

尋根問底是我的特性o(∩_∩)o 哈哈

 

注意:移動數據只能一張表一張表的移動,如果表里預先已經有聚集索引,需要先drop掉

移動之前查一下表中的數據在哪個文件組中

1 USE [Northwind]
2 GO
3 EXEC [sys].[sp_help] @objname = N'[dbo].[Categories]' -- nvarchar(776)

 

如有不對的地方,歡迎大家拍磚o(∩_∩)o

 

2014-1-19 補充:

有表分區的方法

大概有三種

先創建新的數據文件,文件組,分區方案,分區函數

例如創建三個新的數據文件和文件組,分區方案和分區函數對於這三個新的數據文件和文件組

舊表:無論已經分區或者還沒有分區都適用下面三種方法:

方法一:建立中間表(新表),中間表建立在新的分區方案上,然后用insert into 新表 select * from 舊表的方法,插入完畢之后

drop掉舊表

 

方法二:建立中間表,中間表建立在新的分區方案上,然后用switch to,因為新分區方案有三個分區

那么,switch to只能夠將表的全部數據切換到其中一個分區

USE Sales    
GO    
ALTER TABLE 舊表 SWITCH PARTITION 1 TO 新表 PARTITION 1 
GO

或者

USE Sales    
GO    
ALTER TABLE 舊表 SWITCH PARTITION 1 TO 新表 PARTITION 2
GO

或者

USE Sales    
GO    
ALTER TABLE 舊表 SWITCH PARTITION 1 TO 新表 PARTITION 3
GO

上面的三條語句就會把舊表的所有數據移動到新表的某個分區,至於移動到哪個分區由最后那個數字來指定PARTITION 要移動到的分區的數字

完成后drop掉舊表

 

方法三:drop掉舊表的聚集索引(如果有),然后在舊表上創建一個聚集索引,創建聚集索引的時候指定新的分區方案

這樣就會把表數據移動到新分區方案,即新的數據文件里,這個方法跟沒有表分區的數據移動是一樣的

 

參考文章:http://blog.csdn.net/smallfools/article/details/4930810

 

刪除文件和刪除文件組

 

刪除失效文件組 (SQL Server)

 

--Transact-SQL
USE master;
GO
ALTER DATABASE AdventureWorks2012
REMOVE FILE test1dat3 ;
ALTER DATABASE AdventureWorks2012
REMOVE FILE test1dat4 ;
GO


--Transact-SQL
USE master;
GO
ALTER DATABASE AdventureWorks2012
REMOVE FILEGROUP Test1FG1 ;
GO

 

移數據

-- 備份數據庫
backup  database  xx  to  disk =xx

DBCC SHRINKFILE(BSDF2017,EMPTYFILE )


ALTER DATABASE AdventureWorks2012
REMOVE FILE BSDF2017 ;

 

 

 


免責聲明!

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



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