简体   繁体   中英

SQL - Can I base a table primary key on more than one field, requiring the uniqueness of first OR second value?

Let us say we have a product catalog. Table has following fields: CompanyID and ProductID. I want the table primary key to be based on those two fields, so as a record is unique when its pair of CompanyID and ProductID fields have unique values. To be clear: a record of CID = 1 and PID = 10 can coexist with a record of CID = 2 and PID = 10 (two companies may wish to have a product tagged with the same identifier, right?), so can a record of CID = 1 and PID = 9. Of course two records with both CID=1 and PID=10 values can not coexist. I do not want to introduce another column with unique record identifier, because I want these rules to be applied without creating a C# layer checking for integrity. I hope this is understandable, i tried to be clear but I somehow can't find words to describe it.

Yes, a primary key on two column does what you want. Just try it out.

Yes, PRIMARY KEY(CompanyID,ProductID) , although to properly work neither column should be nullable.

Yes, you can have multiple columns as your primary key.

In the designer, select both columns and then click Set Primary Key

Yes, a key is a set of attributes of a table. In principle you can have as many columns in it as you like.

Either of these would work for your PRODUCTS table:

                table: PRODUCTS1
                id autoincrementing integer primary key
                company int
                product int
                productname
                etc

                with a unique composite index on (company,product)

or

                table: PRODUCTS2
               company int
               product int
               productname

               (company, product) composite primary key

But if you create a composite primary key, all foreign references to that composite PK will also have to be composite, two-columns. Orders, for example, referencing the product would require two columns:

                      table: OrderDetail
                      orderdetailid int pk
                      orderheaderid int   --foreign key references ORDERHEADER(id)
                      company
                      product
                      quantity
                      etc

                     -- foreign key (company,product) references PRODUCTS2(company,product)

but this would be simpler for queries and in your front-end GUI code:

                      table: OrderDetail
                      orderdetailid int pk
                      orderheaderid int  --foreign key references ORDERHEADER(id)
                      productid  --here the foreign key references PRODUCTS1(id)
                      quantity
                      etc

I am not sure what you mean by

I do not want to introduce another column with unique record identifier, because I want these rules to be applied without creating a C# layer checking for integrity.

These constraints/indexes can be created in the database itself and the database would enforce the rules; your C# client program would not enforce these rules but would merely report errors generated by the database when attempts were made to violate the rules. The first approach, PRODUCTS1, where you have a separate autoincrementing primary key, gives you a simple handle to the row while also enforcing the two-column uniqueness rule you desired. It is common practice.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM