如何使用模数函数对SQL Server表进行分区

时间:2018-03-15 05:01:41

标签: sql sql-server sql-server-2008

我有一个Orders表,其中包含一些基本信息,如下所示:

+---------+---------+------------+-----------+
| OrderId | StoreId | StoreName  | ProductId |
+---------+---------+------------+-----------+
|       1 |    1001 | Store 1001 |       123 |
|       2 |    1002 | Store 1002 |       124 |
|       3 |    1003 | Store 1003 |       125 |
+---------+---------+------------+-----------+

我想通过表达式StoreId MOD 10对此表进行分区。我认为它可以将这个表分成10个较小的表。

如何使用SQL Server解决它?

2 个答案:

答案 0 :(得分:1)

试试这个:

SELECT StoreId%10 [StoreId mod 10]
      ,StoreId 
      ,OrderId 
      ,StoreName  
      ,ProductId
FROM Orders
order by StoreId%10, OrderId 

答案 1 :(得分:1)

SQL Server中的MOD运算符为%。请记住,如果您想要非零数字,则应在结果中添加1。

SELECT
    StoreOrderGroup = (StoreId % 10) + 1,
    O.*
FROM
    Orders AS O

如果要创建具有相同结构的10个不同表,可以使用生成的StoreOrderGroup来SELECT INTO并创建它们。此不会复制索引或约束

DECLARE @StoreOrderGroup INT
DECLARE @StoreOrderGroupTable VARCHAR(100)

DECLARE StoreOrderGroupCursor CURSOR FOR
    SELECT DISTINCT
        StoreOrderGroup = (StoreId % 10) + 1,
        StoreOrderGroupTable = QUOTENAME('OrdersStore' + CONVERT(VARCHAR(200), (StoreId % 10) + 1))
    FROM
        Orders
    ORDER BY
        StoreOrderGroup ASC

OPEN StoreOrderGroupCursor
FETCH NEXT FROM StoreOrderGroupCursor INTO @StoreOrderGroup, @StoreOrderGroupTable

WHILE @@FETCH_STATUS = 0
BEGIN

    DECLARE @DynamicSQLCreate VARCHAR(MAX) = '
        SELECT 
            * 
        INTO 
            ' + @StoreOrderGroupTable + ' 
        FROM 
            Orders
        WHERE
            (StoreId % 10) + 1 = ' + CONVERT(VARCHAR(200), @StoreOrderGroup)

    EXEC (@DynamicSQLCreate)

    FETCH NEXT FROM StoreOrderGroupCursor INTO @StoreOrderGroup, @StoreOrderGroupTable

END

CLOSE StoreOrderGroupCursor
DEALLOCATE StoreOrderGroupCursor

但是,如果要保留相同的表但具有不同的分区,则需要:

  1. 创建不同的文件组来存储每个分区,每个分区至少有一个文件,最好是在不同的硬盘上。这是推荐的,但不是强制性的。
  2. 创建一个PARTITION FUNCTION,它将接收商店mod结果作为输入参数,并返回应分配给它的分区。边界限制值将是整数(小心LEFT或RIGHT范围)。
  3. 创建一个PARTITION SCHEME,将第2点的分区功能与第1点的不同文件组相关联。这将告诉引擎应该在哪个文件组中存储每个分区。
  4. 使用您的分区方案创建一个新表并存储您的所有订单。
  5. 一个简单的例子:

    ALTER DATABASE YourDatabase ADD FILEGROUP SuperFastFileGroup;  
    GO  
    
    ALTER DATABASE YourDatabase ADD FILEGROUP SuperSlowFileGroup;  
    GO  
    
    ALTER DATABASE YourDatabase   
    ADD FILE   
    (  
        NAME = FastFile,  
        FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\FastFile.ndf',  
        SIZE = 5MB,  
        MAXSIZE = 100MB,  
        FILEGROWTH = 5MB  
    )  
    TO FILEGROUP SuperFastFileGroup;  
    GO
    
    ALTER DATABASE YourDatabase   
    ADD FILE   
    (  
        NAME = SlowFile,  
        FILENAME = 'D:\SQL Server\SlowFile.ndf',  
        SIZE = 5MB,  
        MAXSIZE = 100MB,  
        FILEGROWTH = 5MB  
    )  
    TO FILEGROUP SuperSlowFileGroup;  
    GO  
    
    
    CREATE PARTITION FUNCTION OrderStoreMod10 (int)
        AS RANGE LEFT FOR VALUES (1, 2, 3, 4, 5, 6, 7, 8, 9);  
    GO  
    
    
    CREATE PARTITION SCHEME OrderStoreScheme  
        AS PARTITION OrderStoreMod10  
        TO (
            SuperFastFileGroup, -- 1 or lower
            SuperFastFileGroup, -- 2
            SuperFastFileGroup, -- 3
            SuperFastFileGroup, -- 4
            SuperFastFileGroup, -- 5
            SuperFastFileGroup, -- 6
            SuperFastFileGroup, -- 7
    
            SuperSlowFileGroup, -- 8
            SuperSlowFileGroup, -- 9
            SuperSlowFileGroup); -- higher than 9
    GO  
    
    
    CREATE TABLE NewOrders (
        -- Your columns...
        StoreID INT,
        StoreOrderGroup AS StoreID % 10) -- ComputedColumn
        ON OrderStoreScheme (StoreOrderGroup);  
    GO  
    
    -- Insert your data into the new table
    

    在使用StoreID分割的表格上使用分区方案之前,请先阅读this post,这可能不是一个好主意。