SQL Server Int或BigInt数据库表ID

Rob*_*ood 51 sql sql-server

我正在编写一个新程序,它需要一个数据库(SQL Server 2008).我现在为系统运行的所有东西都是64位,这让我想到了这个问题.对于各种表中的所有Id列,我应该将它们全部设为INT还是BIGINT?我怀疑该系统是否会超越INT范围,但我认为它可能在一些较大的财务表中.似乎INT是标准虽然......

mar*_*c_s 107

好的,让我们快速回顾一下数学:

  • INT是32位,基本上给你40亿个值 - 如果你只计算大于零的值,它仍然是20亿.你有这么多员工吗?顾客?库存产品?您公司一生中的订单?真?

  • BIGINT远远超出了它.你真的需要吗?真的?如果你是天文学家,或者是粒子物理学 - 也许.平均业务线用户?我强烈怀疑

想象一下,你有一张表 - 比如 - 1000万行(贵公司的订单).假设您有一个Orders表,并且您创建BIGINT的OrderID被其他5个表引用,并在Orders表中的5个非聚集索引中使用 - 我认为,这不是过度的,对吧?

1000万行,5个表加5个非聚集索引,这是1亿个实例,每个实例使用8个字节而不是4个字节--4亿个字节= 400 MB.完全浪费......你需要更多的数据和索引页面,你的SQL Server必须从磁盘读取更多页面并缓存更多页面......这对你的表现没有好处 - 简单明了.

加:大多数程序员都没有想到:是的,磁盘空间很便宜.但是,浪费的空间也与SQL Server RAM内存和数据库缓存相关 - 而且这个空间并不便宜!

所以要做一个很长的帖子:使用最适合你需要的INT类型; 如果要处理10-20个不同的值 - 使用TINYINT.如果你需要一个顺序表,我相信INT应该PLENTY ENOUGH - BIGINT只是浪费空间.

另外:如果你的任何表真的接近达到2到40亿行,你仍然有足够的时间将你的表升级为BIGINT ID,如果那真的需要.......

  • 考虑ATT:假设有1亿客户,每天1个文本,持续30天,那就是30亿条记录需要一个id字段才能使用一个月.我在一家手机公司(不是ATT)工作,我觉得你对bigint的解雇是不必要的,缺乏想象力.随着手机服务日常和平凡的东西,仅仅是不够的.话虽如此,我感谢你说的其他一切. (19认同)
  • 我给出了一个关于`int`是不够的相关的真实例子.我不确定你为什么选择对此嗤之以鼻.如果你对这个例子有一些疑虑,或者你认为你有一个理由`int`就足够了手机元数据,请告诉我.我总是希望在工作上做得更好. (18认同)
  • 我实际上必须执行这样的更新,你是对的,我们有超过6个月的警告,并没有那么难.具有讽刺意味的是,整个密钥即将在下一个版本中消失,因为它确实没有必要.通常我厌恶自然键,但当你的桌子上有数十亿行时,是时候开始考虑它们了; 插入50,000多行时,100 GB更多可用磁盘空间和一个更新索引是非常好的激励. (6认同)
  • @ user38858:所以使用"BIGINT"身份,这对AT&T来说只有300万个月的好处.... (4认同)

Aar*_*ght 14

您应该使用对相关表有意义的最小数据类型.这包括使用smallint或甚至tinyint没有足够的行.

您将节省数据和索引的空间并获得更好的索引性能.使用bigint时,所有你需要的是一个smallint类似于使用varchar(4000)时,所有你需要的是一个varchar(50).

即使机器的本机字大小为64位,这也只意味着64位CPU操作不会比32位操作.大多数时候,它们也不会更快,它们也会一样.但是大多数数据库都不会受到CPU限制,它们将受到I/O限制,并且在较小程度上受内存限制,所以当你需要执行一个数据时,50%-90%的数据大小是非常好的.索引扫描超过2亿行.

  • @Hogan:好点.为了准确地描述领域要求,合理的最大尺寸更好,但更好的类比可能是`char(10)`与`char(50)`. (6认同)
  • @Aaronaught好帖子+1,快速提问; 我的印象是varchar(50),varchar(4000)和varchar(max)都占用了相同的空间,对于一个小于50的给定字符串,差异只是在一个限制SQL中放置了字段的大小可.(http://msdn.microsoft.com/en-us/library/aa258242(SQL.80).aspx) (4认同)

Ric*_* B. 14

这是一篇关于性能的一些真实答案的文章......如果可能的话,我更愿意用硬数字回答问题......如果你点击以下链接至少有一百万条记录,你会发现磁盘使用量的差异可以忽略不计. ..

http://www.sqlservercentral.com/articles/Performance+Tuning/2753/

就个人而言,我确实认为使用适当的ID大小很重要,但也要考虑到这样一个事实,即随着时间的推移,你可能会有一个表有大量活动的表.这不是存储大量数据,而是由于自动递增的性质(随时间发生删除和插入)而导致密钥值增加.

考虑社区站点上的文件存储库,或社区站点多租户应用程序上的用户注释的ID.

我知道大多数开发人员正在构建永远不会触及数百万条记录的系统,但重要的是要注意有必要使用bigint的原因,而且我仍然不相信当你设计一个你不知道的模式时你不应该试图预测未来的潜在增长,如果你觉得随着id值的增长潜力超过int的最大值,可以考虑使用bigint.

  • 请添加链接文章中的相关信息,因为它不可用,似乎需要注册. (2认同)

gbn*_*gbn 6

32位数字与x86架构或64位与x64架构的对齐称为数据结构对齐

这对于数据库中的数据没有意义,因为这里有影响性能的磁盘空间,数据缓存和表/索引体系结构(如其他答案中所述).

请记住,这不是CPU访问数据.它是在CPU上运行并操纵数据的数据库引擎代码(可能是对齐的,但是谁在乎?).当/如果您的数据通过CPU时,它肯定不会在相同的磁盘结构中.


小智 6

其他人已经为32位ID提供了令人信服的答案.

对于某些应用程序,64位ID确实更有意义.

如果要保证ID在数据库集群中是唯一的 - 对于ID,63位可以非常方便.使用32位,很难在群集中的服务器之间分配ID的生成; 或跨数据中心.虽然64位有足够的空间可以使用,但您可以方便地在服务器上生成ID而无需锁定,并且仍然保证唯一性.

例如,请参阅Twitter SnowflakeInstagram Engineering的博客文章"Sharding&ID at Instagram".两者都提供了很好的理由,为什么63或64位的ID比32位计数器更有意义.


小智 5

对于任何不使用 TB 大小的数据库或具有恒定和高容量插入的表的人来说,第一个答案是天真的答案。在任何大小合适的数据库中,您都会在其生命周期的某个阶段遇到 INT 问题。如果必须的话,请使用 BIGINT,因为这会节省很多麻烦。我见过一些公司在仅获得一年的数据后就遇到了 INT 问题,并且如果无法重新播种,就会导致大量停机。此外,在长期运行的系统(10 年以上)中,预计系统不会继续使用,即使使用清除旧数据的中等大小的数据库,也会受到影响。在大多数需要大量数据的情况下,最好使用 GUID,但如果需要,则禁止使用 BIGINT。