我的问题:这是处理这种情况的最佳方式吗?
带有 CHECK 的多个 FK 只允许其中一个为非 NULL 是一种合理的方法,尤其是对于这种情况下相对较少的表。
另一种方法是Table 1, 2 and 3
从一个公共的“父”表“继承”,然后将评论连接到父表。
在这里和这里查看更多信息。
是否存在通用外键?
如果您的意思是可以从一个表“跳”到另一个表的 FK,那么不。
假设所有 3 个 FK 的类型相同1,理论上您可以通过保留外键值和引用的表名2来实现类似的东西,然后通过触发器强制执行它,但声明性约束应该优先于它,即使价格为存储空间略大。
如果您的 DBMS 完全支持“虚拟”或“计算”列,那么您可以执行与上述类似的操作,但无需触发器,而是根据 FK 值和表名生成 3 个计算列。在任何给定时间,这些计算列中只有一个是非 NULL 的,您可以对它们使用“正常”FK,就像对物理列一样。
但是,当有许多“可连接”表并且您的 DBMS 在存储 NULL 时并不节俭时,所有这些都是有意义的。当它们只有 3 个时或什至还有更多时,几乎没有什么好处,但您的 DBMS 在每个 NULL 字段上只花费一位。
或者我应该为每个主表有一个单独的注释表,即使数据结构完全相同?
“数据结构”并不是唯一重要的事情。如果您碰巧有不同的约束(例如,适用于其中一个但不适用于另一个的 FK),即使列相同,也需要单独的表。
但是,我猜这不是这里的情况。
或者每个人的映射表会是更好的解决方案吗?
我不确定您所说的“映射表”是什么意思,但是您可以执行以下操作:
不幸的是,这将允许单个评论连接到多个表(或根本没有表),这本身就是对您已有的内容的复杂化。
总而言之,您的原始解决方案可能很好。
1或者您愿意将其存储为字符串并接受转换,您应该不愿意这样做。
2在实践中,这实际上不是一个名称(如字符串)——它将是一个整数(或枚举,如果 DBMS 支持它),其中一个众所周知的预定义值标识该表。