我在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?
非常感谢您提供的任何帮助!
答案 0 :(得分:1)
要使外键工作,您必须在引用的字段中具有完全相同的值。因此,如果您打算使用外键,那么您必须拥有其他字段。故事结束。
为了更轻松地维护数据完整性,您可以使用
1)触发以在产品表中维护P1
和P2
值
或
2)从MySQL v5.7.6开始,您可以在产品表中将P1
和P2
定义为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)
如果AB
和CD
具有单独的含义,请不要将它们存储为单个字符串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