解剖SQLSERVER 第八篇 OrcaMDF 现在支持多数据文件的数据库(译)

原文:解剖SQLSERVER 第八篇 OrcaMDF 现在支持多数据文件的数据库(译)

解剖SQLSERVER 第八篇  OrcaMDF 现在支持多数据文件的数据库(译)

http://improve.dk/orcamdf-now-supports-databases-with-multiple-data-files/

OrcaMDF 其中一个最新特性是支持多数据文件的数据库。这在解析上面需要作出相关的小改变,实际上大部分都是bug 修复代码

由于之前只支持单个数据文件而引起的。然而这确实需要一些重大的重构而离开MdfFile 的主入口点,现在使用数据库封装类,封装一个数据文件变量

分配比例填充

OrcaMDF 支持标准的数据库表的比例填充架构,这个数据库表除了有mdf文件之外还有ndf文件,而这些文件都在主文件组里,例如,你可能会创建以下数据文件或者架构

CREATE DATABASE
    [SampleDatabase]
ON  PRIMARY
    (
        NAME = N‘SampleDatabase_Data1‘,
        FILENAME = N‘C:SampleDatabase_Data1.mdf‘,
        SIZE = 3072KB,
        FILEGROWTH = 1024KB
    ),
    (
        NAME = N‘SampleDatabase_Data2‘,
        FILENAME = N‘C:SampleDatabase_Data2.ndf‘,
        SIZE = 3072KB,
        FILEGROWTH = 1024KB
    ),
    (
        NAME = N‘SampleDatabase_Data3‘,
        FILENAME = N‘C:SampleDatabase_Data3.ndf‘,
        SIZE = 3072KB,
        FILEGROWTH = 1024KB
    )
LOG ON
    (
        NAME = N‘SampleDatabase_log‘,
        FILENAME = N‘C:SampleDatabase_log.ldf‘,
        SIZE = 3072KB,
        FILEGROWTH = 10%
    )
GO

USE SampleDatabase
GO

CREATE TABLE MyTable
(
    A int identity,
    B uniqueidentifier default(newid()),
    C char(6000)
)
GO

INSERT INTO MyTable DEFAULT VALUES
GO 100

这会引起MyTable 按比例填充三个数据文件(C列的作用为了让SQLSERVER分配100个页面来装载数据,好让填满三个数据文件)

为了解析这种情况,我们需要做下面的工作

var files = new[]
    {
        @"C:SampleDatabase_Data1.mdf",
        @"C:SampleDatabase_Data2.ndf",
        @"C:SampleDatabase_Data3.ndf"
    };

using (var db = new Database(files))
{
    var scanner = new DataScanner(db);
    var result = scanner.ScanTable("MyTable");

    EntityPrinter.Print(result);
}

运行之后的结果是

大家注意看:

A(4个字节)+B(16个字节)+C(6000个字节)=6020字节

刚好一条记录一页,下面说到,SQLSERVER分配完了一个区之后,一个区8个页面,当一个区分配完毕之后,SQLSERVER

会转到SampleDatabase_Data2.ndf数据文件继续分配页面,分配的值是9~16,一个区分配完毕之后又到

SampleDatabase_Data3.ndf数据文件继续分配页面,分配的值是17~24

自增值会一直到100,注意到A列有间隔,这是由于一个事实我们在每个数据文件的一个区里面以循环赛的方式来分配。

ID1~8在第一个数据文件,9~16在第二个数据文件最后17~24在第三个数据文件。由于这一点,页面25~32分配在第一个数据文件,一直这样下去

由于是堆表,我们使用文件分配顺序扫描,这导致我们获得结果1~8,25~32,49~56,73~80,97~100 全部都是从第一个文件开始,然后9~16,33~40

从第二个数据文件里读取然后到最后一个数据文件的剩余页面。想一下这是不是很怪,好吧,SQLSERVER里面也是完全一样的

