使用外部ID作为主键,有问题吗?

问题描述 投票:0回答:1

所以我有订阅表,它可以来自外部源(Webhook),也可以在仪表板中手动创建。

所以我可以通过两种方式存储它:

  1. 使用外部ID作为主要ID 我喜欢这个想法,因为这样每当我想要处理订阅时我就不需要检查另一列(让我们称之为提供)。我可以直接使用 ID 查询订阅,仅此而已! 有人可能会认为它们可能会发生冲突并且不是唯一的,好吧,无论如何,它们中的大多数都是 UUID,但万一我将来有另一个使用整数 ID 的提供程序,我可以添加一个提供程序后缀,因此 id 值将类似于 { provider_suffix}_{external_id},同样,都在同一列中。

  2. 在其中存储外部ID是自己的列与数据库生成的另一个自动增量ID一起 问题是我每次想要检索 ID 时都需要检查提供者列。如果提供者是手动的,那么external_id将为空,并且ID是存储在id列中的内容,而不是外部ID;你可以看到这如何很快变得复杂。 另一件事是,ORM 提供了在实体之间建立关系的方法,但它不适用于 2 列。例如,我正在使用 Laravel。如果没有复杂的自定义编码,拥有一个名为 item 的关系,该关系与外部 ID 或内部 ID 相关,而该关系依赖于名为“provider”的第三列。

问题是,我总是看到第2点在开源系统上实现,但从未见过第1点。它有什么问题吗?什么是最佳实践?

laravel database primary-key
1个回答
0
投票

既然你提到了 Laravel,我就结合它的上下文来回答吧。

从特定提供商检索订阅并不复杂:

用户.php

public function subscriptions() {
  return $this->hasMany(Subscription::class);
}

订阅.php

public function scopeStripe(Builder $query): void {
  $query->where('provider', Providers::STRIPE);
}

public function scopeManual(Builder $query): void {
  $query->whereNull('provider');
}

用途:

$stripeSubId = $request->input('stripe_subscription_id');
$stripeSubscription = $user->subscriptions()->stripe()->find($stripeSubId);

$manualSubId = $request->input('manual_subscription_id');
$manualSubscription = $user->subscriptions()->manual()->find($manualSubId);

总的来说,我认为从数据库设计的角度来看,依赖元组(external_id,provider)是完全可以的,并且是一个很好的抽象。另外,它不太容易出错(因为您永远不会冒冲突的风险),并且依赖于现有的数据库优化(如果您想查询特定提供商的所有订阅怎么办?)。

© www.soinside.com 2019 - 2024. All rights reserved.