我正在重写一个web应用程序,该应用程序是几年前由cakeHP中的另一位程序员编写的,而该程序员并没有将他的数据库设计为具有外键限制。我将快速解释cakeHP系统的缺陷。
- "products"表有一个名为"type"的字段,可以是"normal"或"cpa"。(不要担心CPA代表什么,不重要)
- "普通"产品每次在浏览器中访问时都会在"跟踪"表中生成一个跟踪id。"cpa"类型每次被访问时都会在"cpatrack"表中生成一个跟踪id
- (这是问题所在)购买产品时,会在"sales"表中输入一个条目,在sales表中有一个名为"track_id"的字段。如果产品类型为"正常",则"跟踪"表中的ID存储在"track_ID"中。如果产品是"cpa",则"cpatrack"表中的ID存储在"track_ID"中
如果我正确地设置了Symfony并创建了正确的关系,那么"track_id"字段显然不能引用多个实体,因此我需要做出决定。我已经研究了Symfony文档中的抽象关系,它主要适用于防止捆绑包具有依赖关系,但它也可以让我在做类似的事情时选择正确的实体
$track = $sale->getTrackingId();
我应该考虑使用抽象关系来帮助解决这个问题,还是应该在销售表中创建另一个字段,如"cpa_track_id",并使用正常关系?有什么建议吗?
不能使用抽象关系。抽象关系是一种将捆绑包彼此解耦的工具,但是,当在应用程序中使用带有抽象关系的捆绑包时,您必须在实现时决定关系指向哪个实体类。您无法在运行时逐行决定它指向哪个类。
如果可以对数据库模式进行更改,请查看类表继承。只是一个粗略的草图:
- 创建具有列
id
和type
("cpa"或"normal")以及匹配继承映射的新表tracking_hdr
(tracking
和cpatrack
是子实体表) - 假设您的
tracking_id
是一个有符号整数(通常是这样,因为许多人不想添加UNSIGNED
…),并且所有现有值都是正的,请将cpatrack
表中的所有id乘以-1,以防止与tracking
表发生冲突 INSERT INTO tracking_hdr (id, type) SELECT id, 'normal' FROM tracking;
INSERT INTO tracking_hdr (id, type) SELECT id, 'cpa' FROM cpatrack;
- 更新
sales
表以否定tracking_id
,其中关联的产品是"cpa"产品 - 在指向
tracking_hdr
的sales
表上创建外键
这样,对数据库模式的更改相对较小,尤其是来自旧cakephp代码的只读访问应该仍然有效。但是,您应该记住,类表继承可能会对性能产生影响,因为如果您不小心,它很容易导致相当复杂的JOIN
查询。
如果您不能对模式进行任何更改,我认为您运气不好,必须接受选项1getTrackingId()
。