• 解剖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

    第八篇完

  • 相关阅读:
    如何阅读一个Web项目 【转载】
    线程的状态与基本操作
    java多线程通信方式之一:wait/notify
    synchronized的简单理解
    每月IT摘录201807
    springmvc 请求无法到达controller,出现404
    android开发 java与c# 兼容AES加密
    android 开发不能创建目录
    mysql存储过程出现OUT or INOUT argument 10 for routine
    android退出登陆后,清空之前所有的activity,进入登陆主界面
  • 原文地址:https://www.cnblogs.com/lyhabc/p/4020876.html
Copyright © 2020-2023  润新知