Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / database / SQL-Server

Processing SQL Server FILESTREAM Data: Part 3 - Creating Tables

4.80/5 (3 votes)
24 Sep 2014CPOL2 min read 9.3K  
Utilizing SQL Server FILESTREAM capabilities from .NET

In Parts 1 and 2 of this series, I discussed my experience with the SQL Server FILESTREAM technology, specifically the background of the decision and setup of the SQL Server. In this installment, I discuss the tables created and how I specified the FILESTREAM BLOB column.

Setting the Table

So after some struggle, I had SQL Server ready to handle FILESTREAMS. What I needed now were the requisite tables to store the data. This is achieved by adding a column to a table and indicating that BLOB data will live there in a file that is stored on a FILESTREAM filegroup. Here are the tables I used for my email and attachments log:

SQL
CREATE TABLE Notification.EmailMessages( 
    EmailMessageId        int            IDENTITY NOT NULL, 
    TransmitStatusId      int            NOT NULL, 
    SubmitDate            datetime       NOT NULL, 
    TransmitDate          datetime           NULL, 
    AttemptCount          int            NOT NULL, 
    FromAddress           varchar( 100 ) NOT NULL, 
    FromAlias             varchar( 100 )     NULL, 
    ToAddresses           varchar( 1000 ) NOT NULL, 
    CcAddresses           varchar( 1000 )    NULL, 
    BccAddresses          varchar( 1000 )    NULL, 
    Subject               varchar( 1000 )    NULL, 
    Body                  text               NULL, 
    timestamp             timestamp      NOT NULL, 
    CONSTRAINT PKEmailMessage 
        PRIMARY KEY( EmailMessageId ), 
    CONSTRAINT FK1EmailMessage 
        FOREIGN KEY( TransmitStatusId ) 
        REFERENCES Notification.TransmitStatus( TransmitStatusId ) 
) 
GO 

CREATE TABLE Notification.EmailAttachments( 
    EmailAttachmentId     int             IDENTITY NOT NULL, 
    EmailMessageId        int             NOT NULL, 
    AttachmentFileId      uniqueidentifier ROWGUIDCOL NOT NULL UNIQUE, 
    SequenceNum           int             NOT NULL, 
    Filename              varchar( 1000 ) NOT NULL, 
    FileData              varbinary( max ) FILESTREAM NULL, 
    timestamp             timestamp       NOT NULL, 
    CONSTRAINT PKEmailAttachments 
        PRIMARY KEY( EmailAttachmentId ), 
    CONSTRAINT FK1EmailAttachments 
        FOREIGN KEY( EmailMessageId ) 
        REFERENCES Notification.EmailMessages( EmailMessageId ) 
) 
ON [PRIMARY] 
    FILESTREAM_ON FilestreamExampleFilegroup ]]

Most of the columns in the EmailMessages table are fairly self-explanatory. The TransmitStatusId column is a reference into a simple lookup table with an integer ID and description that indicates what state the message is in, e.g. Queued, Transmitted, Failed, etc. As you can see in the EmailAttachments table, there are two columns that are somewhat out of the ordinary, the AttachmentFileId and FileData columns. But I'll explain each column so you can understand my approach to this design.

  • EmailAttachmentId - Monotonically increasing surrogate value to be used as a primary key. I prefer these to a GUID when a natural key is not handy but if you want to have a religious war about it, there are plenty of places where the battle rages. Feel free to take it there;
  • EmailMessageId - Parent key to the EmailMessages table;
  • AttachmentFileId - This is a unique GUID identifier for the row, as signified by the ROWGUIDCOL indicator, necessary for the FILESTREAM feature to uniquely identify the data;
  • SequenceNum - Indicates the listing sequence of the attachment, for later reporting purposes;
  • Filename - Saves the original file name, since FILESTREAM will create generated file names, and I will want to recreate the file names later when I'm actually transmitting the file via SMTP;
  • FileData - The binary column where the file data is stored, although the data is read and written on the operating system file storage not the SQL Server data file.
  • timestamp - Yes, I still use timestamp files for concurrency. I'm an old-school kind of guy.

The last part of the CREATE TABLE statement for the EmailAttachments table is where you specify the filegroup on which the FILESTREAM data will be stored. This references the filegroup we created in Processing SQL Server FILESTREAM Data: Part 2 - The Setup. And with that, we're finally ready to start coding!

Next up - Processing SQL Server FILESTREAM Data: Part 4 - Readin' and Writin'

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)