我的一个表order
与另外两个表one to many
和PaymentMethod1
有PaymentMethod2
个关系。我创建了单独的付款方式"表,因为它们具有完全不同的属性,因此我可以避免空值。但是,order
中的特定行会链接到任意一个表的特定行 - PaymentMethod1
或PaymentMethod2
。这要求主键值在这两个表中都是唯一的,即PaymentMethod1
和PaymentMethod2
中的两行不能有相同的主键。
我是否正确地以这种方式选择PaymentMethod1
和PaymentMethod2
的主键?如果是,我该如何实施呢?
答案 0 :(得分:3)
这是解决问题的限制方式。添加新付款类型会发生什么?新表格会上升,并且您的所有使用订单和付款类型的查询的JOIN条件都必须重写。
如果您将来可能会添加更多付款类型,请考虑使用单个付款类型表来保存所有付款类型始终通用的付款类型和属性,然后使用单独的属性表来保存基于付款类型的行中的属性。这样,当你扩展时,你会增加记录数,而不是对象数(表和字段)。
如果您保留所拥有的物品,则需要将订单号写入“付款类型”表,以便加入,或者您需要将付款类型类型和付款类型主键写入订单表。类似的东西:
Order Number | Payment Type Type | Payment Type Key
1 PaymentType1 5
2 PaymentType2 5
3 PaymentType1 5
然后:
SELECT
o.Number,
COALESCE(pm1.key, pm2.key),
CASE WHEN o.PaymentTypeType = "PaymentType1"
THEN pm1.pm1_attr1
ELSE pm2.pm2.attr3
END as "Friendly Attribute Name"
FROM ORDER o
LEFT OUTER JOIN PaymentMethod1 pm1 ON
o.PaymentTypeType = "PaymentType1" AND
o.PaymentTypeKey = pm1.key
LEFT OUTER JOIN PaymentMethod2 pm2 ON
o.PaymentTypeType = "PaymentType2" AND
o.PaymentTypeKey = pm2.key
你可以看到可能会很快变丑。特别是从现在起一年内将新的PaymentType添加到混音中。
答案 1 :(得分:2)
MySQL没有内置的方法来处理这种类型的多态性。
一种解决方案是在order
表中有两个外键列,一个用于第一种付款方式,另一列用于第二种付款方式。允许NULL,只填写适当的。
此方法允许您继续使用外键约束,但它没有完全标准化。
另一种方法是将付款方式密钥从order
表中取出,而是有两个联结表,每种付款类型一个。使用这些联结表将order
表加入适当的付款类型。此方法还允许您使用外键约束,并且比以前的方法更规范化(不需要NULL值),但外键关系(和查询)有点复杂。