简体   繁体   中英

MySQL: Foreign keys for tables with almost-similar fields

I have two tables in mysql which look like:

Product:

ID(PK)     Details
AB23CD     etc
EF45GH     etc
AB34CD     etc
more rows...

Client:

P1        P2        Client   ClientCallsThis
AB        CD        X        X1
EF        GH        Y        Y1
EF        GH        X        X2
more rows...

P1 and P2 refer to the first two and last two characters from the Product ID column.


I will like to join these two tables together . One way I thought of will be to introduce 2 more columns in the Product table and join them via an intermediate table ( Product-Client ):

Product:

ID(PK)   Details   P1(FK)  P2(FK)
AB23CD   etc       AB      CD
EF45GH   etc       EF      GH
AB34CD   etc       AB      CD
more rows...

Client:

P1(FK)    P2(FK)    Client   ClientCallsThis
AB        CD        X        X1
EF        GH        Y        Y1
EF        GH        X        X2
more rows...

Product-Client:

P1(PK)    P2(PK)
AB        CD
EF        GH
more rows...

Doing this however, is very wasteful and adds complexity (increases possibility of errors) since P1 and P2 can be easily derived from the ID column. Is there something I can do to avoid this problem? Perhaps some way to join the ID in Product to P1 and P2 in Product-Client ?

Any help provided is greatly appreciated!

For foreign keys to work you must have exactly the same value in the referenced fields. So, if you intend to have foreign keys, then you have to have the additional fields. End of story.

To make maintaining data integrity easier, you can use

1) Triggers to maintain P1 and P2 values in the product table

or

2) From MySQL v5.7.6 you can define P1 and P2 in the product table as stored generated columns (emphasis on stored, otherwise you cannot use them in FK relationship), which value will be based on the product id.

However, innodb has specific restrictions on FKs using stored generated columns :

A foreign key constraint on a stored generated column cannot use ON UPDATE CASCADE, ON DELETE SET NULL, ON UPDATE SET NULL, ON DELETE SET DEFAULT, or ON UPDATE SET DEFAULT.

• A foreign key constraint cannot reference a virtual generated column.

• Prior to 5.7.16, a foreign key constraint cannot reference a secondary index defined on a virtual generated column.

• In MySQL 5.7.13 and earlier, InnoDB does not permit defining a foreign key constraint with a cascading referential action on the base column of an indexed virtual generated column. This restriction is lifted in MySQL 5.7.14.

• In MySQL 5.7.13 and earlier, InnoDB does not permit defining cascading referential actions on non-virtual foreign key columns that are explicitly included in a virtual index. This restriction is lifted in MySQL 5.7.14.

If AB and CD have a separate meaning, dont store them as a single string AB23CD , but as separate strings P1='AB' , P3='23' , P2='CD' .

The product table then would have a composite primary key wich can be used as a foreign key in other tables.

Product. PK = P1 + P2.

P1  P2  ProductName
AB  CD  etc    
EF  GH  etc    


ProductVariant. PK = P1 + P2 + P3. FK on Product(P1,P2).

P1  P2  P3  Details
AB  CD  23  etc    
EF  GH  45  etc    
AB  CD  34  etc    


Client. PK = ClientID.

ClientID   ClientName
X          A
Y          B
X          C


Product_Client. PK = P1 + P2 + ClientID. FK1 on Product(P1,P2). FK2 on Client(ClientID).

P1  P2  ClientID  ClientCallsThis
AB  CD  X         X1
EF  GH  Y         Y1
EF  GH  X         X2

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