sql中多对多关系的规范化

sql中多对多关系的规范化,sql,normalization,database-normalization,Sql,Normalization,Database Normalization,我有一个包含两列的产品表 ProductID Desc 1 Fan 2 Table 3 Bulb 我有另一个包含供应商信息的表 SupplierID Desc 1 ABC 2 XYZ 3 HJK 现在一个供应商可以提供多个产品,一个产品可以由多个供应商提供,为了实现这一点,我创建了另一个表tbl_supplier_product SupplierID

我有一个包含两列的产品表

ProductID   Desc
  1         Fan
  2         Table
  3         Bulb
我有另一个包含供应商信息的表

SupplierID    Desc
   1          ABC
   2          XYZ
   3          HJK
现在一个供应商可以提供多个产品,一个产品可以由多个供应商提供,为了实现这一点,我创建了另一个表tbl_supplier_product

 SupplierID    ProductID 
     1            1
     1            2
     2            1
     2            2
     2            3
通过主复合键将此表链接到供应商和产品表是否是一种好方法。在这个表中,主键是一个复合键(SupplierID和ProductID),或者我应该为每个记录添加一个额外的列行ID,然后将其用作主键,并为列SupplierID和ProductID添加一个唯一约束

 SupplierID    ProductID    Row ID
         1            1       1
         1            2       2
         2            1       3
         2            2       4
         2            3       5
UNIQUE CONSTRAINT(SupplierID, ProductID)

此表与供应商表的关系是什么?我在这里有点困惑,因为我添加这个表是为了解决多对多关系和冗余数据,但是这个表似乎仍然与这两个表都有多对多关系???

您不需要额外的列:只需要一个复合键

我将创建一个与PK相反的唯一索引:这对许多查询都很有用,并且还为ProductID提供了一个FK索引

 SupplierID    ProductID    Row ID
         1            1       1
         1            2       2
         2            1       3
         2            2       4
         2            3       5
UNIQUE CONSTRAINT(SupplierID, ProductID)
评论后:

CREATE TABLE SupplierProduct (
    SupplierID int NOT NULL,
    ProductID int NOT NULL,

    PRIMARY KEY (SupplierID, ProductID)
);
GO
CREATE UNIQUE NONCLUSTERED INDEX IXU_ReversePK ON SupplierProduct (ProductID, SupplierID);
GO
更多

  • 更多信息(见评论)
并且通常也使用它来确保所有FK都有索引

SELECT  fk.name AS [Missing FK Index]
FROM    sys.foreign_keys fk
WHERE   EXISTS
        (
        SELECT  *
        FROM    sys.foreign_key_columns fkc
        WHERE   fkc.constraint_object_id = fk.object_id
                AND NOT EXISTS
                (
                SELECT  *
                FROM    sys.index_columns ic
                WHERE   ic.object_id = fkc.parent_object_id
                        AND ic.column_id = fkc.parent_column_id
                        AND ic.index_column_id = fkc.constraint_column_id
                )
        );
GO
在ERD中(从我的PowerPoint中随机选择):


您不需要额外的列:只需要一个复合键

我将创建一个与PK相反的唯一索引:这对许多查询都很有用,并且还为ProductID提供了一个FK索引

 SupplierID    ProductID    Row ID
         1            1       1
         1            2       2
         2            1       3
         2            2       4
         2            3       5
UNIQUE CONSTRAINT(SupplierID, ProductID)
评论后:

CREATE TABLE SupplierProduct (
    SupplierID int NOT NULL,
    ProductID int NOT NULL,

    PRIMARY KEY (SupplierID, ProductID)
);
GO
CREATE UNIQUE NONCLUSTERED INDEX IXU_ReversePK ON SupplierProduct (ProductID, SupplierID);
GO
更多

  • 更多信息(见评论)
并且通常也使用它来确保所有FK都有索引

SELECT  fk.name AS [Missing FK Index]
FROM    sys.foreign_keys fk
WHERE   EXISTS
        (
        SELECT  *
        FROM    sys.foreign_key_columns fkc
        WHERE   fkc.constraint_object_id = fk.object_id
                AND NOT EXISTS
                (
                SELECT  *
                FROM    sys.index_columns ic
                WHERE   ic.object_id = fkc.parent_object_id
                        AND ic.column_id = fkc.parent_column_id
                        AND ic.index_column_id = fkc.constraint_column_id
                )
        );
GO
在ERD中(从我的PowerPoint中随机选择):


请详细说明“将创建一个与PK相反的唯一索引:这对许多查询都很有用,并且还为ProductID提供FK索引”感谢您的解释,但是如果ER图中显示,此表与供应商和产品表的关系会是什么。最后一件事,从这个页面上看,如果你看到的答案是“如果你有一个复合主键,那么所有引用它的外键都必须使用复合主键的所有列”这是否意味着我必须将productID添加到供应商表中,将SupplierId添加到产品表中。您的情况并非如此@marc_s指的是一个简单的子表,它指的是一个单亲表,单亲表有一个复合键。这与您的表不同。请详细说明“将创建一个与PK相反的唯一索引:这对许多查询都很有用,并且还为ProductID提供FK索引”感谢您的解释,但是如果ER图中显示,此表与供应商和产品表的关系如何。最后一件事,从这个页面上看,如果你看到的答案是“如果你有一个复合主键,那么所有引用它的外键都必须使用复合主键的所有列”这是否意味着我必须将productID添加到供应商表中,将SupplierId添加到产品表中。您的情况并非如此@marc_s指的是一个简单的子表,它指的是一个单亲表,单亲表有一个复合键。它不像你的桌子那么多。