਍㰀栀攀愀搀㸀ഀഀ Albert van der Sel - BLOBS in SQL Server ਍㰀⼀栀攀愀搀㸀ഀഀ ਍ഀഀ

Simple (and incomplete) note about storage of BLOBS in SQL Server

਍ഀഀ Version : 0.8
਍㰀䈀㸀䐀愀琀攀㰀⼀䈀㸀ऀऀ㨀  ㈀⼀㄀㈀⼀㈀ ㄀㈀㰀戀爀㸀ഀഀ By : Albert van der Sel
਍㰀栀爀⼀㸀ഀഀ ਍㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀氀愀挀欀∀㸀ഀഀ ਍㰀戀爀㸀ഀഀ
਍ഀഀ We all know that Relational Databases, in the "past", typically were used to store traditional "administrative"
਍愀渀搀 ∀戀甀猀椀渀攀猀猀ⴀ氀椀欀攀∀ 搀愀琀愀 氀椀欀攀 䌀甀猀琀漀洀攀爀 渀愀洀攀猀Ⰰ 愀搀搀爀攀猀猀攀猀Ⰰ 漀爀搀攀爀渀甀洀戀攀爀猀Ⰰ 瀀爀椀挀攀猀Ⰰ 愀洀漀甀渀琀猀Ⰰ 瀀爀漀搀甀挀琀 椀搀✀猀 攀琀挀⸀⸀㰀戀爀㸀ഀഀ
਍匀漀Ⰰ 琀栀攀 挀漀洀洀漀渀 匀儀䰀 匀攀爀瘀攀爀 㰀䤀㸀搀愀琀愀琀礀瀀攀猀㰀⼀䤀㸀 椀渀 甀猀攀 愀爀攀 猀椀洀瀀氀礀 挀栀愀爀愀挀琀攀爀戀愀猀攀搀 漀爀 渀甀洀洀攀爀椀挀Ⰰ 氀椀欀攀 ∀挀栀愀爀∀Ⰰ ∀瘀愀爀挀栀愀爀∀Ⰰ ∀椀渀琀∀Ⰰ㰀戀爀㸀ഀഀ "nummeric" (or decimal), "datetime" and the like.
਍吀栀攀猀攀 搀愀琀愀琀礀瀀攀猀 猀琀椀氀氀 愀爀攀 瘀攀爀礀 椀洀瀀漀爀琀愀渀琀 ⠀愀渀搀 洀甀挀栀 甀猀攀搀 漀昀挀漀甀爀猀攀⤀Ⰰ 戀甀琀 琀栀攀 氀愀琀攀爀 匀儀䰀 匀攀爀瘀攀爀 瘀攀爀猀椀漀渀猀 眀攀爀攀㰀戀爀㸀ഀഀ progressively better equiped to handle "binary" data.
਍㰀戀爀㸀ഀഀ This "binary" data could be very diverse: .pdf files, excel sheets, images, video's, and completely unstructured
਍搀愀琀愀 愀猀 眀攀氀氀⸀ 唀猀甀愀氀氀礀Ⰰ 瀀攀漀瀀氀攀 挀愀氀氀 琀栀愀琀 琀礀瀀攀 漀昀 搀愀琀愀 ∀䈀䰀伀䈀猀∀ 漀爀 䈀椀渀愀爀礀 䰀愀爀最攀 伀戀樀攀挀琀猀⸀㰀戀爀㸀ഀഀ
਍䤀琀 猀漀甀渀搀猀 愀 戀椀琀 猀琀爀愀渀最攀㨀 䤀昀 眀攀 樀甀猀琀 氀漀漀欀 愀琀 琀栀攀 瀀栀礀猀椀挀愀氀 椀洀瀀氀攀洀攀渀琀愀琀椀漀渀Ⰰ 匀儀䰀 匀攀爀瘀攀爀 甀猀攀猀 瀀愀最攀猀 漀昀 㠀㄀㤀㈀ 戀礀琀攀猀Ⰰ㰀戀爀㸀ഀഀ where tablerows are stored in (details will follow soon!).
਍匀漀Ⰰ 眀攀 挀愀渀 攀愀猀椀氀礀 椀洀愀最椀渀攀 琀栀愀琀 樀甀猀琀 挀栀愀爀愀挀琀攀爀猀 愀渀搀 猀漀洀攀 渀甀洀洀攀爀椀挀 搀愀琀愀 挀愀渀 戀攀 攀愀猀椀氀礀 猀琀漀爀攀搀 椀渀 猀甀挀栀 愀 瀀愀最攀⸀㰀戀爀㸀ഀഀ Now what happens if a 5MB image is stored? As we will see, SQL Server (in case of "inline" storage) will simply store
਍愀 瀀漀椀渀琀攀爀 椀渀 琀栀攀 昀椀爀猀琀 瀀愀最攀Ⰰ 琀栀愀琀 眀椀氀氀 瀀漀椀渀琀 琀漀 愀 眀栀漀氀攀 猀攀瀀攀爀愀琀攀 ∀琀爀攀攀∀ 漀昀 瀀愀最攀猀 猀琀漀爀椀渀最 琀栀椀猀 戀氀漀戀 搀愀琀愀⸀㰀戀爀㸀ഀഀ
਍匀漀Ⰰ 瀀爀漀戀氀攀洀 猀漀氀瘀攀搀㼀 圀攀 栀愀瘀攀 渀漀琀 猀攀攀渀 愀渀礀 搀攀琀愀椀氀猀 礀攀琀Ⰰ 戀甀琀 琀栀攀 琀漀瀀椀挀 爀攀洀愀椀渀猀 氀椀瘀攀氀礀 搀椀猀挀甀猀猀攀搀 愀洀漀渀最㰀戀爀㸀ഀഀ various SQL Server experts. Fact is, that a true relational database does not seem to be very good in
਍猀琀漀爀椀渀最 愀渀搀 栀愀渀搀氀椀渀最 琀爀愀搀椀琀椀漀渀愀氀 搀愀琀愀 琀漀最攀琀栀攀爀 眀椀琀栀 䈀䰀伀䈀猀⸀㰀戀爀㸀ഀഀ
਍伀渀 琀栀攀 漀琀栀攀爀 栀愀渀搀㨀 琀栀攀 戀甀猀椀渀攀猀猀 栀愀猀 挀栀愀渀最攀搀⸀ 䴀愀渀礀 愀瀀瀀氀椀挀愀琀椀漀渀猀 眀愀渀琀猀 琀漀 猀栀漀眀 琀栀攀椀爀 挀甀猀琀漀洀攀爀猀 椀洀愀最攀猀 愀渀搀 洀漀瘀椀攀猀 漀昀 琀栀攀椀爀㰀戀爀㸀ഀഀ products and services. And the best way to store them seems to be a database.
਍䄀渀搀Ⰰ 䴀椀挀爀漀猀漀昀琀 爀攀猀瀀漀渀搀攀搀 焀甀椀琀攀 眀攀氀氀⸀ 圀栀愀琀 礀漀甀 挀愀渀 猀琀漀爀攀 椀渀 匀儀䰀 匀攀爀瘀攀爀 渀漀眀愀礀搀愀礀猀Ⰰ 甀猀椀渀最 匀儀䰀 ㈀  㠀Ⰰ 漀爀 攀瘀攀渀 戀攀琀琀攀爀Ⰰ㰀戀爀㸀ഀഀ SQL 2012, is amazing.
਍㰀戀爀㸀ഀഀ There exists at least the following options to store binary data in SQL Server:
਍ഀഀ ਍㰀甀氀㸀ഀഀ
  • Inline storage, where the blobs really occupy internal database pages.
  • ਍㰀氀椀㸀䔀砀琀攀爀渀愀氀 猀琀漀爀愀最攀Ⰰ 眀栀攀爀攀 琀栀攀 昀椀氀攀猀 樀甀猀琀 爀攀猀椀搀攀 漀渀 愀 昀椀氀攀猀礀猀琀攀洀Ⰰ 戀甀琀 眀栀攀爀攀 洀攀琀愀搀愀琀愀 攀砀椀猀琀猀 椀渀 匀儀䰀 匀攀爀瘀攀爀 ⠀氀椀欀攀 瀀漀椀渀琀攀爀猀⤀⸀㰀⼀氀椀㸀ഀഀ
  • External storage using additional (third party) providers, but where metadata exists in SQL Server (like pointers).
  • ਍㰀氀椀㸀䈀氀漀戀猀 椀渀 愀 猀漀挀愀氀氀攀搀 ∀䘀椀氀攀猀琀爀攀愀洀∀ 昀椀氀攀最爀漀甀瀀Ⰰ 眀栀椀挀栀 椀猀 愀挀琀甀愀氀氀礀 愀 昀漀氀搀攀爀 漀渀 愀 昀椀氀攀猀礀猀琀攀洀 ⠀㈀  㠀⤀⸀㰀⼀氀椀㸀ഀഀ
  • Usage of socalled "Filetables" (2012)
  • ਍㰀⼀甀氀㸀ഀഀ ਍㰀戀爀㸀ഀഀ In this note, we are trying to explore some stuff on BLOBs: how BLOBs are stored, how to load them,
    ਍栀漀眀 琀漀 爀攀琀爀椀攀瘀攀 琀栀攀洀 ⠀甀猀椀渀最 吀匀儀䰀 愀渀搀 漀琀栀攀爀 瀀爀漀最爀愀洀洀愀琀椀挀 椀渀琀攀爀昀愀挀攀猀⤀Ⰰ 愀渀搀 栀漀瀀攀昀甀氀氀礀 猀漀洀攀 洀漀爀攀 椀渀琀攀爀攀猀琀椀渀最 昀愀挀琀猀⸀㰀戀爀㸀ഀഀ
    ਍䘀椀爀猀琀Ⰰ 眀攀 眀椀氀氀 攀砀瀀氀漀爀攀 琀栀攀 ∀琀爀愀搀椀琀椀漀渀愀氀∀ 椀渀氀椀渀攀 猀琀漀爀愀最攀Ⰰ 愀渀搀 眀漀爀欀 漀甀爀 眀愀礀 琀栀爀漀甀最栀 琀栀攀 漀琀栀攀爀 漀瀀琀椀漀渀猀 氀愀琀攀爀 漀渀⸀㰀戀爀㸀ഀഀ
    ਍㰀䈀㸀䠀漀瀀攀昀甀氀氀礀Ⰰ 礀漀甀 眀椀氀氀 氀椀欀攀 琀栀椀猀 猀椀洀瀀氀攀 渀漀琀攀⸀⸀⸀⸀⸀㰀⼀䈀㸀㰀戀爀㸀ഀഀ
    ਍㰀戀爀㸀ഀഀ
    ਍ഀഀ ਍ഀഀ
    ਍㰀䈀㸀㰀唀㸀䴀愀椀渀 䌀漀渀琀攀渀琀猀㨀㰀⼀唀㸀㰀⼀䈀㸀㰀戀爀㸀ഀഀ
    ਍ഀഀ Chapter 1. Inline storage of a blob.
    ਍☀渀戀猀瀀 ㄀⸀㄀ 匀漀洀攀 瀀爀攀瀀愀爀愀琀椀漀渀猀 昀椀爀猀琀 ⠀挀爀攀愀琀攀 愀 搀愀琀愀戀愀猀攀 攀琀挀⸀⸀⤀⸀㰀戀爀㸀ഀഀ   1.2 Adding a blob to a table.
    ਍☀渀戀猀瀀 ㄀⸀㌀ 䄀渀愀氀礀猀椀猀 漀昀 琀栀攀 ⠀椀渀氀椀渀攀⤀ 戀氀漀戀 猀琀漀爀愀最攀⸀㰀戀爀㸀ഀഀ
    ਍㰀䈀㸀䌀栀愀瀀琀攀爀 ㈀⸀ 倀愀最攀猀Ⰰ 攀砀琀攀渀搀猀Ⰰ 愀渀搀 漀琀栀攀爀 猀琀爀甀挀琀甀爀攀猀⸀㰀⼀䈀㸀㰀戀爀㸀ഀഀ   2.1 Structure of a data page, and special pages.
    ਍☀渀戀猀瀀 ㈀⸀㈀ 䔀砀琀攀渀琀猀⸀㰀戀爀㸀ഀഀ   2.3 System pages.
    ਍㰀戀爀㸀ഀഀ Chapter 3. Using Filestream for storage of blobs.
    ਍☀渀戀猀瀀 ㌀⸀㄀ 䔀渀愀戀氀椀渀最 ∀䘀椀氀攀猀琀爀攀愀洀∀⸀㰀戀爀㸀ഀഀ   3.2 Implementing "Filestream".
    ਍☀渀戀猀瀀 ㌀⸀㌀ 䄀搀搀椀渀最 愀 戀氀漀戀⸀㰀戀爀㸀ഀഀ   3.4 Analysis of blob storage.
    ਍㰀戀爀㸀ഀഀ Chapter 4. Some methods for storage and retrieval of blobs. (not ready)
    ਍㰀戀爀㸀ഀഀ ਍㰀戀爀㸀ഀഀ
    ਍㰀戀爀㸀ഀഀ ਍㰀栀㈀㸀䌀栀愀瀀琀攀爀 ㄀⸀ 䤀渀氀椀渀攀 猀琀漀爀愀最攀 漀昀 愀 戀氀漀戀⸀㰀⼀栀㈀㸀ഀഀ ਍ഀഀ Here we take a quick look on how we can "load" a blob (in this case, a .jpg file) into a SQL Server database.
    ਍䤀渀 琀栀椀猀 挀栀愀瀀琀攀爀Ⰰ 眀攀 眀椀氀氀 椀渀瘀攀猀琀椀最愀琀攀 ∀椀渀氀椀渀攀∀ 猀琀漀爀愀最攀Ⰰ 眀栀攀爀攀 琀栀攀 戀氀漀戀 椀猀 猀琀漀爀攀搀 漀渀 椀渀琀攀爀渀愀氀 搀愀琀愀戀愀猀攀 瀀愀最攀猀⸀㰀戀爀㸀ഀഀ
    ਍ഀഀ

    1.1 Some preparations first (create a database etc..).

    ਍ഀഀ ਍㰀戀爀㸀ഀഀ Now, we will do a practical example. Hopefully, you have sql server installed (like 2008 or 2012), and you
    ਍愀爀攀 椀渀瘀椀琀攀搀 琀漀 昀漀氀氀漀眀 愀氀漀渀最⸀㰀戀爀㸀ഀഀ
    ਍䘀椀爀猀琀Ⰰ 眀攀 眀椀氀氀 挀爀攀愀琀攀 愀 猀椀洀瀀氀攀 搀愀琀愀戀愀猀攀⸀ 䠀漀眀攀瘀攀爀Ⰰ 椀琀 椀猀 挀漀洀瀀漀猀攀搀 漀昀 猀攀瘀攀爀愀氀 昀椀氀攀猀⸀ 吀栀椀猀 椀猀 猀漀 戀攀挀愀甀猀攀 䤀 眀愀渀琀㰀戀爀㸀ഀഀ to prevent to store our objects in the "primary" .mdf file.
    ਍䄀挀琀甀愀氀氀礀 栀愀瘀椀渀最 洀甀氀琀椀瀀氀攀 ⠀搀愀琀愀⤀ 昀椀氀攀猀 椀猀 最漀漀搀 瀀爀愀挀琀椀挀攀Ⰰ 愀渀搀 眀攀 猀栀漀甀氀搀 氀攀愀瘀攀 琀栀攀 ⸀洀搀昀 昀椀氀攀 昀漀爀 琀栀攀 搀椀挀琀椀漀渀愀爀礀⸀㰀戀爀㸀ഀഀ
    ਍䄀氀氀 礀漀甀 渀攀攀搀 琀漀 搀漀 椀猀Ⰰ 椀猀 琀漀 挀爀攀愀琀攀 愀 昀漀氀搀攀爀 ∀挀㨀尀洀猀猀焀氀尀搀愀琀愀∀ 漀渀 礀漀甀爀 琀攀猀琀猀礀猀琀攀洀⸀㰀戀爀㸀ഀഀ Next, using Management Studio, logon to SQL Server as sa or as an Administrator, and run the following script:
    ਍㰀戀爀㸀ഀഀ ਍ഀഀ ਍ഀഀ -- 1. Create the database:
    ਍㰀戀爀㸀ഀഀ create database SALES
    ਍漀渀 倀刀䤀䴀䄀刀夀㰀戀爀㸀ഀഀ (
    ਍渀愀洀攀㴀✀匀䄀䰀䔀匀✀Ⰰ㰀戀爀㸀ഀഀ filename='c:\mssql\data\SALES.mdf',
    ਍猀椀稀攀㴀㐀 䴀䈀Ⰰ㰀戀爀㸀ഀഀ filegrowth= 10MB,
    ਍洀愀砀猀椀稀攀㴀 ㄀  䴀䈀㰀戀爀㸀ഀഀ ),
    ਍䘀䤀䰀䔀䜀刀伀唀倀 匀䄀䰀䔀匀䐀䄀吀䄀 ㄀㰀戀爀㸀ഀഀ (
    ਍渀愀洀攀㴀✀匀䄀䰀䔀匀开䐀䄀吀䄀开 ㄀✀Ⰰ㰀戀爀㸀ഀഀ filename='c:\mssql\data\SALES_DATA_01.ndf',
    ਍猀椀稀攀㴀 㐀 䴀䈀Ⰰ㰀戀爀㸀ഀഀ filegrowth= 10MB,
    ਍洀愀砀猀椀稀攀㴀 ㄀  䴀䈀㰀戀爀㸀ഀഀ ),
    ਍䘀䤀䰀䔀䜀刀伀唀倀 匀䄀䰀䔀匀䤀一䐀䔀堀 ㄀㰀戀爀㸀ഀഀ (
    ਍渀愀洀攀㴀✀匀䄀䰀䔀匀开䤀一䐀䔀堀开 ㄀✀Ⰰ㰀戀爀㸀ഀഀ filename='c:\mssql\data\SALES_INDEX_01.ndf',
    ਍猀椀稀攀㴀 㐀 䴀䈀Ⰰ㰀戀爀㸀ഀഀ filegrowth= 10MB,
    ਍洀愀砀猀椀稀攀㴀 ㄀  䴀䈀㰀戀爀㸀ഀഀ )
    ਍䰀伀䜀 伀一㰀戀爀㸀ഀഀ (
    ਍渀愀洀攀㴀✀匀䄀䰀䔀匀开䰀伀䜀开  ㄀✀Ⰰ㰀戀爀㸀ഀഀ filename='c:\mssql\data\SALES_LOG_001.ldf',
    ਍猀椀稀攀㴀 㐀 䴀䈀Ⰰ㰀戀爀㸀ഀഀ filegrowth= 10MB,
    ਍洀愀砀猀椀稀攀㴀 ㄀  䴀䈀㰀戀爀㸀ഀഀ )
    ਍㰀戀爀㸀ഀഀ ALTER DATABASE SALES
    ਍䴀伀䐀䤀䘀夀 䘀䤀䰀䔀䜀刀伀唀倀 匀䄀䰀䔀匀䐀䄀吀䄀 ㄀ 䐀䔀䘀䄀唀䰀吀㰀戀爀㸀ഀഀ GO
    ਍㰀戀爀㸀ഀഀ USE SALES
    ਍䜀伀㰀戀爀㸀ഀഀ
    ਍㰀戀爀㸀ഀഀ -- Create a sample table:
    ਍㰀戀爀㸀ഀഀ CREATE TABLE dbo.EMPLOYEE
    ਍⠀㰀戀爀㸀ഀഀ EMPID INT NOT NULL,
    ਍䔀䴀倀一䄀䴀䔀   嘀䄀刀䌀䠀䄀刀⠀㈀ ⤀  一伀吀 一唀䰀䰀Ⰰ㰀戀爀㸀ഀഀ EMPSALARY DECIMAL(7,2),
    ਍䔀䴀倀倀䠀伀吀伀  嘀䄀刀䈀䤀一䄀刀夀⠀䴀䄀堀⤀㰀戀爀㸀ഀഀ ਍⤀㰀戀爀㸀ഀഀ ON [SALESDATA01]
    ਍㰀戀爀㸀ഀഀ -- Note the traditional datatypes like INT, VARCHAR, and DECIMAL,
    ਍ⴀⴀ 愀猀 眀攀氀氀 愀猀 琀栀攀 搀愀琀愀琀礀瀀攀 ∀嘀䄀刀䈀䤀一䄀刀夀∀ 昀漀爀 䈀䰀伀䈀猀⸀㰀戀爀㸀ഀഀ
    ਍㰀戀爀㸀ഀഀ -- Insert some characterbased data (no BLOBs yet) into the EMPLOYEE table:
    ਍㰀戀爀㸀ഀഀ insert into EMPLOYEE
    ਍⠀䔀䴀倀䤀䐀Ⰰ䔀䴀倀一䄀䴀䔀Ⰰ䔀䴀倀匀䄀䰀䄀刀夀⤀㰀戀爀㸀ഀഀ values
    ਍⠀㄀Ⰰ✀䠀愀爀爀礀✀Ⰰ㈀   ⸀㔀 ⤀㰀戀爀㸀ഀഀ
    ਍椀渀猀攀爀琀 椀渀琀漀 䔀䴀倀䰀伀夀䔀䔀㰀戀爀㸀ഀഀ (EMPID,EMPNAME,EMPSALARY)
    ਍瘀愀氀甀攀猀㰀戀爀㸀ഀഀ (2,'Nadia',3000.00)
    ਍㰀戀爀㸀ഀഀ insert into EMPLOYEE
    ਍⠀䔀䴀倀䤀䐀Ⰰ䔀䴀倀一䄀䴀䔀Ⰰ䔀䴀倀匀䄀䰀䄀刀夀⤀㰀戀爀㸀ഀഀ values
    ਍⠀㌀Ⰰ✀䄀氀戀攀爀琀✀Ⰰ㔀   ⸀  ⤀㰀戀爀㸀ഀഀ
    ਍䜀伀ഀഀ
    ਍ഀഀ
    ਍ഀഀ ਍ഀഀ So, we have created a database, and an EMPLOYEE table in that database. This table has three simple
    ਍挀栀愀爀愀挀琀攀爀ⴀ 漀爀 渀甀洀洀攀爀椀挀 挀漀氀甀洀渀猀Ⰰ 昀漀爀 猀琀漀爀椀渀最 搀愀琀愀 氀椀欀攀 ∀攀洀瀀氀漀礀攀攀 渀愀洀攀∀ ⠀䔀䴀倀一䄀䴀䔀⤀⸀㰀戀爀㸀ഀഀ Note however, that the last column is of type VARBINARY, which means that SQL Server is now prepared
    ਍琀漀 猀琀漀爀攀 ∀戀椀渀愀爀礀∀ 搀愀琀愀 ⠀氀椀欀攀 ⸀樀瀀最 漀爀 ⸀瀀搀昀 攀琀挀⸀⸀⤀ 椀渀 琀栀愀琀 挀漀氀甀洀渀⸀ 匀漀漀渀 眀攀 眀椀氀氀 猀攀攀 搀攀琀愀椀氀猀 漀渀 琀栀愀琀⸀㰀戀爀㸀ഀഀ
    ਍ഀഀ Then, we inserted 3 rows into that table, filling the first 3 columns, leaving the EMPPHOTO to be 'null' for now.
    ਍伀戀瘀椀漀甀猀氀礀Ⰰ 琀栀攀 䔀䴀倀倀䠀伀吀伀 挀漀氀甀洀渀 椀猀 猀甀瀀瀀漀猀攀搀 琀漀 猀琀漀爀攀 愀 瀀栀漀琀漀 ⠀愀 戀氀漀戀⤀ 漀昀 愀渀 䔀洀瀀氀漀礀攀攀⸀㰀戀爀㸀ഀഀ
    ਍㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀爀漀眀渀∀㸀ഀഀ Note:
    ਍㰀戀爀㸀ഀഀ in older SQL Server versions, binary data could be stored using the "image" datatype.
    ਍䄀氀琀栀漀甀最栀 琀栀椀猀 搀愀琀愀琀礀瀀攀 椀猀 猀琀椀氀氀 愀瘀愀椀氀愀戀氀攀Ⰰ 琀栀攀 ∀瘀愀爀戀椀渀愀爀礀⠀⤀∀ 漀爀 ∀瘀愀爀戀椀渀愀爀礀⠀洀愀砀⤀∀ 搀愀琀愀琀礀瀀攀猀 猀栀漀甀氀搀 戀攀 甀猀攀搀 昀漀爀 猀琀漀爀椀渀最 戀氀漀戀猀⸀㰀戀爀㸀ഀഀ First, "image" might get depreciated (it is, but it's still around), and varbinary is much better in
    ਍猀挀攀渀愀爀椀漀猀 眀栀攀爀攀 猀瀀愀挀攀 洀甀猀琀 戀攀 爀攀挀氀愀椀洀攀搀 椀昀 戀氀漀戀猀 愀爀攀 搀攀氀攀琀攀搀 漀爀 甀瀀搀愀琀攀搀⸀ 吀栀攀 瘀愀爀戀椀渀愀爀礀Ⰰ 椀猀 椀渀搀攀攀搀 漀昀㰀戀爀㸀ഀഀ variable length.
    ਍㰀戀爀㸀ഀഀ ਍㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀氀愀挀欀∀㸀ഀഀ ਍䰀攀琀✀猀 昀椀渀搀 漀甀琀 栀漀眀 琀栀攀 琀愀戀氀攀 椀猀 瀀栀礀猀椀挀愀氀氀礀 猀琀漀爀攀搀⸀㰀戀爀㸀ഀഀ
    ਍䤀昀 礀漀甀 挀爀攀愀琀攀搀 琀栀攀 搀愀琀愀戀愀猀攀 攀砀愀挀琀氀礀 愀猀 猀栀漀眀渀 椀渀 琀栀攀 猀挀爀椀瀀琀 愀戀漀瘀攀Ⰰ 琀栀攀渀 䤀 愀洀 猀甀爀攀 琀栀愀琀 漀甀爀 琀愀戀氀攀 椀猀 ∀瀀愀最攀 渀漀 㠀∀㰀戀爀㸀ഀഀ in the file 'c:\mssql\data\SALES_DATA_01.ndf'.
    ਍㰀戀爀㸀ഀഀ This is so because the first couple of pages of any datafile, are for administrative purposes (for SQL itself),
    ਍氀椀欀攀 琀栀攀 昀椀氀攀栀攀愀搀攀爀 ⠀瀀愀最攀  ⤀Ⰰ 琀栀攀 ∀倀愀最攀 䘀爀攀攀 匀瀀愀挀攀 ⠀倀匀䘀⤀ 瀀愀最攀∀ ⠀瀀愀最攀 ㄀⤀ 攀琀挀⸀⸀㰀戀爀㸀ഀഀ And, when the database was created, we told SQL Server that the filegroup "SALESDATA01" (consisting of 'c:\mssql\data\SALES_DATA_01.ndf')
    ਍琀漀 戀攀 琀栀攀 䐀䔀䘀䄀唀䰀吀 昀椀氀攀最爀漀甀瀀 昀漀爀 渀攀眀 漀戀樀攀挀琀猀⸀㰀戀爀㸀ഀഀ
    ਍䤀昀 礀漀甀 搀椀搀 渀漀琀 甀猀攀搀 琀栀攀 猀挀爀椀瀀琀Ⰰ 漀爀 甀猀攀搀 愀渀 攀砀椀猀琀椀渀最 吀攀猀琀 搀愀琀愀戀愀猀攀Ⰰ 琀栀攀 䔀䴀倀䰀伀夀䔀䔀 琀愀戀氀攀 椀猀 漀渀 搀椀昀昀攀爀攀渀琀 瀀愀最攀猀⸀㰀戀爀㸀ഀഀ Anyway, if that is true, you can still follow the next "experiment":
    ਍㰀戀爀㸀ഀഀ We are going to use the DBCC PAGE command to dump page contents. Just follow along...
    ਍㰀戀爀㸀ഀഀ ਍䤀渀 漀爀搀攀爀 琀漀 最攀琀 ∀昀甀氀氀 漀甀琀瀀甀琀∀ 昀爀漀洀 琀栀攀 䐀䈀䌀䌀 倀䄀䜀䔀 挀漀洀洀愀渀搀Ⰰ 氀攀琀✀猀 昀椀爀猀琀 琀攀氀氀 匀儀䰀 匀攀爀瘀攀爀 琀漀 搀漀 猀漀⸀㰀戀爀㸀ഀഀ
    ਍ഀഀ ਍ഀഀ DBCC TRACEON (3604)
    ਍䜀伀㰀戀爀㸀ഀഀ
    ਍ഀഀ ਍ഀഀ The DBCC PAGE() statement, uses some parameters. These parameters are nothing else than pure logical,
    ਍猀椀渀挀攀 琀栀攀 瀀愀爀愀洀攀琀攀爀猀 樀甀猀琀 琀攀氀氀 匀儀䰀 匀攀爀瘀攀爀 琀栀攀 挀漀洀瀀氀攀琀攀 愀搀搀爀攀猀猀 漀昀 琀栀攀 瀀愀最攀㨀 琀栀愀琀 椀猀Ⰰ 㰀䤀㸀眀栀椀挀栀 搀愀琀愀戀愀猀攀Ⰰ 琀栀攀 昀椀氀攀 椀搀 椀渀 琀栀愀琀 搀愀琀愀戀愀猀攀Ⰰ㰀戀爀㸀ഀഀ the page number in that file, and output mode (printoption).
    ਍匀漀Ⰰ 椀琀✀猀 氀椀欀攀 琀栀椀猀㨀㰀戀爀㸀ഀഀ
    ਍㰀昀漀渀琀 昀愀挀攀㴀∀挀漀甀爀椀攀爀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀氀甀攀∀㸀ഀഀ DBCC PAGE (databasename, file id, page no, modus)
    ਍㰀戀爀㸀ഀഀ ਍一漀眀Ⰰ 眀攀 愀氀爀攀愀搀礀 欀渀漀眀 琀栀攀 搀愀琀愀戀愀猀攀 渀愀洀攀Ⰰ 琀栀攀 瀀愀最攀 渀甀洀戀攀爀Ⰰ 愀渀搀 琀栀攀 洀漀搀甀猀 眀攀 眀愀渀琀 ⠀㌀ 琀漀 氀攀琀 椀琀 戀攀 ∀瘀攀爀戀漀猀攀∀⤀⸀㰀戀爀㸀ഀഀ
    ਍匀漀Ⰰ 洀愀礀戀攀 眀攀 愀爀攀 渀漀琀 猀甀爀攀 愀戀漀甀琀 琀栀攀 昀椀氀攀开椀搀 眀栀攀爀攀 琀栀攀 瀀愀最攀 椀猀 猀琀漀爀攀搀 漀渀⸀ 圀攀氀氀Ⰰ 氀攀琀✀猀 猀椀洀瀀氀礀 琀愀欀攀 愀 氀漀漀欀㰀戀爀㸀ഀഀ in the systemview "sysfiles".
    ਍㰀戀爀㸀ഀഀ ਍唀匀䔀 匀䄀䰀䔀匀㰀戀爀㸀ഀഀ GO
    ਍㰀戀爀㸀ഀഀ ਍猀攀氀攀挀琀 昀椀氀攀椀搀Ⰰ 昀椀氀攀渀愀洀攀 昀爀漀洀 猀礀猀昀椀氀攀猀㰀戀爀㸀ഀഀ ਍㰀戀爀㸀ഀഀ fileid filename
    ਍㰀戀爀㸀 ഀഀ 1 c:\mssql\data\SALES.mdf
    ਍㈀      挀㨀尀洀猀猀焀氀尀搀愀琀愀尀匀䄀䰀䔀匀开䰀伀䜀开  ㄀⸀氀搀昀㰀戀爀㸀 ഀഀ 3 c:\mssql\data\SALES_DATA_01.ndf
    ਍㐀      挀㨀尀洀猀猀焀氀尀搀愀琀愀尀匀䄀䰀䔀匀开䤀一䐀䔀堀开 ㄀⸀渀搀昀㰀戀爀㸀 ഀഀ
    ਍㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀氀愀挀欀∀㸀ഀഀ Since we know that the EMPLOYEE table is stored on the default filegroup, which consists of the
    ਍挀㨀尀洀猀猀焀氀尀搀愀琀愀尀匀䄀䰀䔀匀开䐀䄀吀䄀开 ㄀⸀渀搀昀 昀椀氀攀Ⰰ 眀攀 渀漀眀 欀渀漀眀 琀栀愀琀 琀栀攀 昀椀氀攀 椀搀㴀㌀⸀ 㰀戀爀㸀ഀഀ
    ਍吀栀攀 眀愀礀 洀漀猀琀 攀渀琀爀椀攀猀 椀渀 氀漀最猀 琀攀氀氀 礀漀甀 愀戀漀甀琀 瀀愀最攀猀Ⰰ 椀猀 氀椀欀攀 琀栀椀猀 攀砀愀洀瀀氀攀㨀 ∀㌀㨀㔀㔀∀Ⰰ 洀攀愀渀椀渀最㰀戀爀㸀ഀഀ page 55 in file 3.
    ਍㰀戀爀㸀ഀഀ Now, lets dump the page:
    ਍㰀戀爀㸀ഀഀ ਍ഀഀ DBCC PAGE('sales',3,8,3)
    ਍㰀戀爀㸀ഀഀ output: ਍㰀戀爀㸀ഀഀ ...
    ਍猀漀洀攀 漀甀琀瀀甀琀 猀欀椀瀀瀀攀搀㰀戀爀㸀ഀഀ ...
    ਍㰀䈀㸀䔀䴀倀䤀䐀 㴀 ㌀㰀⼀䈀㸀                            㰀戀爀㸀 ഀഀ Slot 2 Column 2 Offset 0x14 Length 6 Length (physical) 6
    ਍㰀䈀㸀䔀䴀倀一䄀䴀䔀 㴀 䄀氀戀攀爀琀㰀⼀䈀㸀                      㰀戀爀㸀 ഀഀ Slot 2 Column 3 Offset 0x8 Length 5 Length (physical) 5
    ਍㰀䈀㸀䔀䴀倀匀䄀䰀䄀刀夀 㴀 㔀   ⸀  㰀⼀䈀㸀                   㰀戀爀㸀 ഀഀ Slot 2 Column 4 Offset 0x0 Length 0 Length (physical) 0
    ਍㰀䈀㸀䔀䴀倀倀䠀伀吀伀 㴀 嬀一唀䰀䰀崀 㰀⼀䈀㸀㰀戀爀㸀 ഀഀ
    ਍㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀氀愀挀欀∀㸀ഀഀ Above, much output was skipped. Here, we see all fields of the third row.
    ਍㰀戀爀㸀ഀഀ Since our table is still extremely small (it only has 3 rows), all of it "sits" in one page.
    ਍䰀攀琀✀猀 搀漀甀戀氀攀挀栀攀挀欀 琀栀愀琀 眀椀琀栀 琀栀攀 昀漀氀氀漀眀椀渀最⸀㰀戀爀㸀ഀഀ
    ਍㰀昀漀渀琀 昀愀挀攀㴀∀挀漀甀爀椀攀爀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀氀甀攀∀㸀ഀഀ DBCC SHOWCONTIG(EMPLOYEE)
    ਍㰀戀爀㸀ഀഀ DBCC SHOWCONTIG scanning 'EMPLOYEE' table...
    ਍吀愀戀氀攀㨀 ✀䔀䴀倀䰀伀夀䔀䔀✀ ⠀㈀㄀ 㔀 㔀㠀㔀㌀㔀⤀㬀 椀渀搀攀砀 䤀䐀㨀  Ⰰ 搀愀琀愀戀愀猀攀 䤀䐀㨀 㠀㰀戀爀㸀ഀഀ TABLE level scan performed.
    ਍㰀䈀㸀ⴀ 倀愀最攀猀 匀挀愀渀渀攀搀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀㨀 ㄀㰀⼀䈀㸀㰀戀爀㸀ഀഀ - Extents Scanned..............................: 1
    ਍ⴀ 䔀砀琀攀渀琀 匀眀椀琀挀栀攀猀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀㨀  㰀戀爀㸀ഀഀ - Avg. Pages per Extent........................: 1.0
    ਍ⴀ 匀挀愀渀 䐀攀渀猀椀琀礀 嬀䈀攀猀琀 䌀漀甀渀琀㨀䄀挀琀甀愀氀 䌀漀甀渀琀崀⸀⸀⸀⸀⸀⸀⸀㨀 ㄀  ⸀  ─ 嬀㄀㨀㄀崀㰀戀爀㸀ഀഀ - Extent Scan Fragmentation ...................: 0.00%
    ਍ⴀ 䄀瘀最⸀ 䈀礀琀攀猀 䘀爀攀攀 瀀攀爀 倀愀最攀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀㨀 㠀 ㄀㐀⸀ 㰀戀爀㸀ഀഀ - Avg. Page Density (full).....................: 0.99%
    ਍㰀戀爀㸀ഀഀ ਍䄀猀 礀漀甀 挀愀渀 猀攀攀 昀爀漀洀 琀栀攀 漀甀琀瀀甀琀 愀戀漀瘀攀Ⰰ 漀渀氀礀 漀渀攀 瀀愀最攀 渀攀攀搀攀搀 琀漀 戀攀 猀挀愀渀渀攀搀Ⰰ 猀漀 琀栀攀 䔀䴀倀䰀伀夀䔀䔀 琀愀戀氀攀㰀戀爀㸀ഀഀ just sits completely in page 8 of file c:\mssql\data\SALES_DATA_01.ndf.
    ਍㰀戀爀㸀ഀഀ
    ਍㰀栀㌀㸀㄀⸀㈀ 䄀搀搀椀渀最 愀 戀氀漀戀 椀渀 琀栀攀 䔀䴀倀䰀伀夀䔀䔀 琀愀戀氀攀⸀㰀⼀栀㈀㸀ഀഀ ਍唀瀀 琀漀 琀栀椀猀 瀀漀椀渀琀Ⰰ 眀攀 漀渀氀礀 栀愀瘀攀 ∀猀椀洀瀀氀攀∀ 搀愀琀愀 椀渀 漀甀爀 䔀䴀倀䰀伀夀䔀䔀 琀愀戀氀攀 氀椀欀攀 瘀愀爀挀栀愀爀Ⰰ 渀甀洀洀攀爀椀挀Ⰰ㰀戀爀㸀ഀഀ but no blob yet.
    ਍㰀戀爀㸀ഀഀ ਍匀䔀䰀䔀䌀吀 ⨀ 䘀刀伀䴀 䔀䴀倀䰀伀夀䔀䔀㰀戀爀㸀ഀഀ
    ਍䔀䴀倀䤀䐀⸀⸀⸀䔀䴀倀一䄀䴀䔀⸀⸀⸀䔀䴀倀匀䄀䰀䄀刀夀⸀⸀䔀䴀倀倀䠀伀吀伀㰀戀爀㸀ഀഀ 1.......Harry.....2000.50....NULL
    ਍㈀⸀⸀⸀⸀⸀⸀⸀一愀搀椀愀⸀⸀⸀⸀⸀㌀   ⸀  ⸀⸀⸀⸀一唀䰀䰀㰀戀爀㸀ഀഀ 3.......Albert....5000.00....NULL
    ਍㰀戀爀㸀ഀഀ ਍㰀戀爀㸀ഀഀ Let's update the third record, and store a binary file in the EMPPHOTO column, that is, we will place
    ਍愀 瀀栀漀琀漀 漀昀 䄀氀戀攀爀琀 ⠀礀甀欀℀⤀ 椀渀琀漀 琀栀攀 䔀䴀倀䰀伀夀䔀䔀 琀愀戀氀攀Ⰰ 愀渀搀 琀栀攀渀 猀攀攀 眀栀愀琀 栀愀猀 挀栀愀渀最攀搀⸀㰀戀爀㸀ഀഀ
    ਍吀栀攀爀攀 愀爀攀 洀愀渀礀 昀甀渀挀琀椀漀渀猀 椀渀 匀儀䰀 匀攀爀瘀攀爀Ⰰ 昀漀爀 椀洀瀀漀爀琀⼀攀砀瀀漀爀琀 漀昀 搀愀琀愀⸀ 吀栀攀 伀倀䔀一刀伀圀匀䔀吀⠀⤀ 昀甀渀挀琀椀漀渀 挀愀渀 愀氀猀漀㰀戀爀㸀ഀഀ be used to load a blob into a table. So let's try that. Suppose in C:\TEMP, we have the photo "albert.jpg".
    ਍㰀戀爀㸀ഀഀ TSQL statement for adding a BLOB using OPENROWSET():
    ਍㰀戀爀㸀ഀഀ ਍㰀䈀㸀ഀഀ UPDATE EMPLOYEE
    ਍匀䔀吀 䔀䴀倀倀䠀伀吀伀 㴀 㰀戀爀㸀ഀഀ (SELECT * FROM OPENROWSET (BULK 'C:\TEMP\albert.jpg', SINGLE_BLOB) a)
    ਍圀䠀䔀刀䔀 䔀䴀倀䤀䐀㴀㌀㰀戀爀㸀ഀഀ ਍㰀戀爀㸀ഀഀ ਍匀䔀䰀䔀䌀吀 ⨀ 䘀刀伀䴀 䔀䴀倀䰀伀夀䔀䔀㰀戀爀㸀ഀഀ
    ਍䔀䴀倀䤀䐀⸀⸀⸀䔀䴀倀一䄀䴀䔀⸀⸀⸀䔀䴀倀匀䄀䰀䄀刀夀⸀⸀䔀䴀倀倀䠀伀吀伀㰀戀爀㸀ഀഀ 1.......Harry.....2000.50....NULL
    ਍㈀⸀⸀⸀⸀⸀⸀⸀一愀搀椀愀⸀⸀⸀⸀⸀㌀   ⸀  ⸀⸀⸀⸀一唀䰀䰀㰀戀爀㸀ഀഀ 3.......Albert....5000.00....0xFFD8FFE000104A4649...
    ਍㰀戀爀㸀ഀഀ ਍㰀戀爀㸀ഀഀ Ok, we see a pointerlike field in the EMPPHOTO column where EMPID=3, but how is the blob (albert.jpg) stored?
    ਍㰀戀爀㸀ഀഀ
    ਍㰀栀㌀㸀㄀⸀㌀ 䄀渀愀氀礀猀椀猀 漀昀 琀栀攀 ⠀椀渀氀椀渀攀⤀ 戀氀漀戀 猀琀漀爀愀最攀⸀㰀⼀栀㈀㸀ഀഀ ਍ഀഀ We know that the EMPLOYEE table is stored in page 8. Now, there are some special pages in any database file,
    ਍愀琀 瘀愀爀椀漀甀猀 氀漀挀愀琀椀漀渀猀Ⰰ 戀甀琀 椀琀✀猀 爀攀愀猀漀渀愀戀氀攀 琀漀 攀砀瀀攀挀琀 琀栀愀琀 匀儀䰀 匀攀爀瘀攀爀 眀椀氀氀 渀漀琀 猀琀漀爀攀 琀栀攀 戀氀漀戀Ⰰ 猀愀礀Ⰰ 猀琀愀爀琀椀渀最 愀琀 瀀愀最攀 ㄀㈀㤀㠀Ⰰ㰀戀爀㸀ഀഀ or page 633 or something. No, it should be quite"close", so lets play with DBCC PAGE('sales',3,x,3), where
    ਍眀攀 琀愀欀攀 愀 氀漀漀欀 愀琀 瀀愀最攀 渀漀 㠀Ⰰ㤀Ⰰ㄀ Ⰰ㄀㄀ 愀渀搀 愀 昀攀眀 漀琀栀攀爀 瀀愀最攀猀 ∀渀攀愀爀戀礀∀⸀㰀戀爀㸀ഀഀ
    ਍一漀眀 椀琀猀 最攀琀琀椀渀最 椀渀琀攀爀攀猀琀椀渀最⸀⸀⸀⸀㰀戀爀㸀ഀഀ
    ਍䘀椀爀猀琀 氀攀琀 氀漀漀欀 愀琀 瀀愀最攀 㠀 愀最愀椀渀Ⰰ 愀琀 琀栀攀 搀愀琀愀 爀攀氀愀琀攀搀 琀漀 䔀䴀倀䤀䐀㴀㌀ ⠀䄀氀戀攀爀琀⤀⸀㰀戀爀㸀ഀഀ
    ਍㰀昀漀渀琀 昀愀挀攀㴀∀挀漀甀爀椀攀爀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀氀甀攀∀㸀ഀഀ
    ਍䔀䴀倀䤀䐀 㴀 ㌀   㰀戀爀㸀                         ഀഀ Slot 2 Column 2 Offset 0x16 Length 6 Length (physical) 6
    ਍䔀䴀倀一䄀䴀䔀 㴀 䄀氀戀攀爀琀   㰀戀爀㸀                  ഀഀ Slot 2 Column 3 Offset 0x8 Length 5 Length (physical) 5
    ਍䔀䴀倀匀䄀䰀䄀刀夀 㴀 㔀   ⸀       㰀戀爀㸀             ഀഀ EMPPHOTO = [BLOB Inline Root] Slot 2 Column 4 Offset 0x1c Length 24 Length (physical) 24 (more stuff..)
    ਍㰀戀爀㸀ഀഀ ਍䤀渀琀攀爀攀猀琀椀渀最⸀ 䄀琀 琀栀攀 䔀䴀倀倀䠀伀吀伀 挀漀氀甀洀渀 椀琀 渀漀眀 猀愀礀猀 ∀嬀䈀䰀伀䈀 䤀渀氀椀渀攀 刀漀漀琀崀∀Ⰰ 洀攀愀渀椀渀最 琀栀愀琀 匀儀䰀 匀攀爀瘀攀爀 猀琀漀爀攀搀㰀戀爀㸀ഀഀ the binary file inline, that is, really inside the database.
    ਍一漀眀 氀攀琀猀 氀漀漀欀 愀琀 猀漀洀攀 漀琀栀攀爀 渀攀愀爀戀礀 瀀愀最攀猀⸀㰀戀爀㸀ഀഀ
    ਍㰀䈀㸀䄀琀 瀀愀最攀 渀漀 ㄀㈀Ⰰ 䤀 栀愀瘀攀 愀 ∀栀椀琀∀℀ 吀愀欀攀 愀 氀漀漀欀 愀琀 琀栀椀猀㨀㰀⼀䈀㸀㰀戀爀㸀ഀഀ
    ਍㰀昀漀渀琀 昀愀挀攀㴀∀挀漀甀爀椀攀爀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀氀甀攀∀㸀ഀഀ ਍䐀䈀䌀䌀 倀䄀䜀䔀⠀✀猀愀氀攀猀✀Ⰰ㌀Ⰰ㰀䈀㸀㄀㈀㰀⼀䈀㸀Ⰰ㌀⤀㰀戀爀㸀ഀഀ
    ਍瀀愀爀琀椀愀氀 漀甀琀瀀甀琀⸀⸀㰀戀爀㸀ഀഀ
    ਍䈀氀漀戀 䤀搀㨀 㤀㈀㤀 ㌀㠀㌀㌀㘀 䰀攀瘀攀氀㨀   䴀愀砀䰀椀渀欀猀㨀 㔀 ㄀ 䌀甀爀䰀椀渀欀猀㨀 㔀㘀ഀ
    ਍䌀栀椀氀搀   愀琀 倀愀最攀 ⠀㌀㨀㄀㘀⤀ 匀氀漀琀   匀椀稀攀㨀 㠀 㐀  伀昀昀猀攀琀㨀 㠀 㐀 ഀ
    ਍䌀栀椀氀搀 ㄀ 愀琀 倀愀最攀 ⠀㌀㨀㄀㜀⤀ 匀氀漀琀   匀椀稀攀㨀 㠀 㐀  伀昀昀猀攀琀㨀 ㄀㘀 㠀 ഀ
    ਍䌀栀椀氀搀 ㈀ 愀琀 倀愀最攀 ⠀㌀㨀㄀㠀⤀ 匀氀漀琀   匀椀稀攀㨀 㠀 㐀  伀昀昀猀攀琀㨀 ㈀㐀㄀㈀ ഀ
    ਍䌀栀椀氀搀 ㌀ 愀琀 倀愀最攀 ⠀㌀㨀㄀㤀⤀ 匀氀漀琀   匀椀稀攀㨀 㠀 㐀  伀昀昀猀攀琀㨀 ㌀㈀㄀㘀 ഀ
    ਍䌀栀椀氀搀 㐀 愀琀 倀愀最攀 ⠀㌀㨀㈀ ⤀ 匀氀漀琀   匀椀稀攀㨀 㠀 㐀  伀昀昀猀攀琀㨀 㐀 ㈀  ഀ
    ਍䌀栀椀氀搀 㔀 愀琀 倀愀最攀 ⠀㌀㨀㈀㄀⤀ 匀氀漀琀   匀椀稀攀㨀 㠀 㐀  伀昀昀猀攀琀㨀 㐀㠀㈀㐀 ഀ
    ਍⸀⸀㰀戀爀㸀ഀഀ (some entries omitted)
    ਍⸀⸀㰀戀爀㸀ऀഀഀ Child 45 at Page (3:61) Slot 0 Size: 8040 Offset: 369840਍ഀ
    ਍䌀栀椀氀搀 㐀㘀 愀琀 倀愀最攀 ⠀㌀㨀㘀㈀⤀ 匀氀漀琀   匀椀稀攀㨀 㠀 㐀  伀昀昀猀攀琀㨀 ㌀㜀㜀㠀㠀 ഀ ਍㰀戀爀㸀ഀഀ Child 47 at Page (3:63) Slot 0 Size: 8040 Offset: 385920਍ഀ
    ਍䌀栀椀氀搀 㐀㠀 愀琀 倀愀最攀 ⠀㌀㨀㄀㌀⤀ 匀氀漀琀   匀椀稀攀㨀 㠀 㐀  伀昀昀猀攀琀㨀 ㌀㤀㌀㤀㘀 ഀ ਍㰀戀爀㸀ഀഀ Child 49 at Page (3:14) Slot 0 Size: 8040 Offset: 402000਍ഀ
    ਍䌀栀椀氀搀 㔀  愀琀 倀愀最攀 ⠀㌀㨀㄀㔀⤀ 匀氀漀琀   匀椀稀攀㨀 㠀 㐀  伀昀昀猀攀琀㨀 㐀㄀  㐀 ഀ ਍㰀戀爀㸀ഀഀ Child 51 at Page (3:64) Slot 0 Size: 8040 Offset: 418080਍ഀ
    ਍䌀栀椀氀搀 㔀㈀ 愀琀 倀愀最攀 ⠀㌀㨀㘀㔀⤀ 匀氀漀琀   匀椀稀攀㨀 㠀 㐀  伀昀昀猀攀琀㨀 㐀㈀㘀㄀㈀ ഀ ਍㰀戀爀㸀ഀഀ Child 53 at Page (3:66) Slot 0 Size: 8040 Offset: 434160਍ഀ
    ਍䌀栀椀氀搀 㔀㐀 愀琀 倀愀最攀 ⠀㌀㨀㜀㈀⤀ 匀氀漀琀   匀椀稀攀㨀 㠀 㐀  伀昀昀猀攀琀㨀 㐀㐀㈀㈀  ഀ ਍㰀戀爀㸀ഀഀ Child 55 at Page (3:10) Slot 0 Size: 2361 Offset: 444561਍ഀ
    ਍㰀戀爀㸀ഀഀ ਍㰀戀爀㸀ഀഀ You see that? It clearly shows that the pages from page 16 all the way up to page 66, are dedicated
    ਍昀漀爀 猀琀漀爀椀渀最 琀栀攀 戀氀漀戀 搀愀琀愀 ⠀琀栀攀 ⸀樀瀀最 昀椀氀攀⤀⸀㰀戀爀㸀ഀഀ Then, from the output, you can see that pages 3:13, 3:14, and 3:15 are used too, as well as page 3:72.
    ਍䄀挀琀甀愀氀氀礀Ⰰ 瀀愀最攀 ㄀  椀猀 琀栀攀 ∀琀愀椀氀∀ 漀昀 琀栀攀 戀氀漀戀 ⠀漀渀氀礀 ㈀㌀㘀㄀ 戀礀琀攀猀⤀Ⰰ 戀甀琀 愀戀漀瘀攀 椀琀 椀猀 猀栀漀眀渀 挀氀攀愀爀氀礀 琀栀愀琀㰀戀爀㸀ഀഀ pages 16-66, and pages 13-15, and pages 10 and 72, are used for the blob.
    ਍㰀戀爀㸀ഀഀ Evidently, page 12 is a bit "apart" and it looks like the "directory" for the blob.
    ਍䄀挀琀甀愀氀氀礀Ⰰ 椀琀✀猀 琀栀攀 爀漀漀琀ⴀ渀漀搀攀 ⠀瀀愀最攀⤀ 愀渀搀 椀琀 挀漀渀琀愀椀渀猀 愀氀氀 椀渀昀漀爀洀愀琀椀漀渀 漀渀 眀栀攀爀攀 琀漀 昀椀渀搀 琀栀攀 戀氀漀戀 挀栀甀渀欀猀⸀㰀戀爀㸀ഀഀ
    ਍䤀昀 礀漀甀 眀漀甀氀搀 搀甀洀瀀Ⰰ 昀漀爀 攀砀愀洀瀀氀攀Ⰰ 瀀愀最攀 ㌀㨀㘀㘀 眀椀琀栀 䐀䈀䌀䌀 倀䄀䜀䔀Ⰰ 礀漀甀 眀漀甀氀搀 椀渀搀攀攀搀 猀攀攀 㠀 㐀  戀礀琀攀猀 漀昀 戀椀渀愀爀礀 搀愀琀愀 漀昀 琀栀攀 瀀栀漀琀漀⸀㰀戀爀㸀ഀഀ
    ਍ഀഀ Except page 10, each page stores exactly 8040 byte chunks of that photo.
    ਍䤀渀搀攀攀搀Ⰰ 匀儀䰀 匀攀爀瘀攀爀 ∀爀攀琀甀爀渀攀搀∀ 琀漀 瀀愀最攀 ㄀  ⠀愀昀琀攀爀 昀椀氀氀椀渀最 愀氀氀 琀栀攀 眀愀礀 甀瀀 琀漀 瀀愀最攀 㜀㈀⤀ 琀漀 戀攀 挀漀渀猀攀爀瘀愀琀椀瘀攀 眀椀琀栀 瀀愀最攀猀 ⠀愀渀搀 攀砀琀攀渀搀猀⤀⸀㰀戀爀㸀ഀഀ
    ਍匀漀Ⰰ 琀栀攀 氀愀猀琀 戀礀琀攀猀 漀昀 琀栀攀 戀氀漀戀 愀爀攀 猀琀漀爀攀搀 椀渀 瀀愀最攀 ㄀ ⸀ 䈀甀琀 琀栀愀琀 搀漀攀猀 渀漀琀 洀愀琀琀攀爀㨀 琀栀攀 搀椀爀攀挀琀漀爀礀 ⠀猀漀 琀漀 猀瀀攀愀欀⤀㰀戀爀㸀ഀഀ in page 12, tells SQL Server exactly on which pages all chuncks are located, and which file offset is associated,
    ਍猀漀 愀渀礀 愀瀀瀀氀椀挀愀琀椀漀渀 挀愀渀 最攀琀 愀 瀀攀爀昀攀挀琀氀礀 爀攀戀甀椀氀搀 瀀椀挀琀甀爀攀 椀昀 爀攀焀甀攀猀琀攀搀⸀㰀戀爀㸀ഀഀ ਍㰀戀爀㸀ഀഀ Fig 1. Simplified representation of the pages involved in our example.
    ਍㰀戀爀㸀ഀഀ ਍㰀戀爀㸀ഀഀ
    ਍䴀愀礀戀攀 昀椀最甀爀攀 ㄀ 椀猀 栀攀氀瀀昀甀氀氀 椀渀 甀渀搀攀爀猀琀愀渀搀椀渀最 漀甀爀 攀砀愀洀瀀氀攀⸀ 夀漀甀 猀攀攀 琀栀愀琀 漀甀爀 ⠀猀洀愀氀氀⤀ 䔀䴀倀䰀伀夀䔀䔀 琀愀戀氀攀 攀砀椀猀琀猀㰀戀爀㸀ഀഀ in page 8. But, we have loaded a blob, and the very first page of the blob is page 12. This is the root node
    ਍⠀漀爀 爀漀漀琀 瀀愀最攀⤀ 漀昀 琀栀攀 戀氀漀戀Ⰰ 挀漀渀琀愀椀渀椀渀最 琀栀攀 搀椀爀攀挀琀漀爀礀 ⠀猀漀 琀漀 猀瀀攀愀欀⤀ 眀栀椀挀栀 琀攀氀氀猀 匀儀䰀 匀攀爀瘀攀爀 㰀䤀㸀眀栀椀挀栀㰀⼀䤀㸀 瀀愀最攀 猀琀漀爀攀猀 㰀䤀㸀眀栀愀琀㰀⼀䤀㸀 戀氀漀戀 挀栀甀渀挀欀⸀㰀戀爀㸀ഀഀ In the figure, these are the "blue" pages.
    ਍㰀戀爀㸀ഀഀ Now, maybe you think the page distribution is a bit "random". It's not. We have not discussed "extents" yet,
    ਍戀甀琀 匀儀䰀 匀攀爀瘀攀爀 漀爀最愀渀椀稀攀猀 㰀䈀㸀挀漀氀氀攀挀琀椀漀渀猀 漀昀 㠀 瀀愀最攀猀 椀渀琀漀 攀砀琀攀渀琀猀㰀⼀䈀㸀 ⠀猀漀 攀愀挀栀 攀砀琀攀渀琀 挀漀渀猀椀猀琀 漀昀 㠀 挀漀渀琀椀最甀漀甀猀 瀀愀最攀猀⤀⸀㰀戀爀㸀ഀഀ Do you notice, from the "root node", that the actual blob data starts from page 16?. This is also the start
    ਍漀昀 琀栀攀 琀栀椀爀搀 攀砀琀攀渀琀 椀渀 琀栀攀 昀椀氀攀⸀ 匀漀 愀挀琀甀愀氀氀礀Ⰰ 椀琀 椀猀 瀀爀攀琀琀礀 挀氀攀愀渀⸀ 吀栀攀渀 匀儀䰀 匀攀爀瘀攀爀 猀琀愀爀琀猀 昀椀氀氀椀渀最 瀀愀最攀猀 愀猀 昀爀漀洀 瀀愀最攀 ㄀㘀㰀戀爀㸀ഀഀ as is neccessary. Only the last portion of the blob data, then is stored in the second extent, just done in order
    ਍渀漀琀 琀漀 眀愀猀琀攀 猀瀀愀挀攀⸀ 匀漀 琀栀攀 猀攀挀漀渀搀 攀砀琀攀渀琀Ⰰ 挀漀渀琀愀椀渀猀 愀 渀漀爀洀愀氀 爀攀最甀氀愀爀 琀愀戀氀攀 ⠀椀渀 瀀愀最攀 㠀⤀Ⰰ 愀渀搀 愀氀猀漀 猀漀洀攀 瀀愀最攀猀㰀戀爀㸀ഀഀ containing blob data.
    ਍㰀戀爀㸀ഀഀ Now, the file "albert.jpg" is 444,561 bytes in size.
    ਍㰀戀爀㸀ഀഀ How much "space" is then "spend" in SQL Server? Above you can see the answer:
    ਍㰀戀爀㸀ഀഀ (child 0 up to child 54) x 8040 + (the bytes in page 10) = 55 x 8040 + 2361 = 444,561 bytes.
    ਍㰀戀爀㸀ഀഀ So, from this, you might say that there is hardly any "overhead" in storing a blob, compared to the filesystem.
    ਍一漀琀 攀砀愀挀琀氀礀⸀ 䘀椀爀猀琀Ⰰ 愀 瀀愀最攀 椀猀 㠀㄀㤀㈀ 戀礀琀攀猀Ⰰ 愀渀搀 匀儀䰀 甀猀攀猀 㠀 㐀  戀礀琀攀猀 昀漀爀 猀琀漀爀椀渀最 戀氀漀戀 搀愀琀愀⸀㰀戀爀㸀ഀഀ But that's not really much overhead.
    ਍㰀戀爀㸀ഀഀ The point is, that, as we will see later, that if many blobs are stored, and over time some are deleted and updated
    ਍⠀甀猀椀渀最 琀栀攀 爀攀最甀氀愀爀 愀瀀瀀氀椀挀愀琀椀漀渀猀⤀Ⰰ 猀漀洀攀 ∀最愀瀀猀∀ 眀椀氀氀 愀爀椀猀攀Ⰰ 琀栀爀漀甀最栀漀甀琀 琀栀攀 ∀攀砀琀攀渀搀猀∀⸀㰀戀爀㸀ഀഀ Before discussing this, we need to know how SQL Server organizes it's pages for various purposes.
    ਍㰀戀爀㸀ഀഀ You can easily "play" this example by yourself. Just create a new database, and the EMPLOYEE table as shown above.
    ਍吀栀攀渀Ⰰ 樀甀猀琀 甀猀攀 愀 ∀⸀樀瀀最∀ 昀椀氀攀Ⰰ 氀椀欀攀 愀 瀀栀漀琀漀 漀爀 猀漀Ⰰ 漀昀 猀愀礀Ⰰ 愀 昀攀眀 栀甀渀搀爀攀搀猀 漀昀 䬀䈀 椀渀 猀椀稀攀⸀㰀戀爀㸀ഀഀ Next, load the blob into the table (as shown above) and play around a bit with DBCC PAGE().
    ਍㰀戀爀㸀ഀഀ
    ਍㰀戀爀㸀ഀഀ ਍㰀栀㈀㸀䌀栀愀瀀琀攀爀 ㈀⸀ 倀愀最攀猀Ⰰ 攀砀琀攀渀搀猀Ⰰ 愀渀搀 漀琀栀攀爀 猀琀爀甀挀琀甀爀攀猀⸀㰀⼀栀㈀㸀ഀഀ ਍ഀഀ

    2.1 Structure of a data page, and special pages.

    ਍ഀഀ A page is a sort of "atomic" structure in a SQL Server database file (except of the Transaction Log files).
    ਍䈀攀氀漀眀Ⰰ 礀漀甀 猀攀攀 愀 瘀攀爀礀 猀挀栀攀洀愀琀椀挀 爀攀瀀爀攀猀攀渀琀愀琀椀漀渀 漀昀 愀 䐀愀琀愀 瀀愀最攀Ⰰ 氀椀欀攀 甀猀攀搀 眀椀琀栀 琀愀戀氀攀猀⸀㰀戀爀㸀ഀഀ
    ਍㰀䈀㸀䘀椀最 ㈀⸀ 匀椀洀瀀氀椀昀椀攀搀 爀攀瀀爀攀猀攀渀琀愀琀椀漀渀 漀昀 愀 搀愀琀愀 瀀愀最攀⸀㰀⼀䈀㸀㰀戀爀㸀ഀഀ
    ਍㰀椀洀最 猀爀挀㴀∀猀焀氀猀攀爀瘀攀爀戀氀漀戀㄀⸀樀瀀最∀ 愀氀椀最渀㴀∀挀攀渀琀爀攀∀⼀㸀ഀഀ
    ਍㰀戀爀㸀ഀഀ The page header identifies the page, as to which "object id" it belongs, and some further housekeeping info.
    ਍䄀琀 琀栀攀 攀渀搀 漀昀 琀栀攀 瀀愀最攀Ⰰ 椀猀 琀栀攀 ∀爀漀眀 漀昀昀猀攀琀 琀愀戀氀攀∀⸀ 䤀琀 猀愀礀猀Ⰰ 瀀攀爀 爀漀眀Ⰰ 琀栀攀 搀椀猀琀愀渀挀攀 椀渀 戀礀琀攀猀 漀昀 琀栀漀猀攀 爀漀眀猀Ⰰ㰀戀爀㸀ഀഀ from the very start of the page. So, the start of any row can be found.
    ਍㰀戀爀㸀ഀഀ Now, in the figure, you see three example rows, and below that, there exists "free space".
    ਍䤀昀 琀栀攀爀攀 椀猀 爀漀漀洀 昀漀爀 渀攀眀 爀漀眀猀Ⰰ 琀栀攀礀 眀椀氀氀 猀椀洀瀀氀礀 戀攀 愀搀搀攀搀⸀ 一漀眀Ⰰ 椀昀 愀琀 愀 挀攀爀琀愀椀渀 洀漀洀攀渀琀Ⰰ 愀 渀攀眀 爀漀眀 搀漀攀猀 渀漀琀 ∀昀椀琀∀㰀戀爀㸀ഀഀ anymore, a "page split" will occur, and a whole new page will be allocated for this object, and the row
    ਍眀椀氀氀 戀攀 猀琀漀爀攀搀 椀渀 琀栀愀琀 渀攀眀氀礀 愀氀氀漀挀愀琀攀搀 瀀愀最攀 椀渀猀琀攀愀搀⸀㰀戀爀㸀ഀഀ
    ਍一漀琀攀㨀 猀漀洀攀琀椀洀攀猀 琀栀攀 琀攀爀洀 ∀瀀愀最攀 猀瀀氀椀琀∀ 椀猀 爀攀猀攀爀瘀攀搀 昀漀爀 愀 猀椀琀甀愀琀椀漀渀 眀栀攀爀攀 愀 瀀愀最攀Ⰰ 眀栀椀挀栀 眀愀猀 愀氀爀攀愀搀礀 ∀焀甀椀琀攀 昀甀氀氀∀Ⰰ㰀戀爀㸀ഀഀ and then some record just happened to be updated with data larger than the former data, resulting in the fact that
    ਍琀栀攀 爀攀挀漀爀搀猀 搀漀渀✀琀 ∀昀椀琀∀ 愀渀礀洀漀爀攀 椀渀 琀栀愀琀 瀀愀最攀⸀ 䤀渀 琀栀椀猀 挀愀猀攀Ⰰ 匀儀䰀 匀攀爀瘀攀爀 愀氀氀漀挀愀琀攀猀 愀 渀攀眀 瀀愀最攀 昀漀爀 琀栀攀 漀戀樀攀挀琀Ⰰ 愀渀搀㰀戀爀㸀ഀഀ moves record(s) as neccessary.
    ਍㰀戀爀㸀ഀഀ
    ਍匀漀Ⰰ 椀昀 礀漀甀 眀漀甀氀搀 樀甀猀琀 栀愀瘀攀 ∀栀攀愀瀀猀∀ 漀昀 瀀愀最攀猀Ⰰ 琀漀最攀琀栀攀爀 昀漀爀洀椀渀最 琀愀戀氀攀猀Ⰰ 椀琀 眀漀甀氀搀 戀攀 猀椀洀瀀氀攀 椀渀搀攀攀搀⸀㰀戀爀㸀ഀഀ But this is not how it is organized. We will se that in section 2.2
    ਍㰀戀爀㸀ഀഀ What types of pages do we have? The most important types are:
    ਍㰀戀爀㸀ഀഀ => System pages: only in the first extent, and a small number distributed throughout the file.
    ਍㰀戀爀㸀ഀഀ ਍ ഀഀ ਍ 㰀吀䐀㸀㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀㸀㰀䈀㸀倀匀䘀㨀 倀愀最攀 䘀爀攀攀 匀瀀愀挀攀 瀀愀最攀㰀⼀䈀㸀㰀⼀吀䐀㸀ഀഀ ਍㰀⼀吀刀㸀ഀഀ ਍ 㰀吀䐀㸀㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀㸀㰀䈀㸀䜀䄀䴀㨀 䜀氀漀戀愀氀 䄀氀氀漀挀愀琀椀漀渀 䴀愀瀀 愀渀搀 匀䜀䄀䴀 瀀愀最攀猀㰀⼀䈀㸀㰀⼀吀䐀㸀ഀഀ ਍㰀⼀吀刀㸀ഀഀ ਍ 㰀吀䐀㸀㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀㸀㰀䈀㸀䤀䄀䴀㨀 䤀渀搀攀砀 䄀氀氀漀挀愀琀椀漀渀 䴀愀瀀㰀⼀䈀㸀㰀⼀吀䐀㸀ഀഀ ਍㰀⼀吀刀㸀ഀഀ
    Information about page allocation and free space available on pages.
    Information about whether extents are allocated.
    Information about extents used by a clustered table or index per allocation unit.
    ਍㰀戀爀㸀ഀഀ => Special pages: A small number distributed throughout the file.
    ਍㰀戀爀㸀ഀഀ ਍ ഀഀ ਍ 㰀吀䐀㸀㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀㸀㰀䈀㸀䈀甀氀欀 䌀栀愀渀最攀搀 䴀愀瀀 瀀愀最攀猀㰀⼀䈀㸀㰀⼀吀䐀㸀ഀഀ ਍㰀吀刀㸀ഀഀ ਍ 㰀吀䐀㸀㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀㸀䤀渀昀漀爀洀愀琀椀漀渀 愀戀漀甀琀 攀砀琀攀渀琀猀 琀栀愀琀 栀愀瘀攀 挀栀愀渀最攀搀 猀椀渀挀攀 琀栀攀 氀愀猀琀 䈀䄀䌀䬀唀倀 䐀䄀吀䄀䈀䄀匀䔀㰀戀爀㸀ഀഀ or BACKUP DATABASE with Differential statement per allocation unit. ਍㰀⼀吀刀㸀ഀഀ
    Information about extents modified by bulk operations
    ਍                              猀椀渀挀攀 琀栀攀 氀愀猀琀 䈀䄀䌀䬀唀倀 漀爀 䈀䄀䌀䬀唀倀 䰀伀䜀 猀琀愀琀攀洀攀渀琀 瀀攀爀 愀氀氀漀挀愀琀椀漀渀 甀渀椀琀⸀㰀⼀吀䐀㸀ഀഀ
    Differential Changed Map pages
    ਍㰀戀爀㸀ഀഀ => Data pages: these are the common pages in the database file.
    ਍㰀戀爀㸀ഀഀ ਍ ഀഀ ਍ 㰀吀䐀㸀㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀㸀㰀䈀㸀䐀愀琀愀 ⠀琀愀戀氀攀⤀ 瀀愀最攀㰀⼀䈀㸀㰀⼀吀䐀㸀ഀഀ ਍㰀吀刀㸀ഀഀ ਍ 㰀吀䐀㸀㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀㸀䄀氀洀漀猀琀 ∀琀栀攀 猀愀洀攀∀ 愀猀 愀 搀愀琀愀 瀀愀最攀Ⰰ 攀砀挀攀瀀琀 昀漀爀 愀 昀攀眀 琀栀椀渀最猀 氀椀欀攀 瀀漀椀渀琀攀爀猀⸀㰀⼀吀䐀㸀ഀഀ ਍㰀吀刀㸀ഀഀ ਍ 㰀吀䐀㸀㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀㸀唀猀攀搀 昀漀爀 琀攀砀琀 搀愀琀愀琀礀瀀攀猀Ⰰ 漀爀 䈀䰀伀䈀猀㰀⼀吀䐀㸀ഀഀ ਍㰀⼀吀䄀䈀䰀䔀㸀ഀഀ
    ਍匀漀Ⰰ 椀渀 最攀渀攀爀愀氀Ⰰ 琀栀攀 ∀搀愀琀愀∀ 愀渀搀 ∀椀渀搀攀砀∀ 瀀愀最攀猀 愀爀攀 漀昀挀漀甀爀猀攀 㰀䈀㸀琀栀攀 洀漀猀琀 挀漀洀洀漀渀 瀀愀最攀猀㰀⼀䈀㸀 椀渀 愀 搀愀琀愀戀愀猀攀Ⰰ 甀渀氀攀猀猀 礀漀甀 栀愀瘀攀㰀戀爀㸀ഀഀ stored a lot of BLOBs as well.
    ਍㰀戀爀㸀ഀഀ About the "system" and "special" pages:
    ਍㰀戀爀㸀ഀഀ You know, this is just how Microsoft has implemented the physical structure. Ofcourse, a lot of new terms
    ਍愀爀攀 椀渀琀爀漀搀甀挀攀搀Ⰰ 眀栀椀挀栀 眀攀 爀攀愀氀氀礀 栀愀瘀攀 琀漀 搀椀猀挀甀猀猀 昀椀爀猀琀⸀㰀戀爀㸀ഀഀ
    ਍䄀猀 猀栀漀眀 椀渀 昀椀最甀爀攀 ㄀Ⰰ 琀栀攀 昀椀爀猀琀 瀀愀最攀猀 椀渀 愀渀礀 搀愀琀愀戀愀猀攀 昀椀氀攀Ⰰ 愀爀攀 㰀䈀㸀猀礀猀琀攀洀 爀攀氀愀琀攀搀㰀⼀䈀㸀⸀ 匀漀Ⰰ 椀渀 琀栀攀 昀椀爀猀琀 㠀 瀀愀最攀猀 ⠀ ⴀ㜀⤀Ⰰ㰀戀爀㸀ഀഀ you will never find any of your objects (like regular tables, indexes etc...).
    ਍㰀戀爀㸀ഀഀ Let's print the second page of the "c:\mssql\data\SALES_DATA_01.ndf" file (this is the file with our table and blob).
    ਍吀栀椀猀 瀀愀最攀 ⠀瀀愀最攀 ㄀⤀ 椀猀 琀栀攀 ∀倀匀䘀∀Ⰰ 漀爀 ∀倀愀最攀 䘀爀攀攀 匀瀀愀挀攀∀ 瀀愀最攀⸀㰀戀爀㸀ഀഀ
    ਍夀漀甀 挀愀渀 昀漀氀氀漀眀 愀氀漀渀最 ⠀椀昀 礀漀甀 椀渀搀攀攀搀 挀爀攀愀琀攀搀 琀栀攀 搀愀琀愀戀愀猀攀 愀猀 猀栀漀眀渀 椀渀 挀栀愀瀀琀攀爀 ㄀⤀⸀ 䨀甀猀琀 甀猀攀 琀栀攀 䐀䈀䌀䌀 倀䄀䜀䔀 挀漀洀洀愀渀搀 愀最愀椀渀⸀㰀戀爀㸀ഀഀ
    ਍ഀഀ ਍㰀昀漀渀琀 昀愀挀攀㴀∀挀漀甀爀椀攀爀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀氀甀攀∀㸀ഀഀ ਍䄀氀氀漀挀愀琀椀漀渀 匀琀愀琀甀猀㰀戀爀㸀ഀഀ
    ਍䜀䄀䴀 ⠀㌀㨀㈀⤀ 㴀 䄀䰀䰀伀䌀䄀吀䔀䐀⸀⸀⸀⸀匀䜀䄀䴀 ⠀㌀㨀㌀⤀ 㴀 一伀吀 䄀䰀䰀伀䌀䄀吀䔀䐀⸀⸀⸀⸀倀䘀匀 ⠀㌀㨀㄀⤀ 㴀  砀㐀  䄀䰀䰀伀䌀䄀吀䔀䐀    开倀䌀吀开䘀唀䰀䰀㰀戀爀㸀ഀഀ DIFF(3:6) = CHANGED........ML (3:7) = NOT MIN_LOGGED
    ਍㰀戀爀㸀ഀഀ PFS: Page Alloc Status @0x000000000C95A000
    ਍㰀戀爀㸀ഀഀ (3:0)....- (3:3)...=.....ALLOCATED...0_PCT_FULL
    ਍⠀㌀㨀㐀⤀⸀⸀⸀⸀ⴀ ⠀㌀㨀㔀⤀⸀⸀⸀㴀 一伀吀 䄀䰀䰀伀䌀䄀吀䔀䐀⸀⸀⸀ 开倀䌀吀开䘀唀䰀䰀 㰀戀爀㸀                             ഀഀ (3:6)....- (3:7)...=.....ALLOCATED...0_PCT_FULL
    ਍⠀㌀㨀㠀⤀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀㴀⸀⸀⸀⸀⸀䄀䰀䰀伀䌀䄀吀䔀䐀⸀⸀㔀 开倀䌀吀开䘀唀䰀䰀                     䴀椀砀攀搀 䔀砀琀㰀戀爀㸀ഀഀ (3:9)..............=.....ALLOCATED...0_PCT_FULL IAM Page Mixed Ext
    ਍⠀㌀㨀㄀ ⤀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀㴀⸀⸀⸀⸀⸀䄀䰀䰀伀䌀䄀吀䔀䐀⸀⸀㔀 开倀䌀吀开䘀唀䰀䰀                     䴀椀砀攀搀 䔀砀琀㰀戀爀㸀ഀഀ (3:11).............=.....ALLOCATED...0_PCT_FULL IAM Page Mixed Ext
    ਍⠀㌀㨀㄀㈀⤀⸀⸀⸀ⴀ ⠀㌀㨀㄀㔀⤀⸀⸀㴀⸀⸀⸀⸀⸀䄀䰀䰀伀䌀䄀吀䔀䐀⸀㄀  开倀䌀吀开䘀唀䰀䰀                     䴀椀砀攀搀 䔀砀琀㰀戀爀㸀ഀഀ (3:16)...- (3:63)..=.....ALLOCATED.100_PCT_FULL
    ਍⠀㌀㨀㘀㐀⤀⸀⸀⸀ⴀ ⠀㌀㨀㘀㘀⤀⸀⸀㴀⸀⸀⸀⸀⸀䄀䰀䰀伀䌀䄀吀䔀䐀⸀㄀  开倀䌀吀开䘀唀䰀䰀                     䴀椀砀攀搀 䔀砀琀㰀戀爀㸀ഀഀ (3:67)...- (3:71)..= NOT ALLOCATED...0_PCT_FULL
    ਍⠀㌀㨀㜀㈀⤀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀㴀⸀⸀⸀⸀⸀䄀䰀䰀伀䌀䄀吀䔀䐀⸀㄀  开倀䌀吀开䘀唀䰀䰀 㰀戀爀㸀                             ഀഀ (3:73)...- (3:5119)= NOT ALLOCATED...0_PCT_FULL
    ਍㰀戀爀㸀ഀഀ ਍㰀戀爀㸀ഀഀ Here you see the allocation status from page 0 up to page 5119 (we only have used up to page 72).
    ਍吀栀椀猀 氀漀眀 攀渀搀 渀甀洀戀攀爀 漀昀 琀栀攀 氀愀猀琀 瀀愀最攀Ⰰ 挀漀洀攀猀 昀爀漀洀 琀栀攀 昀愀挀琀 琀栀愀琀 眀攀 挀爀攀愀琀攀搀 琀栀攀 搀愀琀愀戀愀猀攀昀椀氀攀猀㰀戀爀㸀ഀഀ with an initial size of 40MB (which is very very small).
    ਍㰀戀爀㸀ഀഀ ਍ഀഀ - The system pages are:
    ਍㰀戀爀㸀ഀഀ page 3:0 The fileheader
    ਍瀀愀最攀 ㌀⸀㄀ 吀栀攀 倀䘀匀㰀戀爀㸀ഀഀ page 3:2 The GAM page
    ਍瀀愀最攀 ㌀㨀㌀ 吀栀攀 匀䜀䄀䴀 瀀愀最攀㰀戀爀㸀ഀഀ page 3:4 and 3:5 are not allocated
    ਍瀀愀最攀 ㌀㨀㘀 吀栀攀 䐀䤀䘀䘀 瀀愀最攀 ⠀爀攀氀愀琀攀搀 琀漀 爀攀最椀猀琀攀爀 攀砀琀攀渀琀 挀栀愀渀最攀猀 戀攀琀眀攀攀渀 戀愀挀欀甀瀀猀⤀㰀戀爀㸀ഀഀ page 3:7 The "Minimally Logged Map (ML Map)" page (related to register extent changes with respect to BULK LOGGED operations)
    ਍㰀戀爀㸀ഀഀ - Then, the "second" extent starts, which can hold user objects.
    ਍㰀戀爀㸀ഀഀ page 3:8 This happens to be a page of the EMPLOYEE table
    ਍瀀愀最攀 ㌀㨀㤀 䄀渀 䤀䄀䴀 瀀愀最攀 ⠀䤀渀搀攀砀 䄀氀氀漀挀愀琀椀漀渀 䴀愀瀀⤀㰀戀爀㸀ഀഀ page 3:10 In our case, it happens to contain BLOB data (from albert's photo)
    ਍瀀愀最攀 ㌀㨀㄀㄀ 䄀渀 䤀䄀䴀 瀀愀最攀 ⠀䤀渀搀攀砀 䄀氀氀漀挀愀琀椀漀渀 䴀愀瀀⤀㰀戀爀㸀ഀഀ page 3:12 In our case, it happens to hold the root node page of the BLOB
    ਍瀀愀最攀 ㌀㨀㄀㌀Ⰰ㄀㐀Ⰰ㄀㔀 戀氀漀戀 搀愀琀愀⸀㰀戀爀㸀ഀഀ
    ਍ⴀ 吀栀攀渀Ⰰ 愀猀 漀昀 瀀愀最攀 ㌀㨀㄀㘀Ⰰ 琀栀攀 琀栀椀爀搀 攀砀琀攀渀琀 猀琀愀爀琀猀⸀ഀഀ Here we find pages with blob data.
    ਍攀琀挀⸀⸀㰀戀爀㸀ഀഀ
    ਍漀琀栀攀爀 瀀愀最攀猀 甀瀀 琀漀 瀀愀最攀 㜀㈀㨀 戀氀漀戀 挀栀甀渀欀猀⸀㰀戀爀㸀ഀഀ pages (3:73) up to (3:5119): free pages.
    ਍㰀戀爀㸀ഀഀ ਍ ഀഀ ਍伀欀Ⰰ 氀攀琀✀猀 昀椀爀猀琀 搀椀猀挀甀猀猀 愀 昀攀眀 昀愀挀琀猀 愀戀漀甀琀 攀砀琀攀渀琀猀⸀㰀戀爀㸀ഀഀ
    ਍㰀戀爀㸀ഀഀ

    2.2 Extents.

    ਍ഀഀ As we already saw in the former section, SQL Server organize pages in units called "extents".
    ਍䔀愀挀栀 攀砀琀攀渀琀 挀漀渀猀椀猀琀猀 漀昀 㠀 挀漀渀琀椀最甀漀甀猀 瀀愀最攀猀⸀㰀戀爀㸀ഀഀ
    ਍匀漀洀攀 漀琀栀攀爀 渀甀洀洀攀爀椀挀 昀愀挀琀猀㨀㰀戀爀㸀ഀഀ
      ਍㰀氀椀㸀匀椀渀挀攀 愀 瀀愀最攀 椀猀 㠀䬀 ⠀㠀㄀㤀㈀ 戀礀琀攀猀⤀Ⰰ 愀渀 攀砀琀攀渀琀 椀猀 㘀㐀䬀 ⠀㘀㔀㔀㌀㘀 戀礀琀攀猀⤀ 椀渀 猀椀稀攀⸀㰀⼀氀椀㸀ഀഀ
    • 4GB (4294967296 bytes) space in a database file, can contain 64K (65536) extents
    • ਍㰀⼀甀氀㸀ഀഀ ਍吀眀漀 洀愀椀渀 琀礀瀀攀 漀昀 攀砀琀攀渀琀猀 攀砀椀猀琀猀㨀㰀戀爀㸀ഀഀ ਍㰀甀氀㸀ഀഀ
    • Uniform (or dedicated) extent: all pages belong to the same object (like an index).
    • ਍㰀氀椀㸀䴀椀砀攀搀 ⠀漀爀 猀栀愀爀攀搀⤀ 攀砀琀攀渀琀㨀 琀栀攀 瀀愀最攀猀 挀愀渀 戀攀氀漀渀最 琀漀 琀眀漀 漀爀 洀漀爀攀 漀戀樀攀挀琀猀⸀㰀⼀氀椀㸀ഀഀ
    ਍ഀഀ Fig 3. Uniform and Mixed extents.
    ਍㰀戀爀㸀ഀഀ ਍㰀戀爀㸀ഀഀ
    ਍唀猀甀愀氀氀礀Ⰰ匀儀䰀 匀攀爀瘀攀爀 愀氀氀漀挀愀琀攀猀 洀甀氀琀椀瀀氀攀 甀渀椀昀漀爀洀 攀砀琀攀渀琀猀 昀漀爀 攀愀挀栀 氀愀爀最攀 琀愀戀氀攀⸀㰀戀爀㸀ഀഀ However, if a table is small, or "begins" small, SQL Server won't allocate an entire extent for it.
    ਍䤀渀猀琀攀愀搀 椀琀 眀椀氀氀 愀氀氀漀挀愀琀攀 漀渀攀 漀爀 洀漀爀攀 搀愀琀愀 瀀愀最攀猀 昀爀漀洀 愀 洀椀砀攀搀 攀砀琀攀渀琀⸀ 匀漀Ⰰ 愀 洀椀砀攀搀 攀砀琀攀渀琀 挀愀渀 戀攀 琀栀漀甀最栀琀 漀昀㰀戀爀㸀ഀഀ as a pool of pages for small objects.
    ਍㰀戀爀㸀 ഀഀ When there are quite a few of small tables and indexes in your database, you might expect a certain
    ਍愀洀漀甀渀琀 漀昀 洀椀砀攀搀 攀砀琀攀渀琀猀⸀ 匀儀䰀 匀攀爀瘀攀爀 漀昀挀漀甀爀猀攀 琀爀椀攀猀 琀漀 猀愀瘀攀 愀渀搀 挀漀洀瀀愀挀琀 猀瀀愀挀攀 愀猀 漀瀀琀椀洀愀氀 愀猀 瀀漀猀猀椀戀氀攀⸀㰀戀爀㸀ഀഀ However, quite some smart algolrithms are in use. If an object gets larger than 8 pages, SQL Server tries
    ਍琀漀 愀氀氀漀挀愀琀攀 甀渀椀昀漀爀洀 攀砀琀攀渀琀猀 琀漀 琀栀愀琀 漀戀樀攀挀琀Ⰰ 昀甀爀琀栀攀爀 漀渀Ⰰ 愀猀 洀甀挀栀 愀猀 瀀漀猀猀椀戀氀攀⸀㰀戀爀㸀ഀഀ
    ਍䄀氀猀漀Ⰰ 眀栀攀渀 礀漀甀 挀爀攀愀琀攀 愀 渀攀眀 挀氀甀猀琀攀爀攀搀 椀渀搀攀砀Ⰰ 漀爀 爀攀戀甀椀氀搀 漀渀攀Ⰰ 琀栀攀 瀀愀最攀猀 眀椀氀氀 最漀 漀渀 甀渀椀昀漀爀洀 攀砀琀攀渀琀猀 愀猀 眀攀氀氀⸀㰀戀爀㸀ഀഀ Indexes will be discussed in another section.
    ਍㰀戀爀㸀ഀഀ How SQL Server "keeps track" of free and occupied extents, will be discussed in the next section.
    ਍ഀഀ ਍㰀戀爀㸀ഀഀ
    ਍㰀栀㌀㸀㈀⸀㌀ 匀礀猀琀攀洀 瀀愀最攀猀⸀㰀⼀栀㈀㸀ഀഀ ਍吀栀攀 洀漀猀琀 椀洀瀀漀爀琀愀渀琀 ∀猀礀猀琀攀洀∀ 瀀愀最攀猀 ⠀昀漀爀 椀渀琀攀爀渀愀氀 愀搀洀椀渀椀猀琀爀愀琀椀漀渀⤀ 愀爀攀 氀漀挀愀琀攀搀 漀渀 琀栀攀 昀椀爀猀琀 㠀 瀀愀最攀猀㰀戀爀㸀ഀഀ of any database file. However, as you will read below, most of them are repeated at certain intervals.
    ਍㰀戀爀㸀ഀഀ Fig 4. System pages.
    ਍㰀戀爀㸀ഀഀ ਍㰀戀爀㸀ഀഀ
    ਍㰀戀爀㸀ഀഀ The "GAM" and "SGAM" (Global Allocation Map) pages:
    ਍㰀戀爀㸀ഀഀ A GAM page registers which extents are totally free, or have been allocated.
    ਍䔀愀挀栀 䜀䄀䴀 瀀愀最攀 挀漀瘀攀爀猀 愀戀漀甀琀 㘀㐀Ⰰ    攀砀琀攀渀琀猀Ⰰ 漀爀 愀戀漀甀琀 㐀 䜀䈀 漀昀 搀愀琀愀⸀㰀戀爀㸀ഀഀ
    ਍㰀䈀㸀䔀砀瀀氀愀渀愀琀椀漀渀㨀㰀⼀䈀㸀㰀戀爀㸀ഀഀ
    ਍吀栀攀 瀀愀最攀 栀愀猀 㠀㄀㤀㈀ 戀礀琀攀猀⸀ 一漀眀Ⰰ 琀栀攀 甀猀甀愀氀 㰀䈀㸀瀀愀最攀 栀攀愀搀攀爀㰀⼀䈀㸀 愀渀搀 㰀䈀㸀䜀䄀䴀 栀攀愀搀攀爀㰀⼀䈀㸀 眀椀氀氀 琀愀欀攀 猀漀洀攀 猀瀀愀挀攀Ⰰ㰀戀爀㸀ഀഀ so let's say that 8000 bytes can be used for tracking extents. Now, if a bitmap is used, something like
    ਍㠀    砀 㠀 戀椀琀猀 挀愀渀 戀攀 甀猀攀搀Ⰰ 猀漀 愀戀漀甀琀 㘀㐀䬀 戀椀琀猀⸀ 䔀愀挀栀 漀昀 猀甀挀栀 愀 戀椀琀Ⰰ 挀愀渀 戀攀 甀猀攀搀 琀漀 椀搀攀渀琀椀昀礀 椀昀 愀渀 攀砀琀攀渀琀 椀猀 琀漀琀愀氀氀礀 昀爀攀攀Ⰰ㰀戀爀㸀ഀഀ or if it is already partly allocated (partly or fully used).
    ਍㰀戀爀㸀ഀഀ
      ਍㰀氀椀㸀䤀昀 琀栀攀 戀椀琀 椀猀 ㄀Ⰰ 琀栀攀 攀砀琀攀渀琀 椀猀 琀漀琀愀氀氀礀 昀爀攀攀⸀㰀⼀氀椀㸀ഀഀ
    • If the bit is 0, the extent is (partly) allocated.
    • ਍㰀⼀甀氀㸀ഀഀ ਍匀漀Ⰰ 㘀㐀䬀 攀砀琀攀渀琀猀 挀愀渀 戀攀 ∀挀漀瘀攀爀攀搀∀ 戀礀 漀渀攀 䜀䄀䴀 瀀愀最攀⸀  匀漀Ⰰ 琀栀椀猀 愀洀漀甀渀琀猀 琀漀 愀戀漀甀琀 㐀䜀䈀 搀愀琀愀猀瀀愀挀攀⸀㰀戀爀㸀ഀഀ So, if a datafile is larger than 4GB, at every 4GB interval a GAM bitmap page is needed.
      ਍㰀戀爀㸀ഀഀ A similar story holds for the SGAM page. Only here, it tracks the following in the bitmap:
      ਍䤀昀 愀渀 攀砀琀攀渀琀 椀猀 愀 洀椀砀攀搀 攀砀琀攀渀琀 眀椀琀栀 愀琀 氀攀愀猀琀 漀渀攀 瀀愀最攀 昀爀攀攀Ⰰ 琀栀攀 戀椀琀 椀猀 ㄀⸀㰀戀爀㸀ഀഀ If an extent is not a mixed extent, or it is a full mixed extent, then the bit is 0.
      ਍㰀戀爀㸀ഀഀ So, this explains how SQL Server can discriminate between free or (partially) used extents.
      ਍㰀戀爀㸀ഀഀ As you have seen in the former sections, the first GAM is page 2, and the first SGAM is page 3 in any .ndf file.
      ਍㰀戀爀㸀ഀഀ ਍㰀䈀㸀㰀唀㸀吀栀攀 ∀倀愀最攀 䘀爀攀攀 匀瀀愀挀攀∀ ⠀倀䘀匀⤀ 瀀愀最攀猀㨀㰀⼀唀㸀㰀⼀䈀㸀㰀戀爀㸀ഀഀ
      ਍吀栀椀猀 椀猀 瀀愀最攀 ㄀ 椀渀 愀渀礀 漀爀搀椀渀愀爀礀 ⸀渀搀昀 搀愀琀愀戀愀猀攀 昀椀氀攀Ⰰ 爀椀最栀琀 愀昀琀攀爀 琀栀攀 昀椀氀攀栀攀愀搀攀爀 ⠀瀀愀最攀  ⤀⸀㰀戀爀㸀ഀഀ It registers which pages and page ranges are in use, or are free.
      ਍䤀昀 礀漀甀 栀愀瘀攀 瘀攀爀礀 猀洀愀氀氀 搀愀琀愀戀愀猀攀 昀椀氀攀猀Ⰰ 琀栀攀渀 攀瘀攀渀 樀甀猀琀 漀渀攀 倀䘀匀 瀀愀最攀 洀椀最栀琀 戀攀 猀甀昀昀椀挀椀攀渀琀 瀀攀爀 昀椀氀攀⸀㰀戀爀㸀ഀഀ This will be explained below.
      ਍䤀渀 漀甀爀 攀砀愀洀瀀氀攀 猀愀氀攀猀 搀愀琀愀戀愀猀攀Ⰰ 眀攀 甀猀攀 㐀 䴀䈀 猀椀稀攀猀Ⰰ 眀栀椀挀栀 椀猀 爀椀搀椀挀甀氀漀甀猀 猀洀愀氀氀 漀昀挀漀甀爀猀攀⸀㰀戀爀㸀ഀഀ
      ਍䈀甀琀 昀漀爀 氀愀爀最攀爀 搀愀琀愀戀愀猀攀 昀椀氀攀猀Ⰰ 愀 倀䘀匀 瀀愀最攀 渀攀攀搀猀 琀漀 戀攀 爀攀瀀攀愀琀攀搀 愀昀琀攀爀 愀戀漀甀琀 㠀    瀀愀最攀猀⸀㰀戀爀㸀ഀഀ This is so, because a PFS does not use a bitmap. The PFS uses one byte for each page, which records whether the page
      ਍椀猀 愀氀氀漀挀愀琀攀搀 漀爀 渀漀琀⸀ 匀漀Ⰰ 猀椀渀挀攀 琀栀攀 倀䘀匀 栀愀猀 愀戀漀甀琀 㠀    甀猀愀戀氀攀 戀礀琀攀猀 昀漀爀 琀栀椀猀 瀀甀爀瀀漀猀攀Ⰰ 漀琀栀攀爀 倀䘀匀 瀀愀最攀猀 愀爀攀 渀攀攀搀攀搀 椀渀 ⠀愀戀漀甀琀⤀㰀戀爀㸀ഀഀ 8000 page intervals.
      ਍䤀琀 渀攀攀搀猀 愀 戀礀琀攀 瀀攀爀 瀀愀最攀Ⰰ 戀攀挀愀甀猀攀 椀琀 琀爀椀攀猀 琀漀 搀攀猀挀爀椀戀攀 昀漀爀 攀愀挀栀 瀀愀最攀Ⰰ 琀栀攀 氀攀瘀攀氀 漀昀 ∀昀甀氀氀渀攀猀猀∀Ⰰ 氀椀欀攀㰀戀爀㸀ഀഀ 0_PCT_FULL, 50_PCT_FULL, 100_PCT_FULL (and a few others), so to register that, one bit per page
      ਍椀猀 渀漀琀 猀甀昀昀椀挀椀攀渀琀⸀ 匀漀Ⰰ 漀渀攀 戀礀琀攀 瀀攀爀 瀀愀最攀 椀猀 甀猀攀搀⸀㰀戀爀㸀ഀഀ
      ਍䠀攀爀攀 愀最愀椀渀Ⰰ 礀漀甀 挀愀渀 猀攀攀 愀 搀甀洀瀀 漀昀 琀栀攀 倀䘀匀 漀昀 琀栀攀 ∀挀㨀尀洀猀猀焀氀尀搀愀琀愀尀匀䄀䰀䔀匀开䐀䄀吀䄀开 ㄀⸀渀搀昀∀ 搀愀琀愀戀愀猀攀 昀椀氀攀Ⰰ㰀戀爀㸀ഀഀ as used in our example SALES database.
      ਍㰀戀爀㸀ഀഀ ਍㰀昀漀渀琀 昀愀挀攀㴀∀挀漀甀爀椀攀爀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀氀甀攀∀㸀ഀഀ ਍䄀氀氀漀挀愀琀椀漀渀 匀琀愀琀甀猀㰀戀爀㸀ഀഀ
      ਍䜀䄀䴀 ⠀㌀㨀㈀⤀ 㴀 䄀䰀䰀伀䌀䄀吀䔀䐀⸀⸀⸀⸀匀䜀䄀䴀 ⠀㌀㨀㌀⤀ 㴀 一伀吀 䄀䰀䰀伀䌀䄀吀䔀䐀⸀⸀⸀⸀倀䘀匀 ⠀㌀㨀㄀⤀ 㴀  砀㐀  䄀䰀䰀伀䌀䄀吀䔀䐀    开倀䌀吀开䘀唀䰀䰀㰀戀爀㸀ഀഀ DIFF(3:6) = CHANGED........ML (3:7) = NOT MIN_LOGGED
      ਍㰀戀爀㸀ഀഀ PFS: Page Alloc Status @0x000000000C95A000
      ਍㰀戀爀㸀ഀഀ (3:0)....- (3:3)...=.....ALLOCATED...0_PCT_FULL
      ਍⠀㌀㨀㐀⤀⸀⸀⸀⸀ⴀ ⠀㌀㨀㔀⤀⸀⸀⸀㴀 一伀吀 䄀䰀䰀伀䌀䄀吀䔀䐀⸀⸀⸀ 开倀䌀吀开䘀唀䰀䰀 㰀戀爀㸀                             ഀഀ (3:6)....- (3:7)...=.....ALLOCATED...0_PCT_FULL
      ਍⠀㌀㨀㠀⤀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀㴀⸀⸀⸀⸀⸀䄀䰀䰀伀䌀䄀吀䔀䐀⸀⸀㔀 开倀䌀吀开䘀唀䰀䰀                     䴀椀砀攀搀 䔀砀琀㰀戀爀㸀ഀഀ (3:9)..............=.....ALLOCATED...0_PCT_FULL IAM Page Mixed Ext
      ਍⠀㌀㨀㄀ ⤀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀㴀⸀⸀⸀⸀⸀䄀䰀䰀伀䌀䄀吀䔀䐀⸀⸀㔀 开倀䌀吀开䘀唀䰀䰀                     䴀椀砀攀搀 䔀砀琀㰀戀爀㸀ഀഀ (3:11).............=.....ALLOCATED...0_PCT_FULL IAM Page Mixed Ext
      ਍⠀㌀㨀㄀㈀⤀⸀⸀⸀ⴀ ⠀㌀㨀㄀㔀⤀⸀⸀㴀⸀⸀⸀⸀⸀䄀䰀䰀伀䌀䄀吀䔀䐀⸀㄀  开倀䌀吀开䘀唀䰀䰀                     䴀椀砀攀搀 䔀砀琀㰀戀爀㸀ഀഀ (3:16)...- (3:63)..=.....ALLOCATED.100_PCT_FULL
      ਍⠀㌀㨀㘀㐀⤀⸀⸀⸀ⴀ ⠀㌀㨀㘀㘀⤀⸀⸀㴀⸀⸀⸀⸀⸀䄀䰀䰀伀䌀䄀吀䔀䐀⸀㄀  开倀䌀吀开䘀唀䰀䰀                     䴀椀砀攀搀 䔀砀琀㰀戀爀㸀ഀഀ (3:67)...- (3:71)..= NOT ALLOCATED...0_PCT_FULL
      ਍⠀㌀㨀㜀㈀⤀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀㴀⸀⸀⸀⸀⸀䄀䰀䰀伀䌀䄀吀䔀䐀⸀㄀  开倀䌀吀开䘀唀䰀䰀 㰀戀爀㸀                             ഀഀ (3:73)...- (3:5119)= NOT ALLOCATED...0_PCT_FULL
      ਍㰀戀爀㸀ഀഀ ਍ഀഀ The "ML" (or Bulk Changed Map pages) and "DIFF" (Differential Changed Map pages):
      ਍㰀戀爀㸀ഀഀ => The Differential Changed Map pages, track which extents have been changed between differential backups.
      ਍䔀瘀攀爀 眀漀渀搀攀爀攀搀 栀漀眀 匀儀䰀 匀攀爀瘀攀爀 欀渀漀眀猀 眀栀愀琀 挀栀愀渀最攀猀 琀漀 戀愀挀欀甀瀀 戀攀琀眀攀攀渀 愀 䘀甀氀氀 戀愀挀欀甀瀀Ⰰ 愀渀搀 琀栀攀 昀漀氀氀漀眀椀渀最㰀戀爀㸀ഀഀ differential backups? The differential backups are generally much smaller compared to the full backup.
      ਍吀栀椀猀 椀猀 搀甀攀 琀漀 琀栀攀 昀愀挀琀 琀栀愀琀 匀儀䰀 匀攀爀瘀攀爀 爀攀最椀猀琀攀爀猀 眀栀椀挀栀 攀砀琀攀渀琀猀 栀愀瘀攀 戀攀攀渀 挀栀愀渀最攀搀⸀ 匀漀Ⰰ 甀渀洀漀搀椀昀椀攀搀 攀砀琀攀渀琀猀㰀戀爀㸀ഀഀ do not need to be backupped between differential backups.
      ਍㰀戀爀㸀ഀഀ => The ML pages track which extents are affected with "Bulk logged" operations.
      ਍㰀戀爀㸀ഀഀ However, both types of pages are not very relevant for our discussion.
      ਍㰀戀爀㸀ഀഀ ਍㰀䈀㸀㰀唀㸀吀栀攀 ∀䤀䄀䴀∀ 瀀愀最攀猀㨀㰀⼀唀㸀㰀⼀䈀㸀㰀戀爀㸀ഀഀ
      ਍䤀 氀椀欀攀 琀漀 瀀漀猀瀀漀渀攀 琀栀椀猀 漀渀攀Ⰰ 甀渀琀椀氀 眀攀 栀愀瘀攀 挀漀瘀攀爀攀搀 䈀琀爀攀攀 愀渀搀 椀渀搀攀砀 猀琀爀甀挀琀甀爀攀猀 椀渀 猀漀洀攀 洀漀爀攀 搀攀琀愀椀氀⸀㰀戀爀㸀ഀഀ
      ਍㰀戀爀㸀ഀഀ
      ਍㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀氀甀攀∀㸀ഀഀ

      Chapter 3. Using FILESTREAM for storage of blobs (2008/2012).

      ਍㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀氀愀挀欀∀㸀ഀഀ ਍唀瀀 琀漀 渀漀眀Ⰰ 眀攀 栀愀瘀攀 猀攀攀渀 㰀䈀㸀漀渀攀 琀礀瀀攀㰀⼀䈀㸀 漀昀 䈀䰀伀䈀 猀琀漀爀愀最攀Ⰰ 渀愀洀攀氀礀 㰀䈀㸀∀椀渀氀椀渀攀∀㰀⼀䈀㸀 猀琀漀爀愀最攀Ⰰ 眀栀攀爀攀 琀栀攀 戀氀漀戀㰀戀爀㸀ഀഀ really physically is stored on database pages.
      ਍㰀戀爀㸀ഀഀ If you would ask me: I think the (traditional) inline storage is quite "ok", since all information
      ਍⠀洀攀琀愀搀愀琀愀⬀戀氀漀戀猀 琀栀攀洀猀攀氀瘀攀猀⤀ 椀猀 挀漀氀氀攀挀琀攀搀 椀渀 漀渀攀 愀渀搀 琀栀攀 猀愀洀攀 搀愀琀愀戀愀猀攀⸀ 䘀漀爀 琀爀愀渀猀愀挀琀椀漀渀愀氀 爀攀愀猀漀渀猀Ⰰ 愀渀搀㰀戀爀㸀ഀഀ for availability, this is good.
      ਍㰀戀爀㸀ഀഀ ⇒ Drawbacks of inline storage:
      ਍㰀戀爀㸀ഀഀ However, if the amount of blobs is very large, DBA's might be confronted with long backup/recovery times.
      ਍䈀甀琀 琀栀愀琀 挀漀甀氀搀 愀氀猀漀 戀攀 搀甀攀 琀漀 琀栀攀 昀愀挀琀 琀栀愀琀 挀攀爀琀愀椀渀 愀瀀瀀氀椀愀渀挀攀猀 栀愀瘀攀 ∀瘀攀爀猀椀漀渀椀渀最∀ 猀眀椀琀挀栀攀搀 漀渀Ⰰ 眀栀椀挀栀 洀椀最栀琀 爀攀猀甀氀琀㰀戀爀㸀ഀഀ in the fact that documents (blobs) are stored several times, corresponding to their "versions".
      ਍匀漀Ⰰ 椀昀 礀漀甀 挀漀甀氀搀 琀栀爀漀琀琀氀攀 琀栀愀琀 戀愀挀欀 愀 氀椀琀琀氀攀Ⰰ 椀琀 洀椀最栀琀 栀愀瘀攀 焀甀椀琀攀 愀渀 椀洀瀀愀挀琀 漀渀 琀栀攀 搀愀琀愀戀愀猀攀 猀椀稀攀⸀㰀戀爀㸀ഀഀ
      ਍匀攀挀漀渀搀氀礀Ⰰ 瀀攀爀昀漀爀洀愀渀挀攀 洀椀最栀琀 戀攀 愀渀 椀猀猀甀攀 琀漀漀⸀ 䈀甀琀 搀漀渀✀琀 昀漀爀最攀琀 琀栀愀琀 瀀漀猀猀椀戀氀攀 ∀洀椀搀搀氀攀眀愀爀攀⼀愀瀀瀀氀椀挀愀琀椀漀渀∀ 匀攀爀瘀攀爀猀㰀戀爀㸀ഀഀ might be involved as well.
      ਍㰀戀爀㸀ഀഀ A commonly heard phrase is that:"for large blobs", the filesystem has better perfomance over inline storage,
      ਍眀栀椀氀攀 ∀昀漀爀 猀洀愀氀氀攀爀 戀氀漀戀猀∀Ⰰ 椀渀氀椀渀攀 猀琀漀爀愀最攀 漀昀昀攀爀猀 最漀漀搀 瀀攀爀昀漀爀洀愀渀挀攀㰀⼀䤀㸀⸀ 一漀眀Ⰰ 搀攀昀椀渀攀 ∀氀愀爀最攀∀ 愀渀搀 ∀猀洀愀氀氀∀⸀⸀⸀⸀㰀戀爀㸀ഀഀ It seems that Microsoft takes "over" 1MB as "large", and smaller than 1MB as "small".
      ਍㰀戀爀㸀ഀഀ The suggested improvement in performance, is partly attributed to the fast file IO service of the OS, and
      ਍琀栀攀 甀猀攀 漀昀 琀栀攀 ∀一吀 昀椀氀攀 挀愀挀栀攀∀⸀㰀戀爀㸀ഀഀ
      ਍㰀䈀㸀☀⌀㠀㘀㔀㠀㬀 䄀氀琀攀爀渀愀琀椀瘀攀猀 昀漀爀 椀渀氀椀渀攀 猀琀漀爀愀最攀㨀㰀⼀䈀㸀㰀戀爀㸀ഀഀ
      ਍䤀琀✀猀 瀀漀猀猀椀戀氀攀 琀漀 猀琀漀爀攀 琀栀攀 戀氀漀戀猀 漀渀 愀 昀椀氀攀猀礀猀琀攀洀 ⠀甀猀椀渀最 戀氀漀挀欀 䤀伀Ⰰ 愀猀 眀攀氀氀 愀猀 昀椀氀攀 䤀伀⤀⸀㰀戀爀㸀ഀഀ This means that SQL Server uses tables and views solely for metadata, but the blobs themselves
      ਍愀爀攀 渀漀琀 猀琀漀爀攀搀 椀渀 匀儀䰀 匀攀爀瘀攀爀Ⰰ 戀甀琀 愀爀攀 昀椀氀攀猀 漀渀 搀椀猀欀猀⸀㰀戀爀㸀ഀഀ
      ਍吀栀攀爀攀 攀砀椀猀琀猀 琀栀椀爀搀ⴀ瀀愀爀琀礀 猀漀氀甀琀椀漀渀猀 昀漀爀 琀栀椀猀Ⰰ 愀猀 眀攀氀氀 愀猀 䴀椀挀爀漀猀漀昀琀 椀洀瀀氀攀洀攀渀琀愀琀椀漀渀猀⸀ഀഀ
      ਍匀椀渀挀攀 匀儀䰀 ㈀  㠀Ⰰ 琀栀攀 䴀椀挀爀漀猀漀昀琀 ∀䘀䤀䰀䔀匀吀刀䔀䄀䴀∀ 昀攀愀琀甀爀攀 戀攀挀愀洀攀 愀瘀愀椀氀愀戀氀攀⸀㰀戀爀㸀ഀഀ In this chapter, we are going to take a quick look at it's main features.
      ਍㰀戀爀㸀ഀഀ ⇒ What is the FILESTREAM feature then?:
      ਍㰀戀爀㸀ഀഀ In essence: the DBA needs to create a new "filegroup" with the "filestream clause". This filegroup,
      ਍琀栀攀渀 瀀栀礀猀椀挀愀氀氀礀 椀猀 㰀䈀㸀愀 昀漀氀搀攀爀 漀渀 愀 昀椀氀攀礀猀琀攀洀㰀⼀䈀㸀Ⰰ 眀栀攀爀攀 琀栀攀 戀氀漀戀猀 愀爀攀 最漀椀渀最 琀漀 戀攀 猀愀瘀攀搀 愀渀搀 愀挀挀攀猀猀攀搀⸀㰀戀爀㸀ഀഀ From a "transactional viewpoint", the filegroup is just a container, accessible using the SQL Server interface
      ਍眀栀椀挀栀 琀栀攀渀 最愀爀愀渀琀攀攀猀 挀漀渀猀椀猀琀攀渀挀礀⸀ 吀栀椀猀 椀猀 伀䬀Ⰰ 戀甀琀 椀昀 䤀伀 椀猀 瀀漀猀猀椀戀氀攀 甀猀椀渀最 漀琀栀攀爀 洀攀琀栀漀搀猀 ⠀甀猀椀渀最 琀栀攀 伀匀 昀漀爀 攀砀愀洀瀀氀攀⤀Ⰰ㰀戀爀㸀ഀഀ there might be serious risks for inconsistencies.
      ਍㰀戀爀㸀ഀഀ Once filestream is enabled and a filestream filegroup is created, you can build tables with a varbinary datatype, using
      ਍琀栀攀 㰀䈀㸀∀昀椀氀攀猀琀爀攀愀洀 挀氀愀甀猀攀∀ 昀漀爀 琀栀愀琀 挀漀氀甀洀渀㰀⼀䈀㸀Ⰰ 眀栀椀挀栀 洀愀欀攀猀 猀甀爀攀 琀栀攀 戀氀漀戀猀 琀栀攀渀 愀爀攀 猀愀瘀攀搀 琀漀Ⰰ 愀渀搀 愀挀挀攀猀猀攀搀 昀爀漀洀Ⰰ 琀栀椀猀 猀瀀攀挀椀愀氀 昀椀氀攀最爀漀甀瀀⸀㰀戀爀㸀ഀഀ
      ਍夀漀甀 挀愀渀 ∀攀渀愀戀氀攀∀ 昀椀氀攀猀琀爀攀愀洀 ∀最氀漀戀愀氀氀礀∀ 漀渀 琀栀攀 椀渀猀琀愀渀挀攀 氀攀瘀攀氀⸀ 倀攀爀 搀攀昀愀甀氀琀Ⰰ 椀琀✀猀 ∀漀昀昀∀⸀㰀戀爀㸀ഀഀ However, filestream is a database feature. You can have databases under your instance with no filestream,
      ਍愀渀搀 搀愀琀愀戀愀猀攀猀 㰀䤀㸀眀椀琀栀㰀⼀䤀㸀 昀椀氀攀猀琀爀攀愀洀⸀㰀戀爀㸀ഀഀ
      ਍㰀戀爀㸀ഀഀ

      3.1 Enabling "Filestream".

      ਍ഀഀ ਍㰀䈀㸀㴀㸀 圀栀椀氀攀 椀渀猀琀愀氀氀椀渀最 匀儀䰀 匀攀爀瘀攀爀㨀㰀⼀䈀㸀㰀戀爀㸀ഀഀ ਍㰀戀爀㸀ഀഀ When you install SQL Server, somewhere "halfway", there is an option to configure the database engine.
      ਍夀漀甀 栀愀瘀攀 琀漀 眀愀琀挀栀 挀愀爀攀昀甀氀氀礀Ⰰ 椀昀 礀漀甀 眀漀甀氀搀 搀漀 愀渀 椀渀琀攀爀愀挀琀椀瘀攀 椀渀猀琀愀氀氀Ⰰ 戀攀挀愀甀猀攀 椀琀✀猀 攀愀猀礀 琀漀 漀瘀攀爀氀漀漀欀 琀栀椀猀 漀瀀琀椀漀渀⸀㰀戀爀㸀ഀഀ See figure 5.
      ਍㰀戀爀㸀ഀഀ Fig 5. Enabling the FILESTREAM feature at the installation of SQL Server.
      ਍㰀戀爀㸀ഀഀ ਍㰀戀爀㸀ഀഀ
      ਍㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀爀漀眀渀∀㸀ഀഀ => After SQL Server already was installed:
      ਍㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀氀愀挀欀∀㸀ഀഀ
      ਍㰀䈀㸀ⴀ 唀猀椀渀最 愀 最爀愀瀀栀椀挀愀氀 甀琀椀氀椀琀礀㨀㰀⼀䈀㸀㰀戀爀㸀ഀഀ
      ਍䤀昀 匀儀䰀 匀攀爀瘀攀爀 眀愀猀 愀氀爀攀愀搀礀 椀渀猀琀愀氀氀攀搀Ⰰ 礀漀甀 挀愀渀 猀琀椀氀氀 甀猀攀 琀栀攀 ∀匀儀䰀 匀攀爀瘀攀爀 䌀漀渀昀椀最甀爀愀琀椀漀渀 䴀愀渀愀最攀爀∀㰀戀爀㸀ഀഀ to enable the filestream feature. Start the utility, rightclick the "SQL Server service", and choose "properties".
      ਍䤀渀 琀栀攀 搀椀愀氀漀最戀漀砀 琀栀愀琀 眀椀氀氀 猀栀漀眀 甀瀀Ⰰ 礀漀甀 挀愀渀 挀栀漀漀猀攀 昀漀爀 猀攀瘀攀爀愀氀 猀攀琀琀椀渀最猀⸀㰀戀爀㸀ഀഀ
      ਍㰀䈀㸀䘀椀最 㘀⸀ 䔀渀愀戀氀椀渀最 琀栀攀 䘀䤀䰀䔀匀吀刀䔀䄀䴀 昀攀愀琀甀爀攀 甀猀椀渀最 琀栀攀 ∀匀儀䰀 匀攀爀瘀攀爀 䌀漀渀昀椀最甀爀愀琀椀漀渀 䴀愀渀愀最攀爀∀⸀㰀⼀䈀㸀㰀戀爀㸀ഀഀ
      ਍㰀椀洀最 猀爀挀㴀∀猀焀氀猀攀爀瘀攀爀戀氀漀戀㔀⸀樀瀀最∀ 愀氀椀最渀㴀∀挀攀渀琀爀攀∀⼀㸀ഀഀ
      ਍㰀戀爀㸀ഀഀ - Using TSQL:
      ਍㰀戀爀㸀ഀഀ Instead of using the graphical utility, you may use TSQL as well, to enable the Filestream feature:
      ਍㰀戀爀㸀ഀഀ ਍ഀഀ USE master
      ਍䜀漀㰀戀爀㸀ഀഀ EXEC sp_configure 'show advanced options'
      ਍䜀伀㰀戀爀㸀ഀഀ EXEC sp_configure filestream_access_level, 1
      ਍䜀伀㰀戀爀㸀ഀഀ RECONFIGURE WITH OVERRIDE
      ਍䜀伀 㰀戀爀㸀ഀഀ
      ਍ⴀⴀ 琀栀攀 瀀漀猀猀椀戀氀攀 漀瀀琀椀漀渀猀   ⠀渀漀渀攀⤀Ⰰ 漀爀 ㄀ ⠀吀匀儀䰀 愀挀挀攀猀猀⤀Ⰰ 漀爀 ㈀ ⠀吀匀儀䰀 愀挀挀攀猀猀Ⰰ 愀渀搀 昀椀氀攀 䤀⼀伀 猀琀爀攀愀洀椀渀最 愀挀挀攀猀猀⤀㰀戀爀㸀ഀഀ -- will be explained below.
      ਍㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀氀愀挀欀∀㸀ഀഀ
      ਍㰀戀爀㸀ഀഀ ਍㰀䈀㸀㴀㸀 䌀漀渀昀椀最甀爀椀渀最 琀栀攀 䘀椀氀攀猀琀爀攀愀洀 猀攀琀琀椀渀最猀㨀㰀⼀䈀㸀㰀戀爀㸀ഀഀ ਍㰀戀爀㸀ഀഀ Note from figures 5 and 6, that you can configure Filestream for various settings.
      ਍䄀氀琀栀漀甀最栀 琀栀漀猀攀 昀椀最甀爀攀猀 猀栀漀眀 琀栀攀 猀愀洀攀 瀀漀猀猀椀戀氀攀 挀漀渀昀椀最甀爀愀琀椀漀渀猀Ⰰ 椀琀✀猀 洀漀猀琀 挀氀攀愀爀 昀爀漀洀 昀椀最甀爀攀 㘀⸀㰀戀爀㸀ഀഀ ਍㰀甀氀㸀ഀഀ
    • Option 1: "Enable FILESTREAM for Transact-SQL access"
      ਍䠀攀爀攀 礀漀甀 氀椀洀椀琀 愀挀挀攀猀猀 琀漀 琀栀攀 戀氀漀戀猀 甀猀椀渀最 吀匀儀䰀 漀渀氀礀⸀ 吀栀椀猀 椀猀 琀栀攀 猀愀昀攀猀琀 眀愀礀 琀漀 最漀Ⰰ 愀氀戀攀椀琀 ⠀猀攀攀洀椀渀最氀礀⤀㰀戀爀㸀ഀഀ not the most flexible option.
    • ਍ഀഀ
    • Option 2: "Enable FILESTREAM for file I/O streaming access"
      ਍䤀昀 礀漀甀 眀愀渀琀 琀栀椀猀 琀漀漀Ⰰ 琀栀攀渀 吀匀儀䰀 愀挀挀攀猀猀 椀猀 攀渀愀戀氀攀搀Ⰰ 㰀䈀㸀愀渀搀㰀⼀䈀㸀 ∀昀椀氀攀 椀⼀漀 愀挀挀攀猀猀∀ 椀猀 攀渀愀戀氀攀搀⸀㰀戀爀㸀ഀഀ This is very flexible, but you need to do some further research here.
    • ਍ഀഀ
    • Option 3: "Allow remote clients to have streaming access to FILESTREAM data"
      ਍䤀昀 礀漀甀 眀愀渀琀 琀栀椀猀Ⰰ 琀栀攀渀 吀匀儀䰀 愀挀挀攀猀猀 椀猀 攀渀愀戀氀攀搀Ⰰ 㰀䈀㸀愀渀搀㰀⼀䈀㸀 ∀猀栀愀爀攀 愀挀挀攀猀猀∀ 椀猀 攀渀愀戀氀攀搀⸀㰀戀爀㸀ഀഀ Furthermore any client can, in principle, access the share. You really need to do some further research here.
    • ਍㰀⼀甀氀㸀ഀഀ
      ਍䘀爀漀洀 愀 ∀琀爀愀渀猀愀挀琀椀漀渀愀氀 瘀椀攀眀瀀漀椀渀琀∀Ⰰ 琀栀攀 昀椀氀攀最爀漀甀瀀 椀猀 樀甀猀琀 愀 挀漀渀琀愀椀渀攀爀Ⰰ 愀挀挀攀猀猀椀戀氀攀 甀猀椀渀最 琀栀攀 匀儀䰀 匀攀爀瘀攀爀 椀渀琀攀爀昀愀挀攀㰀戀爀㸀ഀഀ which then garantees consistency, if you would use the first and second options.
      ਍䤀渀 琀栀椀猀 挀愀猀攀Ⰰ 礀漀甀 挀愀渀 甀猀攀 吀匀儀䰀Ⰰ 愀渀搀 愀氀猀漀 甀猀攀 圀椀渀㌀㈀ 䄀倀䤀猀 琀漀 眀漀爀欀 眀椀琀栀 琀栀攀 戀氀漀戀猀⸀ 䘀漀爀 攀砀愀洀瀀氀攀Ⰰ 琀栀攀 ∀挀漀氀甀洀渀渀愀洀攀⸀瀀愀琀栀渀愀洀攀⠀⤀∀㰀戀爀㸀ഀഀ method (columnname of the varbinary column), can provide a handle to a file, and further operations can take place.
      ਍伀渀攀 椀洀瀀漀爀琀愀渀琀 挀漀渀猀攀焀甀攀渀挀攀 椀猀 琀栀甀猀 琀栀愀琀 䄀瀀瀀氀椀挀愀琀椀漀渀猀 挀愀渀 甀猀攀 猀琀爀攀愀洀椀渀最 䄀倀䤀猀 愀渀搀 瀀攀爀昀漀爀洀愀渀挀攀 漀昀 琀栀攀 昀椀氀攀 猀礀猀琀攀洀㰀戀爀㸀ഀഀ and at the same time maintain transactional consistency between the unstructured data (the files) and the
      ਍挀漀爀爀攀猀瀀漀渀搀椀渀最 猀琀爀甀挀琀甀爀攀搀 搀愀琀愀Ⰰ 琀栀愀琀 椀猀Ⰰ 琀栀攀 漀琀栀攀爀 昀椀攀氀搀猀 漀昀 琀栀攀 琀愀戀氀攀Ⰰ 愀渀搀 愀氀氀 漀瀀琀椀漀渀愀氀氀礀 爀攀氀愀琀攀搀 琀愀戀氀攀猀⸀㰀戀爀㸀ഀഀ ਍㰀戀爀㸀ഀഀ If you enable the third option, so using a share access for remote clients, I would say that a fully garanteed
      ਍挀漀渀猀椀猀琀攀渀挀礀 椀猀 ∀愀琀 爀椀猀欀∀Ⰰ 甀渀氀攀猀猀 琀栀攀 愀瀀瀀氀椀挀愀琀椀漀渀猀 椀渀 甀猀攀 愀爀攀 琀爀甀氀礀 ∀椀爀漀渀挀氀愀搀∀⸀ 夀漀甀 渀攀攀搀 琀漀 搀漀 洀漀爀攀 爀攀猀攀愀爀挀栀 ⠀椀昀 礀漀甀 愀爀攀 椀渀琀攀爀爀攀猀琀攀搀⤀⸀㰀戀爀㸀ഀഀ So, I guess I try to say that there might be security issues as well as transactional consistency issues.
      ਍㰀戀爀㸀ഀഀ
      ਍㰀栀㌀㸀㌀⸀㈀ 䤀洀瀀氀攀洀攀渀琀椀渀最 ∀䘀椀氀攀猀琀爀攀愀洀∀⸀㰀⼀栀㈀㸀ഀഀ ਍䰀攀琀猀 琀爀礀 琀漀 愀搀搀 愀 昀椀氀攀猀琀爀攀愀洀 琀愀戀氀攀猀瀀愀挀攀 琀漀 漀甀爀 匀䄀䰀䔀匀 搀愀琀愀戀愀猀攀⸀㰀戀爀㸀ഀഀ I suggest we make a suitable folder first. I choose to create a folder "c:\fsblobs". ਍㰀戀爀㸀ഀഀ Inside that, I want to have a "c:\fsblobs\documents" folder. But do not create this one.
      ਍吀栀愀琀 琀栀攀渀 眀椀氀氀 戀攀 琀栀攀 昀漀氀搀攀爀⼀挀漀渀琀愀椀渀攀爀 琀栀愀琀✀猀 愀猀猀漀挀椀愀琀攀搀 眀椀琀栀 琀栀攀 渀攀眀 昀椀氀攀猀琀爀攀愀洀 琀愀戀氀攀猀瀀愀挀攀⸀㰀戀爀㸀ഀഀ
      ਍䌀爀攀愀琀攀 琀栀攀 ∀挀㨀尀昀猀戀氀漀戀猀∀Ⰰ 戀甀琀 搀漀 渀漀琀 挀爀攀愀琀攀 琀栀攀 猀攀挀漀渀搀 昀漀氀搀攀爀 ∀挀㨀尀昀猀戀氀漀戀猀尀搀漀挀甀洀攀渀琀猀∀Ⰰ 戀攀挀愀甀猀攀 匀儀䰀㰀戀爀㸀ഀഀ will do that for us (it does not expect an existing directory).
      ਍㰀戀爀㸀ഀഀ So, here we go:
      ਍㰀戀爀㸀ഀഀ ਍ഀഀ ALTER DATABASE SALES ADD FILEGROUP Documents CONTAINS FILESTREAM
      ਍䜀伀㰀戀爀㸀ഀഀ ALTER DATABASE SALES ADD FILE (NAME='Documents', FILENAME='c:\fsblobs\documents') TO FILEGROUP Documents
      ਍䜀伀㰀戀爀㸀ഀഀ
      ਍㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀氀愀挀欀∀㸀ഀഀ In my case, it succeeded. Let's see what happened on the filesystem:
      ਍㰀戀爀㸀ഀഀ ਍ഀഀ C:\> cd fsblobs
      ਍䌀㨀尀昀猀戀氀漀戀猀㸀 挀搀 搀⨀㰀戀爀㸀ഀഀ
      ਍䌀㨀尀昀猀戀氀漀戀猀尀搀漀挀甀洀攀渀琀猀㸀搀椀爀㰀戀爀㸀ഀഀ
      ਍㌀ ⸀㄀㄀⸀㈀ ㄀㈀  ㈀ 㨀㄀㐀    䐀䤀刀          ␀䘀匀䰀伀䜀㰀戀爀㸀ഀഀ 30.11.2012 20:14 422 filestream.hdr
      ਍㰀戀爀㸀ഀഀ C:\fsblobs\documents>cd $*
      ਍㰀戀爀㸀ഀഀ C:\fsblobs\documents\$FSLOG>dir
      ਍ഀഀ 30.11.2012 20:14 DIR .
      ਍㌀ ⸀㄀㄀⸀㈀ ㄀㈀  ㈀ 㨀㄀㐀    䐀䤀刀         ⸀⸀㰀戀爀㸀ഀഀ ਍㰀戀爀㸀ഀഀ ਍伀昀挀漀甀爀猀攀Ⰰ 琀栀攀 昀漀氀搀攀爀 椀猀 㰀䈀㸀猀琀椀氀氀 攀洀瀀琀礀㰀⼀䈀㸀⸀ 圀攀 栀愀瘀攀 渀漀琀 猀琀漀爀攀搀 愀渀礀琀栀椀渀最 礀攀琀 ∀椀渀∀ 琀栀攀 昀椀氀攀猀琀爀攀愀洀 昀椀氀攀最爀漀甀瀀⸀㰀戀爀㸀ഀഀ
      ਍一漀琀攀 琀栀攀 ∀␀䘀匀䰀伀䜀∀ 搀椀爀攀挀琀漀爀礀⸀ 吀栀椀猀 椀猀 愀 猀漀爀琀 漀昀 愀 ∀琀爀愀渀猀愀挀琀椀漀渀 氀漀最∀ ⠀挀漀渀琀愀椀渀攀爀⤀ 昀漀爀 攀瘀攀渀琀猀 漀渀 戀氀漀戀猀 琀栀愀琀 愀爀攀 最漀椀渀最㰀戀爀㸀ഀഀ to be stored in the filestream container.
      ਍㰀戀爀㸀ഀഀ As we will see later on, anytime you create a table using filestream for blob storage, we will see a subfolder added
      ਍椀渀 琀栀攀 昀漀爀洀 漀昀 ∀䌀㨀尀昀猀戀氀漀戀猀尀搀漀挀甀洀攀渀琀猀尀最甀椀搀∀ 氀椀欀攀 昀漀爀 攀砀愀洀瀀氀攀 ∀䌀㨀尀昀猀戀氀漀戀猀尀搀漀挀甀洀攀渀琀猀尀㈀㔀㠀㤀㈀攀㄀㜀ⴀ㠀 昀㘀ⴀ㐀㄀㔀昀ⴀ㤀挀㘀㔀ⴀ㜀㌀㤀㔀㘀㌀㈀昀 ㈀㈀㌀⸀∀㰀戀爀㸀ഀഀ Then, inside such a GUID named container, we will find the blobs associated with that table. Later more on this.
      ਍㰀戀爀㸀ഀഀ Note:
      ਍吀栀攀 ∀␀䘀匀䰀伀䜀∀ 搀椀爀攀挀琀漀爀礀 椀猀 ⠀漀昀挀漀甀爀猀攀⤀ 瘀攀爀礀 猀攀渀猀椀琀椀瘀攀 琀漀 ∀昀漀爀攀椀最渀∀ 昀椀氀攀猀⸀ 䤀昀Ⰰ 漀渀 愀 琀攀猀琀 猀礀猀琀攀洀Ⰰ 礀漀甀 瀀氀愀挀攀 愀渀礀 漀戀樀攀挀琀 琀栀攀爀攀㰀戀爀㸀ഀഀ it will have an effect to the status of the database of which this filestream container is associated with.
      ਍夀漀甀 洀椀最栀琀 攀瘀攀渀 攀渀搀 甀瀀 眀椀琀栀 愀 匀甀猀瀀攀挀琀 搀愀琀愀戀愀猀攀⸀ 䤀琀✀猀 攀愀猀礀 琀漀 爀攀挀漀瘀攀爀 昀爀漀洀 琀栀椀猀Ⰰ 漀昀挀漀甀爀猀攀⸀㰀戀爀㸀ഀഀ But it's an illustration that any interactive access to filestream containers (e.g. using OS commands) must be avoided.
      ਍㰀戀爀㸀ഀഀ
      ਍䰀攀琀✀猀 渀漀眀 猀攀攀 眀栀愀琀 匀儀䰀 匀攀爀瘀攀爀 ∀琀栀椀渀欀猀∀ 眀栀愀琀 眀攀 栀愀瘀攀 愀猀 搀愀琀愀戀愀猀攀 昀椀氀攀猀㨀㰀戀爀㸀ഀഀ
      ਍㰀昀漀渀琀 昀愀挀攀㴀∀挀漀甀爀椀攀爀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀氀甀攀∀㸀ഀഀ ਍匀䔀䰀䔀䌀吀 昀椀氀攀开椀搀Ⰰ 琀礀瀀攀开搀攀猀挀Ⰰ 渀愀洀攀Ⰰ 瀀栀礀猀椀挀愀氀开渀愀洀攀 䘀刀伀䴀 猀礀猀⸀搀愀琀愀戀愀猀攀开昀椀氀攀猀㰀戀爀㸀ഀഀ
      ਍昀椀氀攀开椀搀⸀⸀⸀琀礀瀀攀开搀攀猀挀⸀⸀⸀⸀⸀渀愀洀攀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀瀀栀礀猀椀挀愀氀开渀愀洀攀㰀戀爀㸀ഀഀ 1.........ROWS..........SALES...........c:\mssql\data\SALES.mdf
      ਍㈀⸀⸀⸀⸀⸀⸀⸀⸀⸀䰀伀䜀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀匀䄀䰀䔀匀开䰀伀䜀开  ㄀⸀⸀⸀挀㨀尀洀猀猀焀氀尀搀愀琀愀尀匀䄀䰀䔀匀开䰀伀䜀开  ㄀⸀氀搀昀㰀戀爀㸀ഀഀ 3.........ROWS..........SALES_DATA_01...c:\mssql\data\SALES_DATA_01.ndf
      ਍㐀⸀⸀⸀⸀⸀⸀⸀⸀⸀刀伀圀匀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀匀䄀䰀䔀匀开䤀一䐀䔀堀开 ㄀⸀⸀挀㨀尀洀猀猀焀氀尀搀愀琀愀尀匀䄀䰀䔀匀开䤀一䐀䔀堀开 ㄀⸀渀搀昀㰀戀爀㸀ഀഀ 65537.....FILESTREAM....Documents.......c:\fsblobs\documents
      ਍㰀戀爀㸀ഀഀ ਍匀漀Ⰰ 琀栀攀 爀攀最甀氀愀爀 搀愀琀愀戀愀猀攀 昀椀氀攀猀 愀爀攀 愀氀眀愀礀猀 漀昀 ∀琀礀瀀攀∀ 刀伀圀匀Ⰰ 漀爀 䰀伀䜀 ⠀椀渀 挀愀猀攀 漀昀 琀爀愀渀猀愀挀琀椀漀渀氀漀最 昀椀氀攀猀⤀⸀㰀戀爀㸀ഀഀ Indeed, we now have a new type of file, of type FILESTREAM, associated with the physical location "c:\fsblobs\documents".
      ਍㰀戀爀㸀ഀഀ
      ਍㰀䈀㸀㰀唀㸀圀栀愀琀 猀琀漀爀愀最攀 挀愀渀 戀攀 甀猀攀搀㨀㰀⼀唀㸀㰀⼀䈀㸀㰀戀爀㸀ഀഀ
      ਍吀栀攀 搀椀猀欀⠀猀⤀ 琀栀愀琀 栀漀氀搀 琀栀攀 昀椀氀攀猀琀爀攀愀洀 挀漀渀琀愀椀渀攀爀猀 搀漀攀猀 渀漀琀 渀攀攀搀 琀漀 戀攀 氀漀挀愀氀 搀椀猀欀猀⸀㰀戀爀㸀ഀഀ They can easily be LUNs from a SAN as well.
      ਍䠀漀眀攀瘀攀爀Ⰰ 愀氀氀 昀椀氀攀猀礀猀琀攀洀猀 猀栀漀甀氀搀 戀攀 一吀䘀匀 昀漀爀洀愀琀琀攀搀⸀㰀戀爀㸀ഀഀ
      ਍吀栀攀爀攀 愀爀攀 洀愀渀礀 漀琀栀攀爀 挀漀渀猀椀搀攀爀愀琀椀漀渀猀Ⰰ 攀猀瀀攀挀椀愀氀氀礀 昀漀爀 漀戀琀愀椀渀椀渀最 琀栀攀 戀攀猀琀 瀀攀爀昀漀爀洀愀渀挀攀⸀㰀戀爀㸀ഀഀ For example, cluster (block) size can be important, as well as the RAID level, to name a few.
      ਍ഀഀ ਍ഀഀ
      ਍㰀戀爀㸀ഀഀ ਍㰀栀㌀㸀㌀⸀㌀ 䄀搀搀椀渀最 愀 戀氀漀戀⸀㰀⼀栀㈀㸀ഀഀ ਍䰀攀琀✀猀 挀爀攀愀琀攀 愀 䐀伀䌀匀 琀愀戀氀攀Ⰰ 眀椀琀栀 猀漀洀攀 爀攀最甀氀愀爀 搀愀琀愀琀礀瀀攀猀Ⰰ 愀渀搀 漀昀挀漀甀爀猀攀 愀 搀愀琀愀琀礀瀀攀 漀昀 搀愀琀愀琀礀瀀攀 瘀愀爀戀椀渀愀爀礀⠀洀愀砀⤀⸀㰀戀爀㸀ഀഀ
      ਍ഀഀ ਍ഀഀ CREATE TABLE DOCS
      ਍⠀㰀戀爀㸀ഀഀ   FileStreamID UNIQUEIDENTIFIER ROWGUIDCOL NOT NULL UNIQUE DEFAULT NEWSEQUENTIALID(),
      ਍☀渀戀猀瀀 䐀伀䌀开䔀堀吀䔀一匀䤀伀一 嘀䄀刀䌀䠀䄀刀⠀㄀ ⤀Ⰰ㰀戀爀㸀ഀഀ   DOC_NAME VARCHAR(256),
      ਍☀渀戀猀瀀 㰀䈀㸀䐀伀䌀唀䴀䔀一吀 嘀䄀刀䈀䤀一䄀刀夀⠀䴀䄀堀⤀ 䘀䤀䰀䔀匀吀刀䔀䄀䴀㰀⼀䈀㸀㰀戀爀㸀ഀഀ ) FILESTREAM_ON Documents
      ਍䜀伀㰀戀爀㸀ഀഀ
      ਍㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀氀愀挀欀∀㸀ഀഀ ਍䰀攀琀✀猀 琀愀欀攀 愀 氀漀漀欀 愀琀 琀栀攀 挀漀氀甀洀渀猀 䤀 琀漀漀欀 栀攀爀攀⸀㰀戀爀㸀ഀഀ
      ਍㴀㸀 吀栀攀 ∀䐀伀䌀开䔀堀吀䔀一匀䤀伀一∀ 愀渀搀 ∀䐀伀䌀开一䄀䴀䔀∀ 愀爀攀 猀椀洀瀀氀礀 漀瀀琀椀漀渀愀氀⸀ 吀栀攀礀 愀爀攀 樀甀猀琀 琀栀攀爀攀 昀漀爀 椀渀昀漀爀洀愀琀椀漀渀愀氀 瀀甀爀瀀漀猀攀猀⸀䤀昀 礀漀甀 眀愀渀琀Ⰰ㰀戀爀㸀ഀഀ we could have left those out. It's only that it might be handy to have the "document name" (blobname), and
      ਍琀栀攀 昀椀氀攀 攀砀琀攀渀猀椀漀渀 ⠀氀椀欀攀⸀ 樀瀀最 漀爀 ⸀砀氀猀⤀ 爀攀最椀猀琀攀爀攀搀 椀渀 琀栀攀 琀愀戀氀攀 愀猀 眀攀氀氀⸀㰀戀爀㸀ഀഀ
      ਍㴀㸀 吀栀攀 渀愀洀攀 ∀䘀椀氀攀匀琀爀攀愀洀䤀䐀∀ 椀猀 渀漀琀 愀 爀攀焀甀椀爀攀搀 挀漀氀甀洀渀渀愀洀攀⸀ 䤀琀 挀漀甀氀搀 樀甀猀琀 愀猀 眀攀氀氀 栀愀瘀攀 戀攀攀渀 渀愀洀攀搀 ∀椀搀∀ 漀爀 愀渀漀琀栀攀爀 爀攀愀猀漀渀愀戀氀攀 渀愀洀攀⸀㰀戀爀㸀ഀഀ But we must have such a field, and it must be of a "uniqueidentifier" datatype.
      ਍吀栀椀猀 椀猀 愀 ㄀㘀ⴀ戀礀琀攀 戀椀渀愀爀礀 瘀愀氀甀攀 琀栀愀琀 猀栀漀甀氀搀 愀挀琀甀愀氀氀礀 昀甀渀挀琀椀漀渀 愀猀 愀 ∀圀漀爀氀搀 圀椀搀攀 最氀漀戀愀氀氀礀 甀渀椀焀甀攀 椀搀攀渀琀椀昀椀攀爀∀ ⠀䜀唀䤀䐀⤀⸀㰀戀爀㸀ഀഀ
      ਍䄀猀 眀攀 眀椀氀氀 猀攀攀Ⰰ 椀琀 椀猀 甀猀攀搀 琀漀 㰀䤀㸀甀渀椀焀甀攀氀礀 搀攀琀攀爀洀椀渀攀㰀⼀䤀㸀 琀栀攀 昀椀氀攀 愀猀猀漀挀椀愀琀攀搀 眀椀琀栀 琀栀愀琀 爀攀挀漀爀搀Ⰰ 漀渀 琀栀攀 昀椀氀攀猀礀猀琀攀洀⸀㰀戀爀㸀ഀഀ Often, we use the NEWID() function, or NEWSEQUENTIALID() function, to let SQL Server itself automatically generate GUIDs
      ਍昀漀爀 愀渀礀 渀攀眀 爀攀挀漀爀搀⸀ 一漀琀攀 琀栀愀琀 眀攀 栀愀瘀攀 甀猀攀搀 ∀䐀䔀䘀䄀唀䰀吀 一䔀圀匀䔀儀唀䔀一吀䤀䄀䰀䤀䐀⠀⤀∀ 愀猀 愀 搀攀昀愀甀氀琀Ⰰ 猀漀 匀儀䰀 匀攀爀瘀攀爀 眀椀氀氀 栀愀渀搀氀攀 椀琀㰀戀爀㸀ഀഀ automatically, if we (or an application) do not provide a GUID for a new record.
      ਍㰀戀爀㸀ഀഀ As "UNIQUEIDENTIFIER" should result in unique identifiers anyway, you might wonder what the "ROWGUIDCOL" is doing here.
      ਍䤀 戀攀氀椀攀瘀攀 椀琀 椀猀 渀漀琀 愀戀猀漀氀甀琀攀氀礀 渀攀挀挀攀猀猀愀爀礀Ⰰ 戀甀琀 琀栀攀 攀昀昀椀挀椀攀渀挀礀 最攀琀猀 甀瀀 戀礀 甀猀椀渀最 唀一䤀儀唀䔀䤀䐀䔀一吀䤀䘀䤀䔀刀 眀椀琀栀 琀栀攀 刀伀圀䜀唀䤀䐀䌀伀䰀 瀀爀漀瀀攀爀琀礀⸀㰀戀爀㸀ഀഀ ਍㰀戀爀㸀ഀഀ => Lastly, we have a field (DOCUMENT) which is of datatype "varbinary", and this one refers to our blob.
      ਍一漀琀攀 琀栀愀琀 椀渀 琀栀椀猀 挀漀氀甀洀渀 搀攀挀氀愀爀愀琀椀漀渀Ⰰ 琀栀攀 挀氀愀甀猀攀 ∀䘀䤀䰀䔀匀吀刀䔀䄀䴀∀ 椀猀 渀攀挀挀攀猀猀愀爀礀 琀漀 椀渀昀漀爀洀 匀儀䰀 匀攀爀瘀攀爀 琀栀愀琀㰀戀爀㸀ഀഀ we are going to use the FILESTREAM feature for storage of blobs.
      ਍㰀戀爀㸀ഀഀ
      ਍匀甀瀀瀀漀猀攀 琀栀愀琀 眀攀 栀愀瘀攀 琀栀攀 昀椀氀攀 ⠀漀爀 琀栀攀 ∀戀氀漀戀∀⤀ 挀㨀尀琀攀洀瀀尀猀愀氀攀猀⸀砀氀猀⸀ 圀攀 愀爀攀 最漀椀渀最 琀漀 猀琀漀爀攀 琀栀椀猀 愀猀 愀 戀氀漀戀 椀渀 漀甀爀㰀戀爀㸀ഀഀ "Documents" filestream filegroup (which actually is the "c:\fsblobs\documents" container).
      ਍㰀戀爀㸀ഀഀ Take a look at the following TSQL:
      ਍㰀戀爀㸀ഀഀ ਍ഀഀ INSERT INTO DOCS (DOC_EXTENSION, DOC_NAME, Document)
      ਍匀䔀䰀䔀䌀吀㰀戀爀㸀ഀഀ 'xls' AS DOC_EXTENSION,
      ਍ ✀猀愀氀攀猀⸀砀氀猀✀ 䄀匀 䐀伀䌀开一䄀䴀䔀Ⰰ㰀戀爀㸀ഀഀ * FROM OPENROWSET(BULK 'c:\temp\sales.xls', SINGLE_BLOB) AS Document
      ਍䜀伀㰀戀爀㸀ഀഀ
      ਍ഀഀ ਍ഀഀ Now, let's see what record we have in the table DOCS:
      ਍㰀戀爀㸀ഀഀ ਍ഀഀ SELECT * FROM DOCS
      ਍㰀戀爀㸀ഀഀ FileStreamID............................DOC_EXTENSION....DOC_NAME.........DOCUMENT
      ਍㘀㐀㈀㌀䐀䄀㠀㈀ⴀ㔀㔀㈀㌀ⴀ䔀㈀㄀㄀ⴀ䈀㘀㠀㜀ⴀ   䄀䔀㐀䈀㌀䘀 㘀 ⸀⸀⸀ 砀氀猀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀猀愀氀攀猀⸀砀氀猀⸀⸀⸀⸀⸀⸀⸀⸀ 砀䐀 䌀䘀㄀㄀䔀 䄀㄀䈀㄀㄀ ⠀攀琀挀⤀㰀戀爀㸀ഀഀ
      ਍ഀഀ ਍ഀഀ
      ਍㰀戀爀㸀ഀഀ ਍㰀栀㌀㸀㌀⸀㐀 䄀渀愀氀礀猀椀猀 漀昀 戀氀漀戀 猀琀漀爀愀最攀⸀㰀⼀栀㈀㸀ഀഀ ਍㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀爀攀搀∀㸀ഀഀ ⇒ Let's take a look at the database pages first:
      ਍㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀氀愀挀欀∀㸀ഀഀ
      ਍ഀഀ The "sales.xls" file, I loaded "into" the DOCS table (in reality in the filestream tablespace),
      ਍椀猀 㠀㤀㈀㄀ 䬀䈀 ⠀挀椀爀挀愀 㤀䴀䈀⤀ 椀渀 猀椀稀攀Ⰰ 眀栀椀挀栀 焀甀愀氀椀昀椀攀猀 愀猀 愀 氀愀爀最攀 䈀䰀伀䈀⸀㰀戀爀㸀ഀഀ
      ਍䤀渀 琀栀攀 挀栀愀瀀琀攀爀猀 愀戀漀瘀攀Ⰰ 眀攀 栀愀瘀攀 猀攀攀渀 眀栀椀挀栀 瀀愀最攀猀 椀渀 琀栀攀 匀䄀䰀䔀匀 搀愀琀愀戀愀猀攀 眀攀爀攀 愀氀氀漀挀愀琀攀搀Ⰰ 愀昀琀攀爀 ⠀漀渀氀礀⤀ 氀漀愀搀椀渀最㰀戀爀㸀ഀഀ an employee photo (albert.jpg). You know how to do that using the DBCC PAGE statement.
      ਍圀攀 欀渀漀眀 琀栀愀琀 愀昀琀攀爀 瀀愀最攀 ㌀㨀㜀㈀Ⰰ 愀氀氀 瀀愀最攀猀 眀攀爀攀 ∀昀爀攀攀∀⸀ 䠀攀爀攀 椀猀 愀 瀀愀爀琀椀愀氀 漀甀琀瀀甀琀 愀最愀椀渀㨀㰀戀爀㸀ഀഀ
      ਍㰀䈀㸀ⴀ 匀椀琀甀愀琀椀漀渀 戀攀昀漀爀攀 昀椀氀攀猀琀爀攀愀洀 愀渀搀 戀攀昀漀爀攀 氀漀愀搀椀渀最 ∀猀愀氀攀猀⸀砀氀猀∀㨀㰀⼀䈀㸀㰀戀爀㸀ഀഀ
      ਍㰀昀漀渀琀 昀愀挀攀㴀∀挀漀甀爀椀攀爀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀氀甀攀∀㸀ഀഀ ਍䄀氀氀漀挀愀琀椀漀渀 匀琀愀琀甀猀㰀戀爀㸀ഀഀ
      ਍䜀䄀䴀 ⠀㌀㨀㈀⤀ 㴀 䄀䰀䰀伀䌀䄀吀䔀䐀⸀⸀⸀⸀匀䜀䄀䴀 ⠀㌀㨀㌀⤀ 㴀 一伀吀 䄀䰀䰀伀䌀䄀吀䔀䐀⸀⸀⸀⸀倀䘀匀 ⠀㌀㨀㄀⤀ 㴀  砀㐀  䄀䰀䰀伀䌀䄀吀䔀䐀    开倀䌀吀开䘀唀䰀䰀㰀戀爀㸀ഀഀ DIFF(3:6) = CHANGED........ML (3:7) = NOT MIN_LOGGED
      ਍㰀戀爀㸀ഀഀ PFS: Page Alloc Status @0x000000000C95A000
      ਍㰀戀爀㸀ഀഀ (3:0)....- (3:3)...=.....ALLOCATED...0_PCT_FULL
      ਍⠀㌀㨀㐀⤀⸀⸀⸀⸀ⴀ ⠀㌀㨀㔀⤀⸀⸀⸀㴀 一伀吀 䄀䰀䰀伀䌀䄀吀䔀䐀⸀⸀⸀ 开倀䌀吀开䘀唀䰀䰀 㰀戀爀㸀                             ഀഀ (3:6)....- (3:7)...=.....ALLOCATED...0_PCT_FULL
      ਍⠀㌀㨀㠀⤀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀㴀⸀⸀⸀⸀⸀䄀䰀䰀伀䌀䄀吀䔀䐀⸀⸀㔀 开倀䌀吀开䘀唀䰀䰀                     䴀椀砀攀搀 䔀砀琀㰀戀爀㸀ഀഀ (3:9)..............=.....ALLOCATED...0_PCT_FULL IAM Page Mixed Ext
      ਍⠀㌀㨀㄀ ⤀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀㴀⸀⸀⸀⸀⸀䄀䰀䰀伀䌀䄀吀䔀䐀⸀⸀㔀 开倀䌀吀开䘀唀䰀䰀                     䴀椀砀攀搀 䔀砀琀㰀戀爀㸀ഀഀ (3:11).............=.....ALLOCATED...0_PCT_FULL IAM Page Mixed Ext
      ਍⠀㌀㨀㄀㈀⤀⸀⸀⸀ⴀ ⠀㌀㨀㄀㔀⤀⸀⸀㴀⸀⸀⸀⸀⸀䄀䰀䰀伀䌀䄀吀䔀䐀⸀㄀  开倀䌀吀开䘀唀䰀䰀                     䴀椀砀攀搀 䔀砀琀㰀戀爀㸀ഀഀ (3:16)...- (3:63)..=.....ALLOCATED.100_PCT_FULL
      ਍⠀㌀㨀㘀㐀⤀⸀⸀⸀ⴀ ⠀㌀㨀㘀㘀⤀⸀⸀㴀⸀⸀⸀⸀⸀䄀䰀䰀伀䌀䄀吀䔀䐀⸀㄀  开倀䌀吀开䘀唀䰀䰀                     䴀椀砀攀搀 䔀砀琀㰀戀爀㸀ഀഀ (3:67)...- (3:71)..= NOT ALLOCATED...0_PCT_FULL
      ਍⠀㌀㨀㜀㈀⤀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀㴀⸀⸀⸀⸀⸀䄀䰀䰀伀䌀䄀吀䔀䐀⸀㄀  开倀䌀吀开䘀唀䰀䰀 㰀戀爀㸀                             ഀഀ (3:73)...- (3:5119)= NOT ALLOCATED...0_PCT_FULL
      ਍㰀戀爀㸀ഀഀ ਍ഀഀ Now, we have "loaded" are large blob, but it should NOT have been loaded into database pages.
      ਍吀栀攀 戀氀漀戀 ∀猀愀氀攀猀⸀砀氀猀∀ 椀猀 猀甀瀀瀀漀猀攀搀 琀漀 氀椀瘀攀 漀渀 琀栀攀 昀椀氀攀猀礀猀琀攀洀⸀ 匀漀 氀攀琀✀猀 搀甀洀瀀 琀栀攀 倀䘀匀 瀀愀最攀 愀最愀椀渀㨀㰀戀爀㸀ഀഀ ਍㰀戀爀㸀ഀഀ - Situation after enabling filestream and after loading "sales.xls":
      ਍ഀഀ ਍ഀഀ
      ਍⠀䄀氀氀漀挀愀琀椀漀渀 匀琀愀琀甀猀㰀戀爀㸀ഀഀ
      ਍䜀䄀䴀 ⠀㌀㨀㈀⤀ 㴀 䄀䰀䰀伀䌀䄀吀䔀䐀⸀⸀⸀⸀匀䜀䄀䴀 ⠀㌀㨀㌀⤀ 㴀 一伀吀 䄀䰀䰀伀䌀䄀吀䔀䐀⸀⸀⸀⸀倀䘀匀 ⠀㌀㨀㄀⤀ 㴀  砀㐀  䄀䰀䰀伀䌀䄀吀䔀䐀    开倀䌀吀开䘀唀䰀䰀㰀戀爀㸀ഀഀ DIFF(3:6) = CHANGED........ML (3:7) = NOT MIN_LOGGED
      ਍㰀戀爀㸀ഀഀ PFS: Page Alloc Status @0x000000000C95A000
      ਍㰀戀爀㸀ഀഀ (3:0)....- (3:3)...=.....ALLOCATED...0_PCT_FULL
      ਍⠀㌀㨀㐀⤀⸀⸀⸀⸀ⴀ ⠀㌀㨀㔀⤀⸀⸀⸀㴀 一伀吀 䄀䰀䰀伀䌀䄀吀䔀䐀⸀⸀⸀ 开倀䌀吀开䘀唀䰀䰀 㰀戀爀㸀                             ഀഀ (3:6)....- (3:7)...=.....ALLOCATED...0_PCT_FULL
      ਍⠀㌀㨀㠀⤀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀㴀⸀⸀⸀⸀⸀䄀䰀䰀伀䌀䄀吀䔀䐀⸀⸀㔀 开倀䌀吀开䘀唀䰀䰀                     䴀椀砀攀搀 䔀砀琀㰀戀爀㸀ഀഀ (3:9)..............=.....ALLOCATED...0_PCT_FULL IAM Page Mixed Ext
      ਍⠀㌀㨀㄀ ⤀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀㴀⸀⸀⸀⸀⸀䄀䰀䰀伀䌀䄀吀䔀䐀⸀⸀㔀 开倀䌀吀开䘀唀䰀䰀                     䴀椀砀攀搀 䔀砀琀㰀戀爀㸀ഀഀ (3:11).............=.....ALLOCATED...0_PCT_FULL IAM Page Mixed Ext
      ਍⠀㌀㨀㄀㈀⤀⸀⸀⸀ⴀ ⠀㌀㨀㄀㔀⤀⸀⸀㴀⸀⸀⸀⸀⸀䄀䰀䰀伀䌀䄀吀䔀䐀⸀㄀  开倀䌀吀开䘀唀䰀䰀                     䴀椀砀攀搀 䔀砀琀㰀戀爀㸀ഀഀ (3:16)...- (3:63)..=.....ALLOCATED 100_PCT_FULL
      ਍⠀㌀㨀㘀㐀⤀⸀⸀⸀ⴀ ⠀㌀㨀㘀㘀⤀⸀⸀㴀⸀⸀⸀⸀⸀䄀䰀䰀伀䌀䄀吀䔀䐀 ㄀  开倀䌀吀开䘀唀䰀䰀                     䴀椀砀攀搀 䔀砀琀㰀戀爀㸀ഀഀ (3:67).............=.....ALLOCATED..50_PCT_FULL Mixed Ext
      ਍⠀㌀㨀㘀㠀⤀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀㴀⸀⸀⸀⸀⸀䄀䰀䰀伀䌀䄀吀䔀䐀⸀⸀⸀ 开倀䌀吀开䘀唀䰀䰀           䤀䄀䴀 倀愀最攀  䴀椀砀攀搀 䔀砀琀㰀戀爀㸀ഀഀ (3:69).............=.....ALLOCATED...0_PCT_FULL Mixed Ext
      ਍⠀㌀㨀㜀 ⤀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀㴀⸀⸀⸀⸀⸀䄀䰀䰀伀䌀䄀吀䔀䐀⸀⸀⸀ 开倀䌀吀开䘀唀䰀䰀           䤀䄀䴀 倀愀最攀  䴀椀砀攀搀 䔀砀琀㰀戀爀㸀ഀഀ (3:71).............= NOT ALLOCATED...0_PCT_FULL
      ਍⠀㌀㨀㜀㈀⤀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀⸀㴀⸀⸀⸀⸀⸀䄀䰀䰀伀䌀䄀吀䔀䐀⸀㄀  开倀䌀吀开䘀唀䰀䰀 㰀戀爀㸀                             ഀഀ (3:73)...- (3:5119)= NOT ALLOCATED...0_PCT_FULL
      ਍㰀戀爀㸀ഀഀ ਍ഀഀ From this, it is easy to conclude that our sales.xls blob (8MB in size), is not stored inside the database.
      ਍䤀昀 椀琀 眀漀甀氀搀Ⰰ 琀栀攀渀 愀戀漀甀琀 ㄀    搀愀琀愀戀愀猀攀 瀀愀最攀猀 眀漀甀氀搀 栀愀瘀攀 戀攀攀渀 愀氀氀漀挀愀琀攀搀Ⰰ 眀栀椀挀栀 椀猀 渀漀琀 琀栀攀 挀愀猀攀⸀㰀戀爀㸀ഀഀ You can see from the output, that the range of pages (3:73) - (3:5119) are still free, as they were before.
      ਍㰀戀爀㸀ഀഀ So, the blob is not in the database. Now let's take a look how it is organized in "c:\fsblobs\documents",
      ਍眀栀椀挀栀 椀猀 琀栀攀 挀漀渀琀愀椀渀攀爀 漀昀 漀甀爀 昀椀氀攀猀琀爀攀愀洀 昀椀氀攀最爀漀甀瀀⸀㰀戀爀㸀ഀഀ
      ਍一漀琀攀㨀 琀栀攀爀攀 愀爀攀 樀甀猀琀 愀 昀攀眀 挀栀愀渀最攀猀 琀栀漀甀最栀Ⰰ 氀椀欀攀 琀栀攀 猀琀漀爀愀最攀 漀昀 琀栀攀 䐀伀䌀匀 琀愀戀氀攀 椀渀 瀀愀最攀 ㌀㨀㘀㜀Ⰰ 愀渀搀㰀戀爀㸀ഀഀ the two new IAM pages. But there are no new pages due to blob storage. We will come back on the IAM later on.
      ਍㰀戀爀㸀ഀഀ
      ਍㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀爀攀搀∀㸀ഀഀ ⇒ Let's take a look at the filesystem:
      ਍㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀氀愀挀欀∀㸀ഀഀ
      ਍伀渀 愀 吀攀猀琀 猀礀猀琀攀洀Ⰰ 礀漀甀 挀漀甀氀搀 戀爀漀眀猀攀 愀爀漀甀渀搀 琀栀爀漀甀最栀 琀栀攀 猀甀戀搀椀爀猀 眀椀琀栀椀渀 琀栀攀 ∀挀㨀尀昀猀戀氀漀戀猀尀搀漀挀甀洀攀渀琀猀∀ 搀椀爀攀挀琀漀爀礀⸀㰀戀爀㸀ഀഀ Don't do that on anything labeled "production".
      ਍㰀戀爀㸀ഀഀ In the figure below, you see how the storage is organized.
      ਍㰀戀爀㸀ഀഀ Fig 7. Folder structure of the FILESTREAM container/filegroup after storing one blob.
      ਍㰀戀爀㸀ഀഀ ਍㰀戀爀㸀ഀഀ
      ਍䠀攀爀攀 礀漀甀 猀攀攀 洀礀 ∀猀愀氀攀猀⸀砀氀猀∀ 戀氀漀戀Ⰰ 眀椀琀栀 攀砀愀挀琀氀礀 琀栀攀 猀愀洀攀 猀椀稀攀 愀猀 琀栀攀 漀爀椀最椀渀愀氀 昀椀氀攀⸀㰀戀爀㸀ഀഀ Note the different levels of the subdirectories, each named as a GUID identifier.
      ਍㰀戀爀㸀ഀഀ The "upper" GUID, represent the DOCS table.
      ਍吀栀攀 ∀氀漀眀攀爀∀ 䜀唀䤀䐀Ⰰ 爀攀瀀爀攀猀攀渀琀 琀栀攀 ∀䐀伀䌀唀䴀䔀一吀∀ 挀漀氀甀洀渀 漀昀 琀栀攀 䐀伀䌀匀 琀愀戀氀攀⸀㰀戀爀㸀ഀഀ
      ਍䰀攀琀✀猀 猀攀攀 眀栀愀琀 栀愀瀀瀀攀渀猀 椀昀 眀攀 氀漀愀搀 愀 猀攀挀漀渀搀 戀氀漀戀 ∀椀渀琀漀∀ 琀栀攀 䐀伀䌀匀 琀愀戀氀攀⸀㰀戀爀㸀ഀഀ This time, we use the "sales2.xls" file, with a size of 5283KB, stored in "c:\temp".
      ਍吀漀 氀漀愀搀 椀渀 椀渀琀漀 琀栀攀 昀椀氀攀猀琀爀攀愀洀 挀漀渀琀愀椀渀攀爀Ⰰ 眀攀 挀愀渀 甀猀攀㨀㰀戀爀㸀ഀഀ
      ਍㰀昀漀渀琀 昀愀挀攀㴀∀挀漀甀爀椀攀爀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀氀甀攀∀㸀ഀഀ ਍䤀一匀䔀刀吀 䤀一吀伀 䐀伀䌀匀 ⠀䐀伀䌀开䔀堀吀䔀一匀䤀伀一Ⰰ 䐀伀䌀开一䄀䴀䔀Ⰰ 䐀漀挀甀洀攀渀琀⤀㰀戀爀㸀ഀഀ SELECT
      ਍ ✀砀氀猀✀ 䄀匀 䐀伀䌀开䔀堀吀䔀一匀䤀伀一Ⰰ㰀戀爀㸀ഀഀ 'sales2.xls' AS DOC_NAME,
      ਍ ⨀ 䘀刀伀䴀 伀倀䔀一刀伀圀匀䔀吀⠀䈀唀䰀䬀 ✀挀㨀尀琀攀洀瀀尀猀愀氀攀猀㈀⸀砀氀猀✀Ⰰ 匀䤀一䜀䰀䔀开䈀䰀伀䈀⤀  䄀匀 䐀漀挀甀洀攀渀琀㰀戀爀㸀ഀഀ GO
      ਍㰀戀爀㸀ഀഀ ਍㰀戀爀㸀ഀഀ Fig 8. After storing the second blob.
      ਍㰀戀爀㸀ഀഀ ਍㰀戀爀㸀ഀഀ
      ਍㰀戀爀㸀 ഀഀ TSQL and Win32 API:
      ਍㰀戀爀㸀ഀഀ - TSQL:
      ਍㰀戀爀㸀ഀഀ Using TSQL, you have full control on columns with blob data. You can use INSERT, UPDATE, DELETE
      ਍漀渀 琀愀戀氀攀猀Ⰰ 椀渀 琀栀攀 ∀甀猀甀愀氀∀ 眀愀礀⸀ 䠀漀眀攀瘀攀爀Ⰰ 椀昀 礀漀甀 眀漀甀氀搀 搀攀氀攀琀攀 愀 爀漀眀 眀椀琀栀 戀椀渀愀爀礀 搀愀琀愀Ⰰ㰀戀爀㸀ഀഀ you probably will not see that the object is removed from the filestream folder immediately.
      ਍䘀椀爀猀琀Ⰰ 琀栀攀 漀戀樀攀挀琀 椀猀 ∀琀漀洀戀猀琀漀渀攀搀∀ 愀渀搀 愀 猀漀爀琀 漀昀 ∀最愀爀戀愀最攀 挀漀氀氀攀挀琀漀爀∀ 眀椀氀氀 爀攀洀漀瘀攀 椀琀 瀀攀爀洀愀渀攀渀琀氀礀 氀愀琀攀爀⸀㰀戀爀㸀ഀഀ Sometimes, it is observed that this can take quite a while.
      ਍㰀戀爀㸀ഀഀ There are some "best practices" in using TSQL in relation to tables with blobs.
      ਍匀攀攀 挀栀愀瀀琀攀爀 㐀⸀㰀戀爀㸀ഀഀ
      ਍㰀䈀㸀ⴀ 倀爀漀最爀愀洀洀愀琀椀挀 䄀倀䤀✀猀 琀漀 䘀椀氀攀猀琀爀攀愀洀㨀㰀⼀䈀㸀㰀戀爀㸀ഀഀ
      ਍唀猀椀渀最 䌀⌀Ⰰ 嘀䈀⌀Ⰰ 䌀⬀⬀ 攀琀挀⸀⸀Ⰰ 礀漀甀 挀愀渀 愀挀挀攀猀猀 琀栀攀 戀氀漀戀猀 ∀椀渀 愀 渀攀愀琀 眀愀礀∀ 甀猀椀渀最 匀儀䰀 匀攀爀瘀攀爀㰀戀爀㸀ഀഀ services. This means that manipulating blobs, using the filestream file API is possible.
      ਍吀栀椀猀 愀氀猀漀 洀攀愀渀猀 琀栀愀琀 愀甀琀栀攀渀琀椀挀愀琀椀漀渀 琀漀 匀儀䰀 匀攀爀瘀攀爀 栀愀瘀攀 漀挀挀甀爀爀攀搀⸀㰀戀爀㸀ഀഀ
      ਍唀猀甀愀氀氀礀Ⰰ 愀 栀愀渀搀氀攀 琀漀 琀栀攀 漀戀樀攀挀琀 椀猀 愀焀甀椀爀攀搀⸀ 匀甀挀栀 愀 栀愀渀搀氀攀 挀愀渀 戀攀 搀攀爀椀瘀攀搀 昀爀漀洀 愀 猀漀爀琀 唀一䌀 瀀愀琀栀㰀戀爀㸀ഀഀ to the object. Take a look at this example. Although it's SQL, it shows how a handle
      ਍挀愀渀 戀攀 漀戀琀愀椀渀攀搀⸀ 匀椀洀椀氀愀爀 挀漀搀攀 挀愀渀 戀攀 瀀氀愀挀攀搀 椀渀 漀琀栀攀爀 搀攀瘀攀氀漀瀀椀渀最 攀渀瘀椀爀漀渀洀攀渀琀猀⸀㰀戀爀㸀ഀഀ
      ਍㰀昀漀渀琀 昀愀挀攀㴀∀挀漀甀爀椀攀爀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀氀甀攀∀㸀ഀഀ ਍䐀䔀䌀䰀䄀刀䔀 䀀甀渀挀瀀愀琀栀 瘀愀爀挀栀愀爀⠀洀愀砀⤀㰀戀爀㸀ഀഀ
      ਍匀䔀䰀䔀䌀吀 䀀甀渀挀瀀愀琀栀 㴀 䐀漀挀甀洀攀渀琀⸀倀愀琀栀一愀洀攀⠀⤀㰀戀爀㸀ഀഀ FROM DOCS
      ਍圀䠀䔀刀䔀 䐀伀䌀开一䄀䴀䔀 㴀 ✀猀愀氀攀猀⸀砀氀猀✀㰀戀爀㸀ഀഀ
      ਍倀刀䤀一吀 䀀甀渀挀瀀愀琀栀㰀戀爀㸀ഀഀ
      ਍尀尀圀㈀䬀㠀猀爀瘀㄀尀䴀匀匀儀䰀匀䔀刀嘀䔀刀尀瘀㄀尀匀䄀䰀䔀匀尀搀戀漀尀䐀伀䌀匀尀䐀伀䌀唀䴀䔀一吀尀䘀䈀㌀ 䔀䌀䔀㔀ⴀ䄀㌀㌀䌀ⴀ䔀㈀㄀㄀ⴀ㠀䘀䐀䌀ⴀ䘀 㐀䐀䄀㈀㤀㄀㔀䔀㘀㤀㰀戀爀㸀 ഀഀ ਍㰀昀漀渀琀 昀愀挀攀㴀∀愀爀椀愀氀∀ 猀椀稀攀㴀㈀ 挀漀氀漀爀㴀∀戀氀愀挀欀∀㸀ഀഀ
      ਍㰀戀爀㸀 ഀഀ Some Further remarks:
      ਍㰀戀爀㸀ഀഀ Up to now, we have seen two types of blob "storage":
      ਍㰀戀爀㸀ഀഀ - "Inline", that is, the blobs are really stored inside the database, in database pages.
      ਍ⴀ ∀䘀椀氀攀猀琀爀攀愀洀∀Ⰰ 眀栀攀爀攀 戀氀漀戀猀 愀爀攀 猀琀漀爀攀搀 椀渀 琀栀攀 昀椀氀攀猀礀猀琀攀洀⸀㰀戀爀㸀ഀഀ
      ਍䄀渀漀琀栀攀爀 漀瀀琀椀漀渀 椀猀 琀栀攀 匀儀䰀 ㈀ ㄀㈀ ∀䘀椀氀攀 吀愀戀氀攀猀∀ 漀瀀琀椀漀渀Ⰰ 眀栀椀挀栀 椀猀 愀挀琀甀愀氀氀礀 愀 渀椀昀琀礀 爀攀昀椀渀攀洀攀渀琀 漀昀 琀栀攀 䘀椀氀攀猀琀爀攀愀洀 昀攀愀琀甀爀攀⸀㰀戀爀㸀ഀഀ
      ਍伀琀栀攀爀 漀瀀琀椀漀渀猀 琀漀 猀琀漀爀攀 戀氀漀戀猀 漀渀 琀栀攀 昀椀氀攀猀礀猀琀攀洀 攀砀椀猀琀猀 愀猀 眀攀氀氀Ⰰ 氀椀欀攀 刀䈀匀 漀昀 䴀椀挀爀漀猀漀昀琀Ⰰ 漀爀 琀栀椀爀搀ⴀ瀀愀爀琀礀 瀀爀漀瀀爀椀攀爀琀礀 猀漀氀甀琀椀漀渀猀㰀戀爀㸀ഀഀ which sometimes can be observed in certain document workflow appliances.
      ਍㰀戀爀㸀ഀഀ If you would be in a situation to select a storage model, then ultimately the Application that will
      ਍戀攀 甀猀攀搀 琀漀 愀挀挀攀猀猀猀 琀栀攀 漀戀樀攀挀琀猀Ⰰ 猀栀漀甀氀搀 戀攀 㰀䈀㸀∀瀀爀椀洀愀爀礀∀㰀⼀䈀㸀 椀渀 礀漀甀爀 搀攀挀椀猀椀漀渀⸀㰀戀爀㸀ഀഀ Anyway, if you are in such a situation, you got a lot of research to do.
      ਍㰀戀爀㸀ഀഀ However, in many documents and blogs you will find the "general" advice to store objects over 1MB
      ਍漀渀 琀栀攀 昀椀氀攀猀礀猀琀攀洀Ⰰ 愀渀搀 猀洀愀氀氀攀爀 漀戀樀攀挀琀猀 椀渀氀椀渀攀⸀㰀戀爀㸀ഀഀ
      ਍伀昀挀漀甀爀猀攀Ⰰ 眀栀愀琀 愀 挀攀爀琀愀椀渀 ∀䄀氀戀攀爀琀∀ 猀愀礀猀 椀猀 渀漀琀 瘀攀爀礀 爀攀氀攀瘀愀渀琀Ⰰ 戀甀琀 洀礀 琀眀漀 挀攀渀琀猀 愀爀攀㨀㰀戀爀㸀ഀഀ
      ਍䤀 眀愀猀 渀攀瘀攀爀 瘀攀爀礀 搀椀猀猀愀瀀漀椀渀琀攀搀 眀椀琀栀 椀渀氀椀渀攀 猀琀漀爀愀最攀Ⰰ 眀椀琀栀 爀攀猀瀀攀挀琀 琀漀 最攀渀攀爀愀氀 瀀攀爀昀漀爀洀愀渀挀攀Ⰰ㰀戀爀㸀ഀഀ and throughput of backup/recovery. So, if the database is to be expected not to grow very large,
      ਍琀栀攀 椀渀氀椀渀攀 漀瀀琀椀漀渀 猀琀愀礀猀 愀瀀瀀攀愀氀椀渀最 琀漀 洀攀⸀㰀戀爀㸀ഀഀ Furthermore, I was never too keen about a "split" situation where one part exists on the filesystem
      ਍愀渀搀 漀琀栀攀爀 瀀愀爀琀猀 椀渀猀椀搀攀 琀栀攀 搀愀琀愀戀愀猀攀⸀㰀戀爀㸀ഀഀ
      ਍䈀甀琀Ⰰ 愀渀 愀瀀瀀氀椀挀愀琀椀漀渀 挀愀渀 昀愀瘀漀甀爀 漀渀攀 洀漀搀攀氀 漀瘀攀爀 琀栀攀 漀琀栀攀爀Ⰰ 猀漀 椀琀✀猀 瀀爀漀戀愀戀氀礀 戀攀猀琀 琀漀 昀漀氀氀漀眀 琀栀攀 愀瀀瀀氀椀挀愀琀椀漀渀猀 昀愀瘀漀甀爀椀琀攀⸀㰀戀爀㸀ഀഀ
      ਍䠀漀眀攀瘀攀爀Ⰰ 洀愀渀礀 眀攀氀氀ⴀ欀渀漀眀渀 匀儀䰀 愀甀琀栀漀爀椀琀椀攀猀 愀搀瘀椀猀攀 琀栀椀猀㨀㰀戀爀㸀ഀഀ Use the filesystem for large objects, and inline for smaller blobs.
      ਍㰀戀爀㸀ഀഀ
      ਍㰀戀爀㸀ഀഀ ਍㰀栀㈀㸀䌀栀愀瀀琀攀爀 㐀⸀ 匀漀洀攀 洀攀琀栀漀搀猀 昀漀爀 猀琀漀爀愀最攀 愀渀搀 爀攀琀爀椀攀瘀愀氀 漀昀 戀氀漀戀猀⸀㰀⼀栀㈀㸀ഀഀ ਍ഀഀ ਍㰀戀爀㸀ഀഀ ਍㰀戀爀㸀ഀഀ ਍㰀戀爀㸀ഀഀ
      ਍㰀戀爀㸀ഀഀ
      ਍㰀戀爀㸀ഀഀ ਍ഀഀ ਍㰀⼀栀琀洀氀㸀�
    Used for "normal" tables, with a few exceptions for certain column datatypes like:
    ਍                               琀攀砀琀⼀渀琀攀砀琀Ⰰ 椀洀愀最攀Ⰰ 瘀愀爀戀椀渀愀爀礀⠀洀愀砀⤀ 愀渀搀 愀 昀攀眀 漀琀栀攀爀猀⸀㰀⼀吀䐀㸀ഀഀ
    Index page
    text/image page