表内引用父级

时间:2019-04-24 18:49:51

标签: sql sql-server

我有一个具有以下结构的SQL Server表:

create table Products
(
    Id int identity not null 
        constraint primary key clustered (Id),
    Name nvarchar (200) not null,
)

我需要允许Product引用另一个Product

目标是在列出产品时显示一种替代某些产品的方法。

我可以在ProductId表中添加一个名为Products的FK,但是我有几个问题:

  1. 循环引用会产生问题吗?
  2. 如何防止IdProductId相同?我不希望产品引用自己。

2 个答案:

答案 0 :(得分:3)

您可以像这样在同一个表格中放置一个替代项:

create table Products ( 
   ProductId int identity(1, 1) primary key,
   Name nvarchar(200) not null,
   Alternate_ProductId int references Products(ProductId),
   check (Alternate_ProductId <> ProductId)
);

请注意,在SQL Server中,主键是自动集群的,因此没有理由明确。另外,根据定义,主键不是NULL,因此NOT NULL是多余的。

检查约束使NULL值可以通过(与WHERECASE WHEN不同),因此您不必担心NULL的{​​{1}}值

这会引起问题吗?好吧,这仅允许一种替代产品,而这可能还不够。而且,这使备用产品链变得可能繁琐。

答案 1 :(得分:0)

我认为一个基本问题是您要具体建模的内容:

  • 对于任何给定的产品,可以有1个(或更多)替代/等效产品(“差不多”)。
  • 对于任何给定的产品类别,都有一个首选产品。

对于第一种选择,@ Gordon的答案肯定足够了(只要每个产品只需要1个替代品即可)。如果一个产品可以有多个替代产品,则您需要一个“替代产品”映射表(如@pmbAustin所建议),或者(假设您具有产品类别)仅显示同一类别中的其他产品。

对于选项2(同样,假设您具有产品类别或类似名称),可以存储类别的首选产品:

CREATE TABLE ProductCategories
(
    category_id INT IDENTITY(1,1) PRIMARY KEY,
    category_name NVARCHAR(255) NOT NULL,
    preferred_product INT NOT NULL FOREIGN KEY REFERENCES Products(Id)
);

That way, if the user is looking at a "non-preferred" product, they can be shown the preferred product for that category (if it's defined).