【问题标题】:Why would I use ID in MySQL when I can search with the username?当我可以使用用户名进行搜索时,为什么要在 MySQL 中使用 ID?
【发布时间】:2021-03-05 02:44:22
【问题描述】:

在许多关于 MySQL 的教程中,他们经常使用在用户创建帐户时自动创建的 ID。稍后,该 ID 用于搜索该配置文件或更新该配置文件。

问题:当我可以使用用户名进行搜索时,为什么我要在 MySQL 中使用 ID?

我也可以使用用户名在 MySQL 表中进行搜索,那么使用 ID 的优缺点是什么?

更新:

非常感谢您的反应! 因此,假设用户想要登录网站。他将提供用户名和密码。但是对于我的代码,我首先必须进行查询才能知道 ID,因为用户不知道 ID。这是正确的还是有其他方法可以做到?

如果我将用户的 ID 存储在 cookie 中,当用户登录时,我首先查看 ID 是否与用户名相符。然后检查密码是否正确。然后我可以使用 ID 进行查询。这是个好主意吗?当然,我会在所有这些上使用准备好的语句。

【问题讨论】:

  • 可以在Wikipedia - Surrogate key上阅读代理键相关的优缺点
  • 谢谢您,您对更新问题有任何想法吗?
  • 在数据库中插入一行时,可以得到最后插入的ID。在 MySQL 中,您可以使用 [LAST_INSERT_ID()](http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id) 信息函数来获取新生成的 ID。这意味着,您不必在创建用户之前生成 ID,但您必须将用户插入到保存密钥的表中。顺便说一句,如果您有更多问题,请随时将其作为新问题发布。
  • 好的,谢谢,但我的意思是以下。假设用户创建帐户并在 4 天后登录,那么 LAST_INSERT_ID() 将不起作用。是否可以使用 cookie 直接从用户那里获取 ID?
  • 对不起,我的错 :) 当用户登录时,它提供了一个用户名,您将通过检索相应的 ID 来检查该名称。您可以将 ID 存储在会话中,也可以将会话 ID 存储在 cookie 中。请在网上搜索这些东西。这个话题对于这个网站来说太板了(特别是在 cmets 中谈论它)

标签: mysql


【解决方案1】:

请参考this post

1 - 更快。整数上的 JOIN 比字符串字段或字段组合上的 JOIN 快得多。比较整数比比较字符串更有效。

2 - 它更简单。与基于不同数据类型的其他字段的组合相比,基于单个数字字段映射关系要容易得多。

3 - 它与数据无关。如果您在 ID 上匹配,则无需担心关系会发生变化。如果你匹配一个名字,如果他们的名字发生变化(即结婚),你会怎么做?如果你匹配一个地址,如果有人搬家怎么办?

4 - 更高效 如果您在(自动递增的)int 字段上进行集群,您可以减少碎片并减少数据集的整体大小。这也简化了覆盖您的关系所需的索引。

【讨论】:

    【解决方案2】:

    来自“自动生成的 ID” 我假设您正在谈论一个具有属性 AUTO_INCREMENT 的整数列。

    数字自动递增的PK 优于字符串PK 的几个原因:

    • INT 类型的值是 stored on 4 bytes,一个字符串使用 1 到 4 个字节用于每个字符,具体取决于字符集和字符(加上 1 或 2 个额外字节,用于存储实际字符串长度) VARCHAR 类型)。除非您的 string 列仅包含 2-3 个 ASCII 字符,否则 INT 总是比字符串占用更少的空间;这会影响该列表中接下来的两个条目。

    • 主键是一个索引,任何索引都用于加快表中行的搜索。通过将搜索到的值与存储在索引中的值进行比较来完成搜索。比较整数值(INTINT)需要单个 CPU 操作;它工作得非常快。比较字符串值更难:比较两个字符串中的对应字符,考虑到它们的编码、排序、大小写等特性;通常需要比较多对字符;这需要大量 CPU 操作,并且比比较 INTs 慢得多。

    • InnoDB storage engine 在表的每个索引中保留对PK 的引用。如果表的PK 未设置或不是数字,InnoDB 在内部创建一个数字自动递增列并使用它(并使可见的PK 也引用它)。这意味着您不会通过添加额外的 ID 列来浪费任何数据库空间(或者如果您希望以相反的方式获得它,则不添加它也不会节省任何东西)。
      为什么 InnoDB 会这样工作?再读一遍上一条。

    • 表的PK 通常在相关表中迁移为FK。这意味着第一个表中每一行的PK 列的值复制 到相关表的FK 字段中(想想employee 的经典示例,它适用于departmentdepartmentdepartment_id 列复制到 employee 表中)。这里的列类型会影响已用空间和速度(FK 通常用于查询中的JOINWHEREGROUP BY 子句)。

    【讨论】:

      【解决方案3】:

      这是很多人这样做的一个原因。

      如果用户名确实是关系的主键,则使用代理键 (ID) 至少是空间优化。在规范化过程中,您的关系可以拆分为几个表。将相关表中的username(varchar 30)替换为ID(int)作为外键可以节省大量空间。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-12-06
        • 2011-11-11
        • 2020-10-04
        • 2013-01-06
        • 1970-01-01
        • 1970-01-01
        • 2011-12-15
        • 1970-01-01
        相关资源
        最近更新 更多