(超详细)SQL Server for Linux表分区GUID

目录

前言

什么是表分区?

为什么要表分区?

什么时候需要表分区?

为什么选择Linux版SqlServer?

是否支持EF Core?

项目案例说明

编写SQL脚本

第一步、创建数据库Demo

第二步、创建文件组和分区文件

 第三步、创建分区函数

第四步、创建分区架构

第五步、创建分区表

检验分区是否成功


前言

当您找到这篇教程的时候,您已经被数据架构玩得头昏脑涨了,所以在进行教程之前,我先解答大家几个疑问:

什么是表分区?

通俗易懂的说,就是将一个数据表根据某字段的一定规则分为多个文件进行存储。

例如:有一个用户数据表Users,数据表有主键ID,ID为1~1000000的存储在数据文件A,ID为1000001~2000000的存储在数据文件B,依此类推。

为什么要表分区?

当表数据规模非常庞大的时候,各种维护难题都会出现。以下是表分区的优势:

1、改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索速度。 
2、增强可用性:如果表的某个分区出现故障,表在其他分区的数据仍然可用; 
3、维护方便:如果表的某个分区出现故障,需要修复数据,只修复该分区即可; 
4、均衡I/O:可以把不同的分区映射到磁盘以平衡I/O,改善整个系统性能。

什么时候需要表分区?

表的大小超过1GB(也有说法是2GB,但我建议是1GB,因为项目发展快速的情况下,表容量达到1GB后,距离2GB仅需要很短的运营时间) 

为什么选择Linux版SqlServer?

理由很简单,需要用到表分区的项目基本是大型项目,例如:美团、拼多多、淘宝、唯品会等,而大型项目一定会用到微服务,微服务强烈推荐使用Linux系统,所以SqlServer也用Linux啦~

什么?我用C#开发的才选用SqlServer的,C#怎么运行在Linux?这里特别强调一下,.Net Core已经发展几年了,可运行于Linux,且运行效率超Java很多,且.Net Core非常适用于微服务。

是否支持EF Core?

 很遗憾告诉您,当您选用微服务和表分区的时候,务必放弃EF Core,原因如下:

1、EF Core运行效率不如ado.net(虽然EF Core大大提高了开发速度),做表分区本身就是追求极致的运行效率

2、表分区不支持Code First,既然不支持Code First,那还要EF Core干嘛?


项目案例说明

为了更好的编写教程,这里直接使用一个案例:我们即将设计一个数据库表Users,该表数据量可能达到100,000,000行,该表主键名称为Guid,类型uniqueidentifier,实际上该主键也是一个GUID(全局唯一标识符)。然后我们将这个表分为256分文件,预设每个文件存储数据100,000,000/256=390,625行。如果单独从一个100,000,000行的数据文件里的数据查找一个数据,效率太低了,但如果从一个只有390,625行的数据分区文件里查询一个数据,效率就很高了。


编写SQL脚本

第一步、创建数据库Demo

create database Demo

第二步、创建文件组和分区文件

declare @c0 int
declare @c1 int
declare @c0_s varchar(1)
declare @c1_s varchar(1)
declare @c_s varchar(3)
declare @hex CHAR(16)

SET @hex = '0123456789ABCDEF'
    --从00到FF轮询创建文件组名和分区文件名,后缀都为十六进制值00至FF,一共产生256个文件和分组
	set @c0=0
	while @c0<16
	begin
	set @c0_s=SUBSTRING(@hex, (@c0%16)+1, 1)
	set @c1=0
	while @c1<16
	begin
		set @c1_s=SUBSTRING(@hex, (@c1%16)+1, 1)
		set @c_s=@c0_s+@c1_s
		--创建文件组
		exec('alter database Demo add filegroup FG_Users'+@c_s)
        --创建分区文件
		exec('alter database Demo add file (name=''F_Users'+@c_s+''',filename=''/data/mssql/demo/F_Users'+@c_s+'.ndf'',size=1mb,filegrowth=1mb) to filegroup FG_Users'+@c_s)
		set @c1=@c1+1
	end
	set @c0=@c0+1
	end

案例里的分区文件夹/data/mssql/demo/,需在linux下将所有者修改mssql。

执行命令:chown mssql /data/mssql/demo

 第三步、创建分区函数

--创建GUID分割列表,格式为00000000-0000-0000-0000-010000000000,00000000-0000-0000-0000-020000000000,...,00000000-0000-0000-0000-ff0000000000
--由于将表分割为256份,所以一共有255个分割GUID(没有00000000-0000-0000-0000-000000000000)
declare @guid_items varchar(max)

set @c0=0
while @c0<16
begin
	set @c0_s=SUBSTRING(@hex, (@c0%16)+1, 1)
	set @c1=0
	while @c1<16
	begin
		set @c1_s=SUBSTRING(@hex, (@c1%16)+1, 1)
		set @c_s=@c0_s+@c1_s
		if @c0=0 and @c1=0
		begin
			 
		end
		else begin
			if @c0=0 and @c1=1
			begin
				set @guid_items='''00000000-0000-0000-0000-'+@c0_s+@c1_s+'0000000000'''
			end
			else begin
				 set @guid_items= @guid_items+',''00000000-0000-0000-0000-'+@c0_s+@c1_s+'0000000000'''
			end
			 
		end
		set @c1=@c1+1
	end
	set @c0=@c0+1
end

--创建分区函数
if exists( select 1 from sys.partition_functions where name = 'fn_users_partition' )
begin
    drop partition function fn_users_partition
end

exec('create partition function fn_users_partition(uniqueidentifier) as range left for values('+@guid_items+')')

第四步、创建分区架构

--创建分区文件组名列表,格式为FG_Users00,FG_Users01,FG_Users02,...,FG_UsersFF
--每个分区文件组对应一个分区
declare @group_items varchar(max)


set @c0=0
while @c0<16
begin
	set @c0_s=SUBSTRING(@hex, (@c0%16)+1, 1)
	set @c1=0
	while @c1<16
	begin
		set @c1_s=SUBSTRING(@hex, (@c1%16)+1, 1)
		set @c_s=@c0_s+@c1_s
		if @c0=0 and @c1=0
		begin
			set @group_items=@group_name+@c_s
		end
		else begin
			set @group_items=@group_items+','+@group_name+@c_s
		end
		set @c1=@c1+1
	end
	set @c0=@c0+1
end

--创建分区架构
if exists( select * from sys.partition_schemes   where name = 'sch_users_partition' )
begin
    drop partition scheme sch_users_partition
end
exec('create partition scheme sch_users_partition as partition fn_users_partition to ('+@group_items+')')

第五步、创建分区表

create table Users(
	[Guid] uniqueidentifier rowguidcol constraint PK_GUID primary key default(newid()), 
	[Time] smalldatetime not null default(getdate())
) on sch_users_partition([Guid])

到这里,表分区已结束!


检验分区是否成功

insert Users ([Guid]) values (newid())
insert Users ([Guid]) values (newid())
insert Users ([Guid]) values (newid())
insert Users ([Guid]) values (newid())
insert Users ([Guid]) values (newid())
go

select *, $PARTITION.fn_users_partition([Guid]) AS 数据所在分区 from Users

还有另一种检验方式,当您插入大量数据的时候,例如循环插入10,000,000数据(测试时建议启动事务插入,不然太久了),观察分区文件大小变化。

你可能感兴趣的:(.net,core,sqlserver,表分区)