Question

Imagine the following database:

Table 'companies' has fields id, name and flagship_product_id. Table 'products' have fields id, name and company_id.

A company must have a flagship product (1:1 relationship) and all products have one company (1:N relationship).

When using a storage engine such as MyISM, there shouldn't be any problem with the above scenario, but when using an engine such as InnoDB, problems result when INSERTing new data.

What is a good solution except allowing a NULL relationship for the initial INSERT?

To summarize, A company must have one flagship product.

Was it helpful?

Solution

I don't know that particular database engine, but search for a way to temporarily suspend the data consistency checks or referential integrity during your atomic insert and update operations.

OTHER TIPS

You're either going to have to allow NULLs in flagship_product or reconsider how you model this situation. Consider putting flagship_product as a boolean field on product instead. Then you don't have a circular dependency. Or have a product_type field on product that might have values like FLAGSHIP or NORMAL or OBSOLETE or whatever. Of course you have to enforce that but in the past I've found it a cleaner solution to this kind of problem.

I recommend using the following data model:

COMPANIES

  • COMPANY_ID pk

PRODUCTS

  • PRODUCT_ID (pk)
  • COMPANY_ID (fk)

FLAGSHIP_PRODUCTS

  • COMPANY_ID (pk, fk)
  • PRODUCT_ID (fk)

Creating a FLAGSHIP column in the PRODUCTS table will not ensure that only one product is the flagship product for the given company because:

  • A unique key on the FLAGSHIP column requires the values to be different from each other
  • A check constraint is only a list of acceptable values

why not put a flagship product field into the products table as a boolean... you could index that and companyid and have a pretty quick lookup

The only products that are smart and powerful enough to deal with such situations correctly are systems that fully embrace/implement the concept of Multiple Assignment.

There is not a single SQL system plays in that league.

EDIT

SQL systems have deferred constraint checking, but using that can get messy.

Here's an outline of a possible work-around. I'm not sure how high on the Kludge scale this fits, but it's up there.

  • Create Database
  • Create clients and products tables
  • Insert a placeholder or "dummy" row in each, configured to reference each other
  • Establish FK constraints between the tables

Thereafter, whenever a client or product is created, IF the proper referenced product/company has not yet been created, you initialized the new item to point to dummy placholder. Next you enter that item, and you complete by updating the first entry.

The upside is, you have absolute referential integrity once your database initialization routine is completed--and you only run that once under presumably very controlled circumstances, so watch it closely and make sure it doesn't fail! The not downside is, you now have an "extra" item in each table cluttering up your system.

You'll need to break the cycle by deferring one of your referential integrity constraints until the end of the transaction.

Please google for "INITIALLY DEFERRED DEFERRABLE".

(not sure whether InnoDB supports this)

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