关系数据库中的代理键是添加到表中用于唯一标识记录的人工标识符。这些键并非源自应用程序数据本身,而是由系统生成。常见的例子是自增整数列(例如 id
在 users
表中)或 GUID(全局唯一标识符)。与基于现有业务数据(如电子邮件地址或产品代码)的自然键不同,代理键在数据库外部没有固有的意义。它们唯一的目的是提供一种稳定、简单的方式来引用行,尤其是在自然键不可靠或复杂的情况下。
开发者使用代理键有几个实际原因。首先,自然键常常因业务需求而改变(例如,用户的电子邮件地址可能会更新),这会使外键关系复杂化并需要级联更新。代理键保持静态,避免了这个问题。其次,它们简化了表之间的连接。例如,通过 customer_id
整数列连接 orders
表和 customers
表比使用 (first_name, last_name, phone_number)
这样的复合键更有效率且更易读。当自然键过长、包含特殊字符或容易重复时,代理键还能降低出错风险。例如,使用自增的 product_id
比依赖可能被重复使用或拼写错误的商品名称更安全。
尽管代理键广泛有用,但它们需要仔细实施。开发者在必要时仍必须在自然键上强制执行唯一性——例如,即使存在 user_id
代理键,也要在 user_email
列上添加唯一约束。代理键还增加了一层抽象:应用程序可能需要连接表以检索有意义的业务数据,这可能会稍微影响查询复杂度。然而,这些权衡通常会被稳定性和简单性带来的好处所抵消。在实践中,代理键和自然键常常并存,前者处理关系,后者强制执行业务特定的唯一性规则。