【问题标题】:Laravel ID primary auto increment alternativeLaravel ID 主自动增量替代方案
【发布时间】:2019-10-07 22:03:47
【问题描述】:

在我的应用程序中,大部分 ID(user_id、classic_id、post_id、assessment_id 等)都是公开的,这意味着它们要么在 URL 中,要么在目录名称中。出于安全原因,我希望每个表都有 10 个字符的随机 ID,而不是自动递增的。

我可以使用时间戳,但这并不是真正唯一的,并且添加了随机数会变得更长(例如,我必须添加 4 个随机数以每秒处理多达 10.000 个数据库插入到一个表中...... . 纯粹假设它不可扩展)。

现在我希望创建一个 10 个字符的随机 ID,这将给我 100 亿个可能的 ID 组合。所以产生重复的机会很小,长度也可以接受。

use Keygen;

$id = Keygen::numeric(10)->generate();

你认为我的想法有道理吗?有谁知道使用 10 个字符的主 ID 是否会对我的数据库性能产生负面影响?谢谢!

【问题讨论】:

  • 可能值得尝试类似github.com/spatie/laravel-binary-uuid
  • YouTube 使用了 11 个看似字母数字的字符。如果您关心的是 URL 上的内容,那么 6 个字母数字字符可能比 10 个数字看起来更好,并为您提供大约 570 亿个可能的值。如果您关心的是存储,那么 6 个字母数字 ASCII 字符占用 6 个字节,但 long 占用 8 个字节,因此稍微小一些。另一方面,如果你确实使用了 long 那么你真的会浪费它,因为 long 最多可以容纳大约 20 位数字
  • @KyleWardle 不幸的是,UUID 不是 URL 友好的。
  • @apokryfos 是的,我考虑过使用 6 个字母数字字符。但是,使用字母数字字符串作为主 ID 会大大降低数据库速度。
  • 这里的想法是您仍然会使用自动递增的主 ID 来提高速度,但只能在内部使用它们。将它们添加到模型的 $hidden 数组中可以防止它们意外暴露在 json 响应中

标签: php laravel auto-increment


【解决方案1】:

你最好改用UUID

您使用什么数据库类型?大部分数据库类型都支持UUID类型,可以自动生成,不用自己生成。

查看: https://dev.mysql.com/doc/refman/8.0/en/miscellaneous-functions.html#function_uuid

【讨论】:

  • 我知道 UUI,但它们对 URL 不友好,因为它们有很多字符。
  • @arety_ 如果这对您来说是个问题,您可以使用 PHP 函数 uniqid() 生成一个简短的唯一标识符。附言。在 URL 中使用 UUID 不是技术问题。
【解决方案2】:

我可以推荐三个用于 ID 生成的包。

  1. Webpatser 的 Laravel UUID 包
    允许为您的模型生成 UUID,设置和使用相当简单。这种类型的 id 是不可预测的,可能被认为更安全,但无法在您的数据库中排序。 Github
  2. Vinkla 的 Laravel Hashids 包
    保留您当前的 id 并获取一个可以解密的哈希,以公开混淆 id。 Github
  3. Hafael 的 Laraflake 包
    Twitter 雪花一样的 id 生成,性能好,功能更好,id 可以排序。 Github

您可以查看所有三个可用的软件包,然后选择一个,或者您可以根据这些软件包制作一个 DIY 解决方案。

【讨论】:

  • 您可以通过将 UUID 添加到数据库配置中来使用不带包的 UUID(请参阅上面的答案)更快,您将在创建时自动获取 UUID
  • 是的,你可以,但是那个包提供了一个带有特征的引导程序,它可以连接到模型以在不同的模型事件上生成 id,它可以手动完成,是的,但是这个包很方便,不必重写这一切
  • 刚刚为我当前的项目使用了 Vinkla 的 Laravel Hashids 包!
【解决方案3】:

您可以使用 UUID。我建议你使用默认的 Laravel 字符串辅助方法来生成 UUID。请参阅下文,了解如何实现这一目标。

use Illuminate\Support\Str;

$uuid = Str::uuid()->toString(); //this generates a v4 UUID.

在您的迁移中,您可以像这样指定uuid 列;

**
 * Run the migrations.
 *
 * @return void
 */
public function up()
{ 
    Schema::create('users', function (Blueprint $table) {
        $table->uuid('id')->primary(); //uuid field set to PK
    });
}

在你的模型中,比如User.php,设置以下属性。

protected $primaryKey = 'id';

public $incrementing = false;

protected $keyType = 'string';

我确实建议,您在表中保留一个自动增量列,以帮助您确定记录数,而无需编写任何查询(这是可选的)。例如。假设这样的列是rowId,您可以通过将其添加到模型上的隐藏属性数组中来将其隐藏在您的响应中。例如。

protected $hidden = [
    'password', 'remember_token', 'rowId'
];

希望这会有所帮助。

【讨论】:

  • 是的,我知道 UUID,但是它们有很多字符可以在用户友好的 URL 中使用它们。
猜你喜欢
  • 2011-03-21
  • 2013-12-07
  • 2018-04-11
  • 2011-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多