如果我有一个表,其中每一行都是客户预订,那么在这个表中是否可以有 2 个外键:一个为空,另一个引用适当的主键。我有两个表应用了外键约束的原因是预订可以是服务包(service_package)或单个服务(服务)的预订。
我的猜测是,这是一个糟糕的设计,因为可以在同一预订行中注册两种预订,除非通过使用函数或存储过程来实施限制。
这个解决方案可以吗,还是有更好的方法来做到这一点,比如为所提供的服务创建一个更通用的表?
如果我有一个表,其中每一行都是客户预订,那么在这个表中是否可以有 2 个外键:一个为空,另一个引用适当的主键。我有两个表应用了外键约束的原因是预订可以是服务包(service_package)或单个服务(服务)的预订。
我的猜测是,这是一个糟糕的设计,因为可以在同一预订行中注册两种预订,除非通过使用函数或存储过程来实施限制。
这个解决方案可以吗,还是有更好的方法来做到这一点,比如为所提供的服务创建一个更通用的表?
这是一种合理的做法。当值NULL
用于特定列时,连接将失败。
在 MySQL 中,您必须使用触发器强制执行此操作。其他数据库具有“检查约束”的概念,您可以在其中强制填充两个值中的一个。
如果您有更多列,您可能会想切换到“类型”列和“id”。这要求所有 id 都具有相同的类型。它还需要一个触发器来确保正确填充列。而且,在进行连接时可能会导致错误。
在这两种选择中,我更喜欢您的方法仅用于两个 id。
尽管拥有可为空的 FK 并没有错,但从性能的角度来看并不总是可取的。正如这篇文章中正确提到的:
B-tree 索引对于高基数数据(即具有许多可能值的列,其中列中的数据是唯一的或几乎唯一的)最有效。如果您将有许多 NULL 值(或任何其他重复值),则查询优化器可能会选择不使用索引来过滤结果集的记录,因为执行表扫描会更快。
我会选择使用复合索引 (id,type) 的类型/id 列。