【问题标题】:Finding SQL Schema for Product Pricings with Separate Vendor Relationship查找具有单独供应商关系的产品定价的 SQL 模式
【发布时间】:2025-12-25 07:30:14
【问题描述】:

我正在努力为我当前的任务找到一个好的架构,非常感谢您提供一点意见。

我正在处理一个非常大的项目,其中包括表 ProductsProductPricingsVendors。 (以下定义经过重新设计,更加简洁。)

产品

CREATE TABLE [dbo].[Products](
    [ProductsId]       [int] IDENTITY(1,1) NOT NULL,
    [Comments]         [nvarchar](max) NULL,
    CONSTRAINT [PK_Products] PRIMARY KEY CLUSTERED 
    (
        [ProductsId] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

产品定价

CREATE TABLE [dbo].[ProductPricing](
    [ProductPricingId] [int] IDENTITY(1,1) NOT NULL,
    [ProductsId]       [int] NOT NULL,
    [EffectiveDate]    [datetime] NOT NULL,
    [BasePrice]        [money] NOT NULL,
    [BaseCost]         [money] NOT NULL,
    [PriceTaxRate]     [decimal](10, 6) NOT NULL,
    [CostTaxRate]      [decimal](10, 6) NOT NULL,
    [GratuityRate]     [decimal](10, 6) NOT NULL,
    CONSTRAINT         [PK_ProductPricing] PRIMARY KEY CLUSTERED 
    (
        [ProductPricingId] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

供应商

CREATE TABLE [dbo].[Vendors](
    [VendorsId]        [int] IDENTITY(1,1) NOT NULL,
    [Description]      [nvarchar](100) NOT NULL,
    [RowVersion]       [timestamp] NOT NULL,
    CONSTRAINT         [PK_Vendors] PRIMARY KEY CLUSTERED 
    (
        [VendorsId] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

一个产品可以包含任意数量的 ProductPricings。

我的任务:

  1. 将每个 ProductPricing 与供应商相关联。
  2. 允许用户在每个产品中指定供应商订单。 (确定哪个优先级更高。)

我提出的更改:

我正在考虑添加一个新表 ProductVendors。然后将 ProductPricings 中的 FK 添加到 ProductVendors。

CREATE TABLE [dbo].[ProductVendors](
    [ProductVendorsId] INT IDENTITY(1,1) NOT NULL,
    [ProductsId]       INT      NOT NULL,
    [VendorsId]      INT      NOT NULL,
    [SortOrder]        SMALLINT NOT NULL,
    CONSTRAINT [PK_ProductVendors_1] PRIMARY KEY CLUSTERED ([ProductsId] ASC, [CompaniesId] ASC),
    CONSTRAINT [FK_ProductVendors_Products] FOREIGN KEY ([ProductsId]) REFERENCES [dbo].[ProductPricing] ([ProductsId]) ON DELETE CASCADE,
    CONSTRAINT [FK_ProductVendors_Vendors] FOREIGN KEY ([VendorsId]) REFERENCES [dbo].[Vendors] ([VendorsId]) ON DELETE CASCADE

这种方法有以下好处:

  1. 允许我控制每个产品的供应商顺序。
  2. 允许我将每个 ProductPricing 与供应商相关联。

这是我不喜欢这种方法的地方:

  1. ProductPricing 以两种方式与产品相关联:通过 FK ProductsId,以及通过 ProductVendors 表。这确立了两个版本的真理。希望他们总是引用同一个产品,但是为此建立一个约束会很尴尬。
  2. 这种方法的代码密集度更高。将 ProductPricing 与 Vendor 关联时,我必须检查 Product 是否已经具有此 ProductVendor,如果没有则创建它。而且,在取消 ProductPricing 与供应商的关联时,我需要检查是否有任何其他 ProductPricing 与该供应商关联,如果没有,则需要删除孤立的 ProductVendors。

我知道这是很多信息。但是有没有更好的方法来解决这个问题? (如果有什么不同,我使用的是 C#、ASP.NET 和 SQL Server。)

【问题讨论】:

  • 仅供参考,对于供应商创建 stmt,得到:当表没有文本、ntext、图像、varchar(max)、nvarchar(max)、varbinary(max)、xml 或大用户时,无法使用 TEXTIMAGE_ON定义的类型列。 2005 年
  • CompanyID(在 dbo.ProductVendors 上)来自哪里?那是 VendorID 吗?
  • 根据您的描述,您能否将 VendorsID 和 SortOrder 添加到 ProductPricing 表中?
  • TEXTIMAGE_ON 可能是多余的,除非有多个文件组......它只是由 SSMS 添加并且可能没有被 OP “简化”?
  • @Beth:抱歉,我做了一些快速编辑以使其更简洁。我更像是一名 C# 程序员而不是数据库程序员。

标签: sql sql-server database-schema


【解决方案1】:

我个人会将 VendorsId 添加到 ProductPricing。这是您完成的清单上的第一项工作。

接下来我将添加一个新表以允许存储供应商首选项:

CREATE TABLE ProductVendors (
    [ProductVendorsId] INT IDENTITY(1,1) NOT NULL,
    [ProductsId]       INT      NOT NULL,
    [VendorsId]      INT      NOT NULL,
    [PreferenceOrder]        SMALLINT NOT NULL,
PRIMARY KEY etc...
FOREIGN KEY etc...

...这是完成的第二项工作。

总而言之,您有办法将供应商与产品价格关联起来,并允许存储供应商偏好而不在数据中引入循环:D

【讨论】:

  • 谢谢。你能详细说明一下为什么你认为这更好吗?这基本上是我建议的,只是您让 ProductPricing 表直接引用 Vendors 表,而不是通过 ProudctVendors 表,对。至于添加和删除 ProductPricing 和 Vendors 之间的关联(需要管理 ProductVendors 列表),仍有一些工作要做。但是,是的,我看到你已经消除了两个版本的真相问题。
  • 在我看来,您有两项不同的工作,一项允许按产品对供应商进行优先排序,另一项将产品定价分配给供应商。我认为做到这一点的最好方法是将这两个更改分开,而不是试图以任何方式将它们结合起来。可能还有其他方法可以实现这两个目标,但通常最简单的解决方案最适合数据库设计?
  • 是的,我在这里听取了您的建议,但由于需要额外的工作,我并不完全满意,而且使用此模式对数据进行分组和排序也有点尴尬。但也许没有更简单的方法。
  • 如果数据难以报告,那么 VIEW 可能是前进的方向?