Question

I would guess this is a semi-common question but I can't find it in the list of past questions. I have a set of tables for products which need to share a primary key index. Assume something like the following:

product1_table:
    id,
    name,
    category,
    ...other fields

product2_table:
    id,
    name,
    category,
    ...other fields

product_to_category_table:
    product_id,
    category_id

Clearly it would be useful to have a shared index between the two product tables. Note, the idea of keeping them separate is because they have largely different sets of fields beyond the basics, however they share a common categorization.

UPDATE:

A lot of people have suggested table inheritance (or gen-spec). This is an option I'm aware of but given in other database systems I could share a sequence between tables I was hoping MySQL had a similar solution. I shall assume it doesn't based on the responses. I guess I'll have to go with table inheritance... Thank you all.

Was it helpful?

Solution

It's not really common, no. There is no native way to share a primary key. What I might do in your situation is this:

product_table
    id
    name
    category
    general_fields...

product_type1_table:
    id
    product_id
    product_type1_fields...

product_type2_table:
    id
    product_id
    product_type2_fields...

product_to_category_table:
    product_id
    category_id

That is, there is one master product table that has entries for all products and has the fields that generalize between the types, and type-specified tables with foreign keys into the master product table, which have the type-specific data.

OTHER TIPS

A better design is to put the common columns in one products table, and the special columns in two separate tables. Use the product_id as the primary key in all three tables, but in the two special tables it is, in addition, a foreign key back to the main products table.

This simplifies the basic product search for ids and names by category.

Note, also that your design allows each product to be in one category at most.

It seems you are looking for table inheritance.

You could use a common table product with attributes common to both product1 and product2, plus a type attribute which could be either "product2" or "product1"

Then tables product1 and product2 would have all their specific attributes and a reference to the parent table product.

product:
    id,
    name,
    category,
    type

product1_table:
    id,
    #product_id,
    product1_specific_fields

product2_table:
    id,
    #product_id,
    product2_specific_fields

First let me state that I agree with everything that Chaos, Larry and Phil have said.

But if you insist on another way...

There are two reasons for your shared PK. One uniqueness across the two tables and two to complete referential integrity.

I'm not sure exactly what "sequence" features the Auto_increment columns support. It seem like there is a system setting to define the increment by value, but nothing per column.

What I would do in Oracle is just share the same sequence between the two tables. Another technique would be to set a STEP value of 2 in the auto_increment and start one at 1 and the other at 2. Either way, you're generating unique values between them.

You could create a third table that has nothing but the PK Column. This column could also provide the Autonumbering if there's no way of creating a skipping autonumber within one server. Then on each of your data tables you'd add CRUD triggers. An insert into either data table would first initiate an insert into the pseudo index table (and return the ID for use in the local table). Likewise a delete from the local table would initiate a delete from the pseudo index table. Any children tables which need to point to a parent point to this pseudo index table.

Note this will need to be a per row trigger and will slow down crud on these tables. But tables like "product" tend NOT to have a very high rate of DML in the first place. Anyone who complains about the "performance impact" is not considering scale.

Please note, this is provided as a functioning alternative and not my recommendation as the best way

You can't "share" a primary key.

Without knowing all the details, my best advice is to combine the tables into a single product table. Having optional fields that are populated for some products and not others is not necessarily a bad design.

Another option is to have a sort of inheritence model, where you have a single product table, and then two product "subtype" tables, which reference the main product table and have their own specialized set of fields. Querying this model is more painful than a single table IMHO, which is why I see it as the less-desirable option.

Your explanation is a little vague but, from my basic understanding I would be tempted to do this

The product table contains common fields

product
-------
product_id
name
...

the product_extra1 table and the product_extra2 table contain different fields these tables habe a one to one relationship enforced between product.product_id and product_extra1.product_id etc. Enforce the one to one relationship by setting the product_id in the Foreign key tables (product_extra1, etc) to be unique using a unique constraint. you will need to decided on the business rules as to how this data is populated

product_extra1
---------------
product_id
extra_field1
extra_field2
....

product_extra2
---------------
product_id
different_extra_field1
different_extra_field2
....

Based on what you have above the product_category table is an intersecting table (1 to many - many to 1) which would imply that each product can be related to many categories This can now stay the same.

This is yet another case of gen-spec.

See previous discussion

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top