亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

解剖SQLSERVER 第五篇 OrcaMDF里讀取Bits類型數(shù)

系統(tǒng) 2469 0
原文: 解剖SQLSERVER 第五篇 OrcaMDF里讀取Bits類型數(shù)據(jù)(譯)

解剖SQLSERVER 第五篇 ?OrcaMDF里讀取Bits類型數(shù)據(jù)(譯)

http://improve.dk/reading-bits-in-orcamdf/

Bits類型的存儲跟SQLSERVER其他定長數(shù)據(jù)類型的存儲很不一樣。通常,所有定長列都會顯示出來,一個條記錄里定長數(shù)據(jù)部分的字段數(shù)據(jù)總是一個挨著一個

我們可以寫入磁盤的最小數(shù)據(jù)單位是一個字節(jié),存儲位類型數(shù)據(jù)的天真的方法就是使用一整個(字節(jié)@)來存儲每一個位,使用常用的格式去解釋位類型數(shù)據(jù)是很簡單的

,不過這會浪費一些空間 ,就像null位圖,如果一個表只有3列,那么用一個字節(jié)來存儲null位圖會比較浪費,因為其他的5個位都沒有用到

@:文章里是用位 ,這里應(yīng)該是用字節(jié)吧

?

在記錄的內(nèi)部位類型是如何存儲的?

一些位類型列的值是存儲在一個字節(jié)中的,最大可以到8個位,通常,我們會有如下表定義

      
        CREATE
      
      
        TABLE
      
      
         BitTest

(

    A 
      
      
        bit
      
      
        

    B 
      
      
        bit
      
      
        

    C 
      
      
        bit
      
      
        

    D 
      
      
        int
      
      
        

)
      
    

記錄的定長部分?jǐn)?shù)據(jù)需要占用5個字節(jié),4個字節(jié)存儲int 列 ,而另一個字節(jié)存儲A 、B、C這三列位類型的數(shù)據(jù),只用了字節(jié)里面的3個位

解剖SQLSERVER 第五篇 OrcaMDF里讀取Bits類型數(shù)據(jù)

我們再添加一些列

      
        CREATE
      
      
        TABLE
      
      
         BitTest

(

    A 
      
      
        bit
      
      
        

    B 
      
      
        bit
      
      
        

    C 
      
      
        bit
      
      
        

    D 
      
      
        int
      
      
        

    E 
      
      
        bit
      
      
        

    F 
      
      
        bit
      
      
        

    G 
      
      
        bit
      
      
        

    H 
      
      
        smallint
      
      
        

    I 
      
      
        bit
      
      
        

    J 
      
      
        bit
      
      
        

    K 
      
      
        bit
      
      
        

)
      
    

E到G列按道理來說應(yīng)該存儲在D列的后面,但是他們會繼續(xù)使用第一個 bit byte,直到第一個 bit byte使用完所有的位空間為止

下面的圖顯示了H列(smallint?)直接存儲在D列的后面,而在D列后面是存儲K列的新bit byte,因為第一個bit byte已經(jīng)滿了

解剖SQLSERVER 第五篇 OrcaMDF里讀取Bits類型數(shù)據(jù)

?

當(dāng)讀取行記錄里的位類型時我們需要知道的狀態(tài)

很明顯,我們一次不能只讀取一個字段的值,我們讀取固定長度數(shù)據(jù)類型的時候還需要讀取定長數(shù)據(jù)偏移指針

我們需要一些能在讀取的時候指示我們當(dāng)前讀取到字節(jié)中哪一個位屬于哪一個字段的狀態(tài),然后我們讀取一個新的bit byte

我來介紹一下RecordReadState類

      
        public
      
      
        class
      
      
         RecordReadState

{

    
      
      
        //
      
      
         We start out having consumed all bits as none have been read
      
      
        private
      
      
        int
      
       currentBitIndex = 
      
        8
      
      
        ;

    
      
      
        private
      
      
        byte
      
      
         bits;



    
      
      
        public
      
      
        void
      
       LoadBitByte(
      
        byte
      
      
         bits)

    {

        
      
      
        this
      
      .bits =
      
         bits;

        currentBitIndex 
      
      = 
      
        0
      
      
        ;

    }



    
      
      
        public
      
      
        bool
      
      
         AllBitsConsumed

    {

        
      
      
        get
      
       { 
      
        return
      
       currentBitIndex == 
      
        8
      
      
        ; }

    }



    
      
      
        public
      
      
        bool
      
      
         GetNextBit()

    {

        
      
      
        return
      
       (bits & (
      
        1
      
       << currentBitIndex++)) != 
      
        0
      
      
        ;

    }

}
      
    

RecordReadState 類當(dāng)前只需要處理bits,但是將來我可能還要創(chuàng)建一個BitReadState 類用來保存讀取狀態(tài)

RecordReadState 類保存了一個字節(jié)用來當(dāng)作指針指出下一個可用的位在字節(jié)的哪個地方,如果字節(jié)已經(jīng)用完了存儲滿了所有的位數(shù)據(jù)

(currentBixIndex = 8 (0-7 being the available bits)),方法AllBitsConsumed 就會返回true,指示我們需要讀取一個新的?bit byte

GetNextBit方法只是簡單的從?bit byte中讀取當(dāng)前的bit ,然后將currentBitIndex(bit index)的值加1

demo

      
        using
      
      
         NUnit.Framework;


      
      
        using
      
      
         OrcaMDF.Core.Engine.Records;


      
      
        namespace
      
      
         OrcaMDF.Core.Tests.Engine.Records

{

    [TestFixture]


      
      
        public
      
      
        class
      
      
         RecordReadStateTests

{

        [Test]


      
      
        public
      
      
        void
      
      
         General()

{


      
      
        var
      
       state = 
      
        new
      
      
         RecordReadState();


      
      
        //
      
      
         No bits available
      
      
        Assert.IsTrue(state.AllBitsConsumed);

state.LoadBitByte(
      
      
        0xD2
      
      ); 
      
        //
      
      
         11010010


      
      
        //
      
      
         Bits available
      
      
        Assert.IsFalse(state.AllBitsConsumed);


      
      
        //
      
      
         Reading bit values
      
      
        Assert.IsFalse(state.GetNextBit());

Assert.IsTrue(state.GetNextBit());

Assert.IsFalse(state.GetNextBit());

Assert.IsFalse(state.GetNextBit());

Assert.IsTrue(state.GetNextBit());

Assert.IsFalse(state.GetNextBit());

Assert.IsTrue(state.GetNextBit());


      
      
        //
      
      
         One bit left
      
      
        Assert.IsFalse(state.AllBitsConsumed);

Assert.IsTrue(state.GetNextBit());


      
      
        //
      
      
         Bits exhausted, ready for next byte
      
      
        Assert.IsTrue(state.AllBitsConsumed);

}

}

}
      
    

?

SqlBit實現(xiàn)

一旦我們實現(xiàn)了狀態(tài)的讀取,我們就可以實現(xiàn)SqlBit 類型

      
        public
      
      
        class
      
      
         SqlBit : ISqlType

{

    
      
      
        private
      
      
        readonly
      
      
         RecordReadState readState;



    
      
      
        public
      
      
         SqlBit(RecordReadState readState)

    {

        
      
      
        this
      
      .readState =
      
         readState;

    }



    
      
      
        public
      
      
        bool
      
      
         IsVariableLength

    {

        
      
      
        get
      
       { 
      
        return
      
      
        false
      
      
        ; }

    }



    
      
      
        public
      
      
        short
      
      ?
      
         FixedLength

    {

        
      
      
        get
      
      
        

        {

            
      
      
        if
      
      
         (readState.AllBitsConsumed)

                
      
      
        return
      
      
        1
      
      
        ;



            
      
      
        return
      
      
        0
      
      
        ;

        }

    }



    
      
      
        public
      
      
        object
      
       GetValue(
      
        byte
      
      
        [] value)

    {

        
      
      
        if
      
      (readState.AllBitsConsumed && value.Length != 
      
        1
      
      
        )

            
      
      
        throw
      
      
        new
      
       ArgumentException(
      
        "
      
      
        All bits consumed, invalid value length: 
      
      
        "
      
       +
      
         value.Length);



        
      
      
        if
      
       (value.Length == 
      
        1
      
      
        )

            readState.LoadBitByte(value[
      
      
        0
      
      
        ]);



        
      
      
        return
      
      
         readState.GetNextBit();

    }

}
      
    

SqlBit 在構(gòu)造函數(shù)里傳入一個read state,read state指示當(dāng)前記錄讀取操作的范圍。需要注意的是固定長度需要依據(jù)read state里的當(dāng)前AllBitsConsumed值

如果字節(jié)里面所有位都被占用,那么意味著需要讀取整個字節(jié),如果if (readState.AllBitsConsumed)返回0表示不需要讀取整個字節(jié),但是GetValue方法依然會被調(diào)用