不理解的童鞋可以看一下这篇文章《SQLSERVER中的ALLOCATION SCAN和RANGE SCAN》或者

Microsoft SQL Server 2008技术内幕:T-SQL查询 笔记》里面有相关介绍

文件组支持

OrcaMDF 也支持使用文件组,包括按比例分配填充在一个单独的 文件组里,举个例子,你可能创建下面的数据库和架构

CREATE DATABASE
    [SampleDatabase]
ON  PRIMARY
    (
        NAME = N‘SampleDatabase_Data1‘,
        FILENAME = N‘C:SampleDatabase_Data1.mdf‘,
        SIZE = 3072KB,
        FILEGROWTH = 1024KB
    )
LOG ON
    (
        NAME = N‘SampleDatabase_log‘,
        FILENAME = N‘C:SampleDatabase_log.ldf‘,
        SIZE = 3072KB,
        FILEGROWTH = 10%
    )
GO

ALTER DATABASE
    [SampleDatabase]
ADD FILEGROUP
    [SecondFilegroup]
GO

ALTER DATABASE
    [SampleDatabase]
ADD FILE
    (
        NAME = N‘SampleDatabase_Data2‘,
        FILENAME = N‘C:SampleDatabase_Data2.ndf‘,
        SIZE = 3072KB,
        FILEGROWTH = 1024KB
    ),
    (
        NAME = N‘SampleDatabase_Data3‘,
        FILENAME = N‘C:SampleDatabase_Data3.ndf‘,
        SIZE = 3072KB,
        FILEGROWTH = 1024KB
    )
TO FILEGROUP
    [SecondFilegroup]
GO

USE SampleDatabase
GO

CREATE TABLE MyTable
(
    A float default(rand()),
    B datetime default(getdate()),
    C uniqueidentifier default(newid()),
    D char(5000)
) ON [SecondFilegroup]
GO

INSERT INTO MyTable DEFAULT VALUES
GO 100

这将会引起MyTable去按比例填充分配在第二和第三个数据文件之间(D列用来占位置,确保让SQLSERVER分配100个页面来装载数据,好让对文件组里的两个数据文件进行

分配填充)数据只会分别对第二和第三数据文件进行填充而主数据文件不受影响

跟先前的例子的解释一样,结果如下

将会一直到100

第八篇完

时间: 2024-10-14 00:37:19

解剖SQLSERVER 第八篇 OrcaMDF 现在支持多数据文件的数据库(译)的相关文章

解剖SQLSERVER 第五篇 OrcaMDF里读取Bits类型数据(译)

原文:解剖SQLSERVER 第五篇 OrcaMDF里读取Bits类型数据(译) 解剖SQLSERVER 第五篇  OrcaMDF里读取Bits类型数据(译) http://improve.dk/reading-bits-in-orcamdf/ Bits类型的存储跟SQLSERVER其他定长数据类型的存储很不一样.通常,所有定长列都会显示出来,一个条记录里定长数据部分的字段数据总是一个挨着一个 我们可以写入磁盘的最小数据单位是一个字节,存储位类型数据的天真的方法就是使用一整个(字节@)来存储每一

解剖SQLSERVER 第七篇 OrcaMDF 特性概述(译)

原文:解剖SQLSERVER 第七篇 OrcaMDF 特性概述(译) 解剖SQLSERVER 第七篇  OrcaMDF 特性概述(译) http://improve.dk/orcamdf-feature-recap/ 时间过得真快,这已经过了大概四个月了自从我最初介绍我的宠物项目OrcaMDF. 自从项目开始到现在,OrcaMDF发生了很多变化,功能更强了,因此我想提供一个概述对目前OrcaMDF的功能的概述以及我对OrcaMDF未来的计划 页面类型 OrcaMDF 当前支持以下页面的数据完整解

解剖SQLSERVER 第十篇 OrcaMDF Studio 发布+ 特性重温(译)

