<select> 对于具有复合键的实体 - 需要策略

<select> for an entity with composite keys - strategy needed

所以说我有数据库 table tours (PK tour_id) 保存区域独立信息和 tours_regional_details (PK tour_id, region_id) 保存区域特定信息。

假设我想用 tours_regional_details table 中的实体填充 select 控件(我的真实场景有点不同,想象一下这是为了简单起见)。

那么,您将如何解决这个问题?我的直觉是将 PK 连接成带分隔符的字符串,例如 "pk1|pk2" 或 "pk1,pk2" 并将其用作 select 控件的值。虽然它有效,但感觉很脏,并且在再次拆分字符串之前可能需要额外的验证步骤,这再次感觉很脏。

我不想开始复合 vs 单人 pk 圣洁 war,但这对我来说可能是一个糟糕的数据库设计决定?我一直相信识别关系和复合键的存在是有原因的,但我很想改变我的 tables 并用自动增量 ID 和唯一约束填充它们。我只是不确定这会带来什么样的新鲜地狱。

这么多年第一次遇到这种情况,我有点吃惊。

编辑: 是的,有一个 table regions (PK region_id) 但大部分是无关紧要的为主题。虽然在某些情况下,两个 select 框是有意义的,但假设在这里它们没有意义,假设我只想要一个 select 框并且想要 select 来自:

复合主键不是糟糕的数据库设计。在理想情况下,我们的编程语言和 UI 库将支持元组和关系作为 first-class 值,因此您可以将一对值分配为您的选项的值下拉控件。然而,由于它们通常只支持标量变量,我们一直在尝试编码或减少我们的标识符。

您当然可以为每个 table 添加代理键/自动增量列(以及可用的自然键的唯一约束)。这是一种非常常见的模式,我见过的大多数数据库至少有一些 table 是这样设置的。您可以按原样保留现有的复合外键,或者您可以 want/need 更改它们以引用代理主键。

对外键使用代理键的风险是您在数据库中的访问路径变得固定。例如,假设 tours_regional_details 有一个主键 tours_regional_detail_id,它被另一个 table 中的外键引用。针对此其他 table 的查询将始终需要与 tours_regional_details 联合以获得 tour_idregion_id。自然键允许更灵活的访问路径,因为标识符在整个数据库中重复使用。这在依赖概念的深层层次结构中变得很重要。这些正是组合键的反对者抱怨键的 "explosion" 的场景,我至少可以同意,在编写查询时记住和键入大量列的连接变得很麻烦。

您可以将自然键列复制到引用 table 中,但是存储冗余信息需要额外的努力来保持一致性。我经常看到这样做是出于性能或方便的原因,其中代理键用作外键,因为它允许查询 table 而不必执行所有连接以取消引用代理标识符。在这些情况下,最好改为引用自然键。

如果允许我 return 我的理想世界,也许 DBMS 可以允许命名和存储连接。

实际上,代理键有助于平衡我们必须处理的复杂性。使用它们,但不要崇拜它们。