【问题标题】:Table partitioning on sql server by foreign key column通过外键列在sql server上进行表分区
【发布时间】:2015-05-25 05:47:01
【问题描述】:

我发现的所有表分区示例都非常简单,但我需要按一个标准对许多表进行分区。

例如,我有表:Contractors 和 Products,其中 Products 表中的 ContractorId 是外键。

我为 ContractorId 创建了函数和架构。它适用于 Contractors 表,但对于 Products 表...

我不知道我应该如何使用它,因为当我尝试时,我总是得到信息:“为聚集索引 'PK_dbo.Products' 指定的文件组 'PRIMARY' 用于表 'dbo.Products' 即使分区为它指定了方案'scheme_Contractors'”。我的产品表如下所示:

CREATE TABLE [dbo].[Products](
[ProductId] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](max) NULL,
[Amount] [int] NULL,
[Color] [nvarchar](max) NULL,
[Price] [decimal](18, 2) NULL,
[Guarantee] [nvarchar](max) NULL,
[GuaranteeType] [int] NULL,
[AdditionalFeatures] [nvarchar](max) NULL,
[Valid] [bit] NULL,
[ContractorId] [int] NOT NULL,
[ProducerId] [int] NOT NULL,
[ProductCategoryId] [int] NOT NULL,
 CONSTRAINT [PK_dbo.Products] PRIMARY KEY ( [ProductId] ASC ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] )
GO
ALTER TABLE [dbo].[Products]  WITH CHECK ADD  CONSTRAINT [FK_dbo.Products_dbo.Contractors_ContractorId] FOREIGN KEY([ContractorId]) 
REFERENCES [dbo].[Contractors] ([ContractorId])
GO
ALTER TABLE [dbo].[Products] CHECK CONSTRAINT [FK_dbo.Products_dbo.Contractors_ContractorId]
GO

谁能告诉我 - 是否可以在 ContractorId 列上使用我的架构以及如何使用?提前谢谢!

【问题讨论】:

  • 我认为您需要为每个表单独的分区功能。
  • 但是如果我想按 CustomerId 分区有什么区别?因此,对于 Products 表,我无法编写依赖于其主键 (ProductId) 的分区函数和模式。不幸的是,问题仍然存在。
  • 分区列 (ContractorId) 必须是所有唯一索引键的一部分,包括主键。如果您不希望 ContractorId 作为 PK 的一部分并且想要对表进行分区,您可以在 ContractorId 和 ProductId 上创建一个唯一的复合聚集索引,并将主键索引更改为非聚集索引而不对该索引进行分区。很大程度上取决于您进行分区的原因。
  • 非常感谢您的评论。很有帮助。

标签: sql sql-server partitioning database-partitioning


【解决方案1】:

我同意 Dan Guzman 的观点,我想指出表定义中不应有 [PRIMARY] 规范。

我们大规模使用分区。在同一个分区方案上对所有表进行分区非常方便,因为 SQL 引擎将充分利用其多处理器并行化功能。

当某组分区在一个数据库文件中,而另一个分区在另一个文件中时,您甚至可以灵活地使用磁盘和备份。

所以你首先需要一个分区函数来定义分区方案的值:

CREATE PARTITION FUNCTION [ContractorPartitionFunction](int) AS RANGE LEFT
FOR VALUES (contractor1,contractor2,...)

那你需要创建分区方案

CREATE PARTITION SCHEME [ContractorPartitionScheme] 
AS PARTITION [ContractorPartitionFunction] 
TO ([File_001],[File_002],...,[PRIMARY])

然后对于您现在创建的所有表和索引,您应该从定义中删除 ON [PRIMARY] 作为目标文件组,但您应该使用 ON [ContractorPartitionScheme](ContractorId)

所以你的表定义现在应该是:

CREATE TABLE [dbo].[Products](
[ProductId] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](max) NULL,
[Amount] [int] NULL,
[Color] [nvarchar](max) NULL,
[Price] [decimal](18, 2) NULL,
[Guarantee] [nvarchar](max) NULL,
[GuaranteeType] [int] NULL,
[AdditionalFeatures] [nvarchar](max) NULL,
[Valid] [bit] NULL,
[ContractorId] [int] NOT NULL,
[ProducerId] [int] NOT NULL,
[ProductCategoryId] [int] NOT NULL)
ON ContractorPartitionScheme(ContractorId)

CREATE UNIQUE NONCLUSTERED INDEX PK_dbo.Products ON Products
    (
    productId,
    ConstructorId
    ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
 ON ContractorPartitionScheme(ContractorId) 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-08
    相关资源
    最近更新 更多