• Базы данных
  • SQL Server
  • Краткие рекомендации по настройке и оптимизации репликации транзакций

Секционированные таблицы и индексы SQL Server 2005 - Управление "включаемой" каскадной таблицей

ОГЛАВЛЕНИЕ

 

Управление "включаемой" каскадной таблицей

  1. Создайте каскадную таблицу - эта таблица является будущей скрытой секцией. Она должна иметь ограничение целостности для того, чтобы ограничивать свои данные только допустимыми для будущей секции таблицы значениями. Возможно, из соображений производительности вы захотите загрузить данные в неиндексированную кучу (heap) безо всяких ограничений целостности и затем только добавить ограничение целостности (см. шаг 3) WITH CHECK перед включением таблицы в секционированную таблицу.

    CREATE TABLE SalesDB.[dbo].[OrdersOctober2004]
    (
    [OrderID] [int] NOT NULL,
    [EmployeeID] [int] NULL,
    [VendorID] [int] NULL,
    [TaxAmt] [money] NULL,
    [Freight] [money] NULL,
    [SubTotal] [money] NULL,
    [Status] [tinyint] NOT NULL,
    [RevisionNumber] [tinyint] NULL,
    [ModifiedDate] [datetime] NULL,
    [ShipMethodID] [tinyint] NULL,
    [ShipDate] [datetime] NOT NULL,
    [OrderDate] [datetime] NOT NULL,
    [TotalDue] [money] NULL
    ) ON [FG1]
    GO

    Автоматизация: эту таблицу будет легко создать, поскольку это всегда будет текущий или только что завершившийся месяц. Структура каскадной таблицы должна соответствовать структуре существующей таблицы, таким образом, основное изменение для каждого месяца будет касаться имени таблицы. Тем не менее, Вы можете использовать одно и то же имя для каскадной таблицы каждый месяц, поскольку она не должна существовать после того, как будет добавлена в секцию. Каскадная таблица все еще будет существовать после того, как вы загрузите данные в секционированную таблицу, но вы можете удалить ее, как только загрузка данных завершится. Кроме того, должен меняться диапазон дат. Поскольку Вы работаете с типом данных datetime, а у него существуют проблемы округления времени, Вы должны быть готовы программно определить нужное значение в миллисекундах. Самый простой способ вычислить верхнее граничное значение месяца - это взять месяц, с которым вы работаете, прибавить к нему 1 месяц, и затем отнять 2 или 3 миллисекунды. Вы не можете вычесть только 1 миллисекунду, поскольку 59.999 округлится до .000 - а это уже будет первым днем следующего месяца. Вы можете вычесть 2 или 3 миллисекунды, поскольку -2 миллисекунды округлят значение до .997, а -3 равняется .997; .997 - применимое значение, которое может быть сохранено. Следующий пример поможет вам получить корректное значение верхней границы вашего диапазона.

    DECLARE @Month nchar(2),
    @Year nchar(4),
    @StagingDateRange nchar(10)
    SELECT @Month = N'11', @Year = N'2004'
    SELECT @StagingDateRange = @Year + @Month + N'01'
    SELECT dateadd(ms, -2, @StagingDateRange)

    Таблица должна будет пересоздаваться каждый месяц, поскольку она должна будет располагаться в файловой группе, данные которой постоянно переключаются. Чтобы определить файловую группу, с которой предстоит работать, используйте следующий запрос к системным таблицам, объединенный с известной уже функцией $partition. Подчеркнутые фрагменты кода Вы будете изменять непосредственно для вашей конкретной таблицы, функции секционирования и определенной даты.

    SELECT ps.name AS PSName,
    dds.destination_id AS PartitionNumber,
    fg.name AS FileGroupName
    FROM (((sys.tables AS t
    INNER JOIN sys.indexes AS i
    ON (t.object_id = i.object_id))
    INNER JOIN sys.partition_schemes AS ps
    ON (i.data_space_id = ps.data_space_id))
    INNER JOIN sys.destination_data_spaces AS dds
    ON (ps.data_space_id = dds.partition_scheme_id))
    INNER JOIN sys.filegroups AS fg
    ON dds.data_space_id = fg.data_space_id
    WHERE (t.name = 'Orders') AND (i.index_id IN (0,1)) AND
    dds.destination_id = $partition.TwoYearDateRangePFN('20021001')

  2. загрузите в каскадную таблицу данные. Если файлы согласованы, то тогда этот процесс следует поручить оператору BULK INSERT.
    Автоматизация: этот процесс является самым сложным, для автоматизации. Вы должны будете удостовериться, что все файлы были загружены, кроме того, Вы можете захотеть загружать их параллельно. Для управления этим процессом Вы могли бы создать таблицу, которая сохраняла бы треки профайлера с информацией о том, какие файлы были загружены и где они располагаются. Вы могли бы создать job в SQL Agent, который проверял бы поступление файлов каждые несколько минут, забирал новые файлы, а затем выполнял бы множественные операторы bulk insert.
  3. Как только данные загрузятся, Вы сможете добавить ограничение целостности. Для того чтобы данные считались "доверительными", ограничение целостности должен быть добавлено с опцией WITH CHECK. Опция WITH CHECK задается по умолчанию, поэтому ее не обязательно специально указывать, самое главное - не указать WITH NOCHECK.

    ALTER TABLE SalesDB.[dbo].[OrdersOctober2004]
    WITH CHECK
    ADD CONSTRAINT OrdersRangeYearCK
    CHECK ([OrderDate] >= '20041001'
    AND [OrderDate] <= '20041031 23:59:59.997')
    GO

  4. Проиндексируйте каскадную таблицу - она должна иметь такой же кластерный индекс, как и таблица, в которую планируется добавить секцию.

    ALTER TABLE [OrdersOctober2004]
    ADD CONSTRAINT OrdersOctober2004PK
    PRIMARY KEY CLUSTERED (OrderDate, OrderID)
    ON [FG1]
    GO

    Автоматизация: это - не сложный этап. Используя название месяца и информацию о файловой группе, полученную на шаге 1, Вы можете создать этот кластерный индекс.