SQLSERVER将一个文件组的数据移动到另一个文件组
SQLSERVER将一个文件组的数据移动到另一个文件组
移动数据:
1、有表分区
2、没有表分区
我这里只讨论没有表分区的情况
例子
比如:你有三个文件组,其中一个是主文件组
测试脚本:
USE master
GO IF EXISTS(SELECT * FROM sys.[databases] WHERE [database_id]=DB_ID('Test'))
DROP DATABASE [Test] --1.创建数据库
CREATE DATABASE [Test]
GO USE [Test]
GO --2.创建文件组
ALTER DATABASE [Test]
ADD FILEGROUP [FG_Test_Id_01] ALTER DATABASE [Test]
ADD FILEGROUP [FG_Test_Id_02] --3.创建文件
ALTER DATABASE [Test]
ADD FILE
(NAME = N'FG_TestUnique_Id_01_data',FILENAME = N'E:\FG_TestUnique_Id_01_data.ndf',SIZE = 1MB, FILEGROWTH = 1MB )
TO FILEGROUP [FG_Test_Id_01]; ALTER DATABASE [Test]
ADD FILE
(NAME = N'FG_TestUnique_Id_02_data',FILENAME = N'E:\FG_TestUnique_Id_02_data.ndf',SIZE = 1MB, FILEGROWTH = 1MB )
TO FILEGROUP [FG_Test_Id_02]; --4.创建表,这个表的数据存放在[FG_Test_Id_01] 文件组上
CREATE TABLE aa(id INT ,cname NVARCHAR(4000)) ON [FG_Test_Id_01]
GO --5.插入数据
INSERT INTO [dbo].[aa]
SELECT 1,REPLICATE('s',3000)
GO 500 --6.查询数据
SELECT * FROM [dbo].[aa] --7.创建聚集索引在[FG_Test_Id_02]文件组上
CREATE CLUSTERED INDEX PK_ID ON [dbo].[aa]([id]) WITH(ONLINE=ON) ON [FG_Test_Id_02]
GO --8.我们查看一下文件组的逻辑文件名
EXEC [sys].[sp_helpdb] @dbname = TEST -- sysname --9.收缩一下FG_Test_Id_01文件组文件
DBCC SHRINKFILE(FG_TestUnique_Id_01_data,1) --10.你可以选择drop掉聚集索引,也可以选择不drop掉聚集索引
DROP INDEX PK_ID ON [dbo].[aa] USE master
GO
DROP DATABASE [Test]
上面的脚本虽然简单,但是隐藏了非常多的知识点
知识点1:创建了两个文件组,现在数据库有三个文件组,包括主文件组,当你不指定任何参数的时候默认创建出来的数据文件是1MB大小

知识点2:插入数据,因为表是创建在[FG_Test_Id_01]文件组上,所以数据都会放在E:\FG_TestUnique_Id_01_data.ndf
CREATE TABLE aa(id INT ,cname NVARCHAR(4000)) ON [FG_Test_Id_01]
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] 这种语法上
就是说你一旦建表并且表中已经有数据之后,如果你要移动表数据,只能通过聚集索引这个中介来移动表数据

CREATE CLUSTERED INDEX PK_ID ON [dbo].[aa]([id]) WITH(ONLINE=ON) ON [FG_Test_Id_02]
GO
从下图可以看出数据都已经移动到E:\FG_TestUnique_Id_02_data.ndf文件上

