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

时间:2017-06-15 08:42:35

标签: mysql

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

我想将这两个表连接在一起。我想到的一种方法是在Product表中引入另外两列,并通过中间表(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...
然而,这样做非常浪费并增加了复杂性(增加了错误的可能性),因为可以从ID列轻松地导出P1和P2。我能做些什么来避免这个问题吗?也许某种方法可以将Product中的ID加入Product-Client中的P1和P2?

非常感谢您提供的任何帮助!

2 个答案:

答案 0 :(得分:1)

要使外键工作,您必须在引用的字段中具有完全相同的值。因此,如果您打算使用外键,那么您必须拥有其他字段。故事结束。

为了更轻松地维护数据完整性,您可以使用

1)触发以在产品表中维护P1P2

2)从MySQL v5.7.6开始,您可以在产品表中将P1P2定义为stored generated columns(强调存储,否则您不能在FK关系中使用它们),值将基于产品ID。

但是,innodb对FKs using stored generated columns具有特定限制:

  

存储生成列的外键约束不能使用ON   UPDATE CASCADE,ON DELETE SET NULL,ON UPDATE SET NULL,ON DELETE SET   DEFAULT或ON UPDATE SET DEFAULT。

     

•外键约束无法引用虚拟生成   柱。

     

•在5.7.16之前,外键约束不能引用a   在虚拟生成列上定义的辅助索引。

     

•在MySQL 5.7.13及更早版本中,InnoDB不允许定义a   外键约束,在基数上具有级联引用操作   索引虚拟生成列的列。这个限制是   在MySQL 5.7.14中解除了。

     

•在MySQL 5.7.13及更早版本中,InnoDB不允许定义   对非虚拟外键列的级联引用操作   显式包含在虚拟索引中。解除了这个限制   在MySQL 5.7.14中。

答案 1 :(得分:1)

如果ABCD具有单独的含义,请不要将它们存储为单个字符串AB23CD,而应将其存储为单独的字符串P1='AB'P3='23',{ {1}}。

然后,product表将有一个复合主键,可用作其他表中的外键。

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