Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在MySQL中使用数字行ID的优点是什么?_Mysql_Sql_Performance - Fatal编程技术网

在MySQL中使用数字行ID的优点是什么?

在MySQL中使用数字行ID的优点是什么?,mysql,sql,performance,Mysql,Sql,Performance,我是SQL新手,从关系而不是层次的角度思考数据集对我来说是一个很大的转变。我希望能够了解使用数字行ID作为主键而不是字符串值的性能(在存储空间和处理速度方面)与设计复杂性之间的关系,因为字符串值更有意义 具体来说,这就是我的情况。我有一个包含几百行的表(“父表”),其中一列是字符串标识符(10-20个字符),这似乎是表主键的自然选择。我有第二个表(“子表”),其中有数十万(或者可能有数百万或更多)行,其中每一行都引用父表中的一行(因此我可以在子表上创建外键约束)。(实际上,我有几张这两种类型的表

我是SQL新手,从关系而不是层次的角度思考数据集对我来说是一个很大的转变。我希望能够了解使用数字行ID作为主键而不是字符串值的性能(在存储空间和处理速度方面)与设计复杂性之间的关系,因为字符串值更有意义

具体来说,这就是我的情况。我有一个包含几百行的表(“父表”),其中一列是字符串标识符(10-20个字符),这似乎是表主键的自然选择。我有第二个表(“子表”),其中有数十万(或者可能有数百万或更多)行,其中每一行都引用父表中的一行(因此我可以在子表上创建外键约束)。(实际上,我有几张这两种类型的表,其中都有一组复杂的引用,但我认为这一点可以理解。)

因此,我需要在子表中有一列,为父表中的行提供标识符。天真地说,创建类似VARCHAR(20)的列来引用第一个表中的“自然”标识符会导致巨大的性能损失,无论是在存储空间还是查询时间方面,因此我应该包含一个数字(可能是自动增量)id列,并将其用作子表中的引用。但是,由于我加载到MySQL中的数据还没有这样的数字ID,这意味着增加了代码的复杂性,并增加了出现错误的机会。更糟糕的是,由于我在进行探索性数据分析,我可能希望在不处理子表的情况下处理父表中的值,因此我必须小心,不要因为删除行和丢失数字id而意外破坏关系(我可能会通过将ID存储在第三个表或类似的傻事来解决这个问题。)

因此,我的问题是,是否有我可能不知道的优化,这意味着一个数十万或数百万行的列只反复重复几百个字符串值,比它最初出现的浪费更少?我不介意为了简单性而适度降低效率,因为这是用于数据分析而不是p生产,但我担心我会把自己编码到一个角落,我想做的每件事都需要大量的时间来运行


提前感谢。

您从数值中获得的主要好处是它们更容易“索引”。索引是MySQL用来更容易找到值的过程

通常,如果你想在一个组中找到一个值,你必须在该组中循环寻找你的值。这很慢,最坏的情况是O(n)。如果你的数据是一种很好的、可搜索的格式,比如a,if可以在O(n)中找到,那么速度要快得多

索引是MySQL用来准备要搜索的数据的过程,它生成搜索树和其他聪明的do Bob,这将使查找数据更快。它使许多搜索更快。但是,要做到这一点,它必须将您搜索的值与各种“键”值进行比较,以确定您的值是否大于或小于键。


这种比较可以在非数值上进行。但是,比较非数值要慢得多。如果您希望能够快速查找数据,最好的选择是您有一个使用的整数“键”。

我不会主要考虑空间因素。整数键通常会占用四个字节。varchar将根据字符串的长度,占用1到21个字节。因此,如果大多数仅为几个字符,则
varchar(20)
键将比整型键占用更多的空间。但不会比整型键占用更多的空间

顺便说一句,两者都可以利用索引,因此访问速度并没有特别不同(当然,较长/可变长度的键对索引性能的影响很小)

有更好的理由使用自动递增的主键

  • 您知道最近插入了哪些值
  • 如果出现重复项(当然主键不应该出现重复项),则很容易确定要删除的项
  • 如果您决定更改其中一个条目的“名称”,则不必更新引用它的所有表
  • 您不必担心前导空格、尾随空格和其他奇怪的字符

  • 您确实需要为额外的功能付费,因为记录中还有四个字节用于某些看似无用的内容。但是,这样的效率还不成熟,可能不值得付出努力。

    数字行id比基于字符串的id有许多优势。 其他答案中提到了其中大部分。 1.其中之一是索引。默认情况下,主键在关系数据库中被索引。因此,拥有数字键总是更有效。 2.数字字段的存储效率更高 2.使用数字键进行连接要快得多。 3.行id可以是外键。数字id存储紧凑,效率高 4.我认为在主键上使用自动递增也有它的优点

    -谢谢 _桑

    戈登是对的(这并不奇怪)

    在我看来,以下是你不必担心的考虑因素

    当您处理几十兆行或更少的数据时,存储空间基本上是免费的。不必担心INT和VARCHAR(20)之间的差异,也不必担心添加一两列所需的磁盘空间成本。只需花大约100美元就可以买到像样的TB驱动器,这并不重要

    INT和VARCHAR都可以非常高效地编制索引。在时间性能方面,您不会看到太大的差异

    这是你应该担心的

    索引性能中有一个明显的缺陷,您可能会遇到字符索引
     WHERE colm IS NULL   /* slow! */
    
     WHERE colm IS NOT NULL  /* slow! */
    
     WHERE SUBSTR(colm,1,3) = 'abc'  /* slow! */
    
     parent       varchar(20)   pk  fk to parent table
     birthorder   int           pk
     name         varchar(20)
    
      parent      birthorder     name
      homer       1              bart
      homer       2              lisa
      homer       3              maggie
    
      homer       1              badbart