简体   繁体   English

MySQL:具有几乎相似字段的表的外键

[英]MySQL: Foreign keys for tables with almost-similar fields

I have two tables in mysql which look like: 我在mysql中有两个表,如下所示:

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. P1和P2指的是“产品ID”列中的前两个字符和后两个字符。


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表中再引入2列,并通过中间表( 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. 但是,这样做很浪费,并且增加了复杂性(增加了出错的可能性),因为可以轻松地从ID列导出P1和P2。 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 ? 也许以某种方式将Product的ID加入Product-Client P1和P2?

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 1)触发以维持产品表中的P1P2

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. 2)在MySQL v5.7.6中,您可以将产品表中的P1P2定义为存储的生成列 (强调存储,否则不能以FK关系使用它们),该值将基于产品ID。

However, innodb has specific restrictions on FKs using stored generated columns : 但是,innodb对使用存储的生成的列的FK具有特定的限制:

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. 存储的生成列上的外键约束不能使用ON UPDATE CASCADE,ON DELETE SET NULL,ON UPDATE SET NULL,ON DELETE SET DEFAULT或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. •在5.7.16之前,外键约束不能引用在虚拟生成的列上定义的二级索引。

• 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. •在MySQL 5.7.13和更早版本中,InnoDB不允许在索引的虚拟生成列的基列上使用级联引用操作定义外键约束。 This restriction is lifted in MySQL 5.7.14. 在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. •在MySQL 5.7.13和更早版本中,InnoDB不允许在显式包含在虚拟索引中的非虚拟外键列上定义级联引用操作。 This restriction is lifted in MySQL 5.7.14. 在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' . 如果ABCD具有单独的含义,请不要将它们存储为单个字符串AB23CD ,而是存储为单独的字符串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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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