原文:解剖SQLSERVER 第十篇 OrcaMDF Studio 发布+ 特性重温(译) 解剖SQLSERVER 第十篇  OrcaMDF Studio 发布+ 特性重温(译) http://improve.dk/orcamdf-studio-release-feature-recap/ 自从我上次作了一个OrcaMDF特性概述之后,两个半月过去了. 只是两个半月过去了自从我上次一个OrcaMDF特性概述.从那时起我一直在忙着参加SQLSERVER的最顶级的三个会议:SQLBits.SQLPA

解剖SQLSERVER 第四篇 OrcaMDF里对dates类型数据的解析(译)

解剖SQLSERVER 第四篇  OrcaMDF里对dates类型数据的解析(译) http://improve.dk/parsing-dates-in-orcamdf/ 在SQLSERVER里面有几种不同的date相关类型,当前OrcaMDF 支持三种最常用的date类型:date,datetime,smalldatetime SqlDate实现 date 类型在三种类型之中是最简单的,他是一个3个字节的定长类型,存储了日期值它支持的日期范围从0001-01-01到9999-12-31 默认值

解剖SQLSERVER 第六篇 对OrcaMDF的系统测试里避免regressions(译)

原文:解剖SQLSERVER 第六篇 对OrcaMDF的系统测试里避免regressions(译) 解剖SQLSERVER 第六篇  对OrcaMDF的系统测试里避免regressions (译) http://improve.dk/avoiding-regressions-in-orcamdf-by-system-testing/ 当我继续添加新功能和新的数据结构支持进去OrcaMDF软件的时候,bug的风险不断增加 特别是当我开发一个很大的未知功能时,我不能预估结构和该结构的关联,为了降低风

解剖SQLSERVER 第十七篇 使用 OrcaMDF Corruptor 故意损坏数据库(译)

解剖SQLSERVER 第十七篇 使用 OrcaMDF Corruptor 故意损坏数据库(译) http://improve.dk/corrupting-databases-purpose-using-orcamdf-corruptor/ 有时候你必须先作恶,后行善.情况就是 当你想磨练你的数据库修复技能 我现在添加了一个Corruptor 类到OrcaMDF里面 去测试新的RawDatabase 的功能.Corruptor 就跟他的名字一样--他会故意损坏数据库文件 Corruptor 本身

解剖SQLSERVER 第十一篇 对SQLSERVER的多个版本进行自动化测试(译)

原文:解剖SQLSERVER 第十一篇 对SQLSERVER的多个版本进行自动化测试(译) 解剖SQLSERVER 第十一篇    对SQLSERVER的多个版本进行自动化测试(译) http://improve.dk/automated-testing-of-orcamdf-against-multiple-sql-server-versions/ 自从我发布了OrcaMDF Studio,我已经意识到SQL2005和SQL2008之间的一些系统表的差异. 这些差异导致OrcaMDF 解析失败

解剖SQLSERVER 第十三篇 Integers在行压缩和页压缩里的存储格式揭秘(译)

原文:解剖SQLSERVER 第十三篇 Integers在行压缩和页压缩里的存储格式揭秘(译) 解剖SQLSERVER 第十三篇    Integers在行压缩和页压缩里的存储格式揭秘(译) http://improve.dk/the-anatomy-of-row-amp-page-compressed-integers/ 当解决OrcaMDF对行压缩的支持的时候,视图解析整数的时候遇到了一些挑战. 和正常的未压缩整数存储不同的是这些都是可变长度--这意味着1个整数的值50只占用1个字节,而不是

解剖SQLSERVER 第三篇 数据类型的实现(译)

解剖SQLSERVER 第三篇  数据类型的实现(译) http://improve.dk/implementing-data-types-in-orcamdf/ 实现对SQLSERVER数据类型的解析在OrcaMDF 软件里面是一件比较简单的事,只需要实现ISqlType 接口 public interface ISqlType { bool IsVariableLength { get; } short? FixedLength { get; } object GetValue(byte[]