没有两行不同的表具有相同的主键?
No two rows of different tables have same primary key?
我的一个 table 的 order
与另外两个 table 的 PaymentMethod1
和 PaymentMethod2
有 one to many
关系。我创建了单独的 "payment method" table,因为它们具有完全不同的属性,因此我可以避免空值。但是,order
中的特定行将 link 到任何 table -- PaymentMethod1
或 PaymentMethod2
中的特定行。这要求主键值在这两个 table 中都是唯一的,即 PaymentMethod1
和 PaymentMethod2
中的两行不能具有相同的主键。
我以这种方式为 PaymentMethod1
和 PaymentMethod2
选择主键是否正确?如果是,我该如何实施?
这是解决问题的一种限制性方式。当您添加新的支付类型时会发生什么?一个新的 table 出现,并且必须重写所有使用订单和付款类型的查询的 JOIN 条件。
如果您将来可能会添加更多支付类型,请考虑使用单一支付类型 table 来保存所有支付类型通用的支付类型和属性,然后再使用一个单独的支付类型attribute table 将根据付款类型将属性保存在行中。这样,当您扩大规模时,您会增加记录数,而不是对象数(tables 和字段)。
如果您保留现有的东西,您需要将订单号写入您的付款类型 table 以便您加入他们,或者您需要写下付款类型以及订单的付款类型主键 table。类似于:
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 添加到组合中时。
MySQL 没有用于处理此类多态性的内置方法。
一种解决方案是在order
table中有两个外键列,一个用于第一种付款方式,一个用于第二种付款方式。允许NULL,只填合适的。
此方法允许您继续使用外键约束,但未完全规范化。
另一种方法是从 order
table 中取出支付方式键,取而代之的是有两个连接点 table,每个连接点对应一种支付类型。使用这些连接 table 将 order
table 连接到适当的支付类型。此方法还允许您使用外键约束,并且比以前的方法更规范化(不需要 NULL 值),但外键关系(和查询)有点复杂。
我的一个 table 的 order
与另外两个 table 的 PaymentMethod1
和 PaymentMethod2
有 one to many
关系。我创建了单独的 "payment method" table,因为它们具有完全不同的属性,因此我可以避免空值。但是,order
中的特定行将 link 到任何 table -- PaymentMethod1
或 PaymentMethod2
中的特定行。这要求主键值在这两个 table 中都是唯一的,即 PaymentMethod1
和 PaymentMethod2
中的两行不能具有相同的主键。
我以这种方式为 PaymentMethod1
和 PaymentMethod2
选择主键是否正确?如果是,我该如何实施?
这是解决问题的一种限制性方式。当您添加新的支付类型时会发生什么?一个新的 table 出现,并且必须重写所有使用订单和付款类型的查询的 JOIN 条件。
如果您将来可能会添加更多支付类型,请考虑使用单一支付类型 table 来保存所有支付类型通用的支付类型和属性,然后再使用一个单独的支付类型attribute table 将根据付款类型将属性保存在行中。这样,当您扩大规模时,您会增加记录数,而不是对象数(tables 和字段)。
如果您保留现有的东西,您需要将订单号写入您的付款类型 table 以便您加入他们,或者您需要写下付款类型以及订单的付款类型主键 table。类似于:
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 添加到组合中时。
MySQL 没有用于处理此类多态性的内置方法。
一种解决方案是在order
table中有两个外键列,一个用于第一种付款方式,一个用于第二种付款方式。允许NULL,只填合适的。
此方法允许您继续使用外键约束,但未完全规范化。
另一种方法是从 order
table 中取出支付方式键,取而代之的是有两个连接点 table,每个连接点对应一种支付类型。使用这些连接 table 将 order
table 连接到适当的支付类型。此方法还允许您使用外键约束,并且比以前的方法更规范化(不需要 NULL 值),但外键关系(和查询)有点复杂。