知识点4:为什麽要加上WITH(ONLINE=ON)??如果你的应用是不能停机的话,加上WITH(ONLINE=ON)就可以在线的创建索引
详情参考:CREATE INDEX (Transact-SQL)
CREATE CLUSTERED INDEX PK_ID ON [dbo].[aa]([id]) WITH(ONLINE=ON) ON [FG_Test_Id_02]
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文件组文件
--9.收缩一下FG_Test_Id_01文件组文件
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掉
移动之前查一下表中的数据在哪个文件组中
USE [Northwind]
GO
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
删除文件和删除文件组
--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 ;
SQLSERVER将一个文件组的数据移动到另一个文件组的更多相关文章
- SQLSERVER将数据移到另一个文件组之后清空文件组并删除文件组
SQLSERVER将数据移到另一个文件组之后清空文件组并删除文件组 之前写过一篇文章:SQLSERVER将一个文件组的数据移动到另一个文件组 每个物理文件(数据文件)对应一个文件组的情况(一对一) 如 ...
- VLOOKUP函数将一个excel表格的数据匹配到另一个表中
sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频) https://study.163.com/course/introduction.htm?courseId=1005269003& ...
- sql将一个表中的数据插入到另一个表中
sql将一个表中的数据插入到另一个表中 列名不一定要相同,只要你在HH中列出要插入列的列表跟select from mm表中的选择的列的列表一一对应就可以了,当然两边的数据类型应该是兼容的. ...
- shell脚本就是由Shell命令组成的执行文件,将一些命令整合到一个文件中,进行处理业务逻辑,脚本不用编译即可运行。它通过解释器解释运行,所以速度相对来说比较慢。
shell脚本?在说什么是shell脚本之前,先说说什么是shell. shell是外壳的意思,就是操作系统的外壳.我们可以通过shell命令来操作和控制操作系统,比如Linux中的Shell命令就包 ...
- 在C#中如何确定一个文件是不是文本文件,以及如何确定一个文件的类型
博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:在C#中如何确定一个文件是不是文本文件,以及如何确定一个文件的类型.
- 工具:从一个文件夹中复制jar到另一个文件夹中
工具类:从一个文件夹中复制jar到另一个文件夹中 需要的小伙伴可以试一试,很爽哦,有时候真的很需要! 需求:当我们拿到一个maven项目时,而maven项目的jar包都是通过pom.xml文件管理的, ...
- sql-server的添加数据库文件(日志数据)以及收缩数据库文件(日志数据)
环境: SSMS sql-server2016 一.为数据库添加数据文件 添加日志数据文件 以下是添加数据文件和日志文件的代码 ALTER DATABASE [joinbest] ADD FILE ( ...
- 如何将一个excel表格的数据匹配到另一个表中
我们在操作excel表的时,有时需要将一个excel表中的数据匹配到另一个表中,那么就需要用到VLOOKUP函数,VLOOKUP函数是Excel中的一个纵向查找函数,VLOOKUP是按列查找,最终返回 ...
- 【VS开发】使用WinPcap编程(4)——把网络数据包存储到一个文件中
这里用到的数据结构是pcap_dumper_t,这也是一个相当于文件描述符的东西,我们在用的时候先指定pcap_dumper_t *dumpfp; 使用两个函数来存储网络数据,一个是pcap_dump ...
随机推荐
- 深入浅出Redis-redis底层数据结构(上)
1.概述 相信使用过Redis 的各位同学都很清楚,Redis 是一个基于键值对(key-value)的分布式存储系统,与Memcached类似,却优于Memcached的一个高性能的key-valu ...
- Sublime Text 3中文乱码解决方法以及安装包管理器方法
一般出现乱码是因为文本采用了GBK编码格式,Sublime Text默认不支持GBK编码. 安装包管理器 简单安装 使用Ctrl+`快捷键或者通过View->Show Console菜单打开命令 ...
- C# - 值类型、引用类型&走出误区,容易错误的说法
1. 值类型与引用类型小总结 1)对于引用类型的表达式(如一个变量),它的值是一个引用,而非对象. 2)引用就像URL,是允许你访问真实信息的一小片数据. 3)对于值类型的表达式,它的值是实际的数据. ...
- [版本控制之道] Git 常用的命令总结(欢迎收藏备用)
坚持每天学习,坚持每天复习,技术永远学不完,自己永远要前进 总结日常开发生产中常用的Git版本控制命令 ------------------------------main-------------- ...
- WebApi接口 - 响应输出xml和json
格式化数据这东西,主要看需要的运用场景,今天和大家分享的是webapi格式化数据,这里面的例子主要是输出json和xml的格式数据,测试用例很接近实际常用情况:希望大家喜欢,也希望各位多多扫码支持和点 ...
- javascript匹配各种括号书写是否正确
今天在codewars上做了一道题,如下 看上去就是验证三种括号各种嵌套是否正确书写,本来一头雾水,一种括号很容易判断, 但是三种怎么判断! 本人只是个前端菜鸟,,不会什么高深的正则之类的. 于是,在 ...
- VS15 preview 5打开文件夹自动生成slnx.VC.db SQLite库疑惑?求解答
用VS15 preview 5打开文件夹(详情查看博客http://www.cnblogs.com/zsy/p/5962242.html中配置),文件夹下多一个slnx.VC.db文件,如下图: 本文 ...
- 【Java学习系列】第3课--Java 高级教程
本文地址 可以拜读: 从零开始学 Java 分享提纲: 1. Java数据结构 2. Java 集合框架 3. Java泛型 4. Java序列化 5. Java网络编程 6. Java发送Email ...
- BPM助力企业数字化转型
自九十年代末,流程管理开始引入国内,至今已经有20多年的历史了,由最初的部门级应用向企业级应用转变,大家的认知也经历了一系列的发展变化.不同阶段的信息化水平对企业的流程以及BPM平台也提出了不同的需求 ...
- SQLServer如何添加try catch
在.net中我们经常用到try catch.不过在sqlserver中我们也可以使用try catch捕捉错误,在这里把语法记录下来和大家分享一下, --构建存储过程CREATE PROCEDURE ...