在MySQL中使用数字行ID的优点是什么?
我是SQL新手,从关系而不是层次的角度思考数据集对我来说是一个很大的转变。我希望能够了解使用数字行ID作为主键而不是字符串值的性能(在存储空间和处理速度方面)与设计复杂性之间的关系,因为字符串值更有意义 具体来说,这就是我的情况。我有一个包含几百行的表(“父表”),其中一列是字符串标识符(10-20个字符),这似乎是表主键的自然选择。我有第二个表(“子表”),其中有数十万(或者可能有数百万或更多)行,其中每一行都引用父表中的一行(因此我可以在子表上创建外键约束)。(实际上,我有几张这两种类型的表,其中都有一组复杂的引用,但我认为这一点可以理解。) 因此,我需要在子表中有一列,为父表中的行提供标识符。天真地说,创建类似VARCHAR(20)的列来引用第一个表中的“自然”标识符会导致巨大的性能损失,无论是在存储空间还是查询时间方面,因此我应该包含一个数字(可能是自动增量)id列,并将其用作子表中的引用。但是,由于我加载到MySQL中的数据还没有这样的数字ID,这意味着增加了代码的复杂性,并增加了出现错误的机会。更糟糕的是,由于我在进行探索性数据分析,我可能希望在不处理子表的情况下处理父表中的值,因此我必须小心,不要因为删除行和丢失数字id而意外破坏关系(我可能会通过将ID存储在第三个表或类似的傻事来解决这个问题。) 因此,我的问题是,是否有我可能不知道的优化,这意味着一个数十万或数百万行的列只反复重复几百个字符串值,比它最初出现的浪费更少?我不介意为了简单性而适度降低效率,因为这是用于数据分析而不是p生产,但我担心我会把自己编码到一个角落,我想做的每件事都需要大量的时间来运行在MySQL中使用数字行ID的优点是什么?,mysql,sql,performance,Mysql,Sql,Performance,我是SQL新手,从关系而不是层次的角度思考数据集对我来说是一个很大的转变。我希望能够了解使用数字行ID作为主键而不是字符串值的性能(在存储空间和处理速度方面)与设计复杂性之间的关系,因为字符串值更有意义 具体来说,这就是我的情况。我有一个包含几百行的表(“父表”),其中一列是字符串标识符(10-20个字符),这似乎是表主键的自然选择。我有第二个表(“子表”),其中有数十万(或者可能有数百万或更多)行,其中每一行都引用父表中的一行(因此我可以在子表上创建外键约束)。(实际上,我有几张这两种类型的表
提前感谢。您从数值中获得的主要好处是它们更容易“索引”。索引是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