GetValue方法會驗證一種情況:readState.AllBitsConsumed 返回真,證明 bit byte是有數(shù)據(jù)存儲在里面,但是value.Length返回的長度是0,那證明有問題了

如果我們讀到一個值,我們會請求?read state 去裝載一個新的bit byte ,之后,我們可以調(diào)用GetNextBit 方法返回?read state的當(dāng)前bit

相關(guān)測試

      
        using
      
      
         NUnit.Framework;


      
      
        using
      
      
         OrcaMDF.Core.Engine.Records;


      
      
        using
      
      
         OrcaMDF.Core.Engine.SqlTypes;




      
      
        namespace
      
      
         OrcaMDF.Core.Tests.Engine.SqlTypes

{

    [TestFixture]

    
      
      
        public
      
      
        class
      
      
         SqlBitTests

    {

        [Test]

        
      
      
        public
      
      
        void
      
      
         GetValue()

        {

            
      
      
        var
      
       readState = 
      
        new
      
      
         RecordReadState();

            
      
      
        var
      
       type = 
      
        new
      
      
         SqlBit(readState);



            
      
      
        //
      
      
         No bytes read - length is one
      
      

            Assert.AreEqual(
      
        1
      
      
        , type.FixedLength);



            
      
      
        //
      
      
         Load byte and check length is 0
      
      

            readState.LoadBitByte(
      
        0xD2
      
      
        );

            Assert.AreEqual(
      
      
        0
      
      
        , type.FixedLength);



            Assert.IsFalse((
      
      
        bool
      
      )type.GetValue(
      
        new
      
      
        byte
      
      [
      
        0
      
      
        ]));

            Assert.IsTrue((
      
      
        bool
      
      )type.GetValue(
      
        new
      
      
        byte
      
      [
      
        0
      
      
        ]));

            Assert.IsFalse((
      
      
        bool
      
      )type.GetValue(
      
        new
      
      
        byte
      
      [
      
        0
      
      
        ]));

            Assert.IsFalse((
      
      
        bool
      
      )type.GetValue(
      
        new
      
      
        byte
      
      [
      
        0
      
      
        ]));

            Assert.IsTrue((
      
      
        bool
      
      )type.GetValue(
      
        new
      
      
        byte
      
      [
      
        0
      
      
        ]));

            Assert.IsFalse((
      
      
        bool
      
      )type.GetValue(
      
        new
      
      
        byte
      
      [
      
        0
      
      
        ]));

            Assert.IsTrue((
      
      
        bool
      
      )type.GetValue(
      
        new
      
      
        byte
      
      [
      
        0
      
      
        ]));



            
      
      
        //
      
      
         One bit left - length should still be 0
      
      

            Assert.AreEqual(
      
        0
      
      
        , type.FixedLength);



            Assert.IsTrue((
      
      
        bool
      
      )type.GetValue(
      
        new
      
      
        byte
      
      [
      
        0
      
      
        ]));



            
      
      
        //
      
      
         All bits consumed - length should be 1
      
      

            Assert.AreEqual(
      
        1
      
      
        , type.FixedLength);

        }

    }

}
      
    

?

第五篇完

解剖SQLSERVER 第五篇 OrcaMDF里讀取Bits類型數(shù)據(jù)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国产精品永久免费 | 免费色片 | 精品爱爱 | 99热只有这里有精品 | 四虎影视永久地址www成人污 | 67194在线午夜亚洲 | 999在线免费视频 | 成人免费高清视频 | 欧美在线一 | a级毛片免费 | 国产午夜不卡 | 奇米影视亚洲 | 奇米影视888狠狠狠777九色 | 久久爱avwww久久爱 | 久久精品免费全国观看国产 | 麻豆日韩区久久综合 | 亚洲 在线播放 | 日本一级毛片视频 | 日韩欧美中文字幕出 | 欧美一级夜夜爽 视频 | 亚洲精品一区最新 | 国产三级观看久久 | 天天干天天拍天天操 | 无毒不卡在线观看 | 久久美 | 99视频在线观看视频一区 | 国产综合精品一区二区 | 99热热久久这里只有精品166 | 毛茸茸的浓密在线视频 | 国产精品国产高清国产专区 | www.黄网站| 欧美亚洲另类视频 | 天天爱夜夜爱 | 中文字幕一区日韩在线视频 | 久久这里只精品国产99热8 | 日本视频播放免费线上观看 | 久久新| 亚洲精品色综合色在线观看 | 中文字幕一区日韩在线视频 | 国产精品成人久久久久久久 | 97色伦图片97色伦图影院久久 |