Search code examples
sqlnormalizationdatabase-normalization

Normalization of Many to Many relation in sql


I have a product table that contains two column

ProductID   Desc
  1         Fan
  2         Table
  3         Bulb

I have another table that contains supplier information

SupplierID    Desc
   1          ABC
   2          XYZ
   3          HJK

Now One supplier can supply multiple products and one product can be supplied by multiple suppliers To achieve this I have created another table tbl_Supplier_Product

 SupplierID    ProductID 
     1            1
     1            2
     2            1
     2            2
     2            3

Is it a good way to link this table to supplier and product table through primary composite key. In this table the primary key would be a composite key (SupplierID and ProductID) or should I add an extra column row ID for each record and then use that as a primary key and add a unique constraint to columns SupplierID and ProductID

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

What would the relationship of this table be to supplier table? I am a bit confused here because I added this table to resolve many to many relationship and redundant data but it still seems like this table has many to many relationship with both the tables??


Solution

  • You don't need the extra column: a composite key is all you need

    I would create a unique index that is the reverse of the PK too: this is useful for many queries and also provides an FK index for ProductID

    After comment:

    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
    

    For more

    And also use this generally to ensure that all your FKs have indexes

    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
    

    In an ERD (random one from a PowerPoint I have):

    enter image description here