数据库设计Primay Key,ID vs String

Mic*_*han 22 database database-design

我目前正计划开发音乐流媒体应用程序.我想知道作为服务器上的表中的主键会更好.ID int或唯一字符串.

方法1:

歌曲表: SongID(int),Title(字符串),*Artist**(字符串),Length(int),*Album**(string)

流派表格 类型(字符串),名称(字符串)

SongGenre:***SongID****(int),***类型****(字符串)

方法2

歌曲表: SongID(int),Title(字符串),*ArtistID**(int),Length(int),*AlbumID**(int)

流派表 GenreID(int),名称(字符串)

SongGenre:***SongID****(int),***GenreID****(int)

键:粗体 =主键,*字段**=外键

我目前正在使用方法2进行设计,因为我相信它会加快查找性能并减少使用空间,因为int占用的空间比字符串少得多.

有什么理由这不是个好主意吗?有什么我应该知道的吗?

Ode*_*ded 20

你正在做正确的事情 - 身份字段应该是数字而不是基于字符串,既节省空间又出于性能原因(字符串上的匹配键比整数上的匹配慢).

  • -1:这些是做出设计决策的错误理由.根据它是否是正确的_design_做出设计决策.然后,如果存在性能问题,请根据需要进行调整和重新设计. (32认同)
  • @Oded 我可能同意你的看法。但我经常在我的空间中看到它,因此 YMMV。这绝对是一种权衡。我倾向于 String 因为 - 性能或存储将来会成为更大的问题吗?可能没有-摩尔定律。数据不一致会成为问题吗?是的,因为今天有 x 个系统来处理数据,而明天它将是 x + y。如果您说您的系统将永远处于孤岛状态(我打赌不会),那么您对任何事情都很好。别管。 (5认同)
  • 我同意麦克斯的观点。使用自然键进行设计。这是过早优化的又一个例子。技术密钥有一席之地,但它们不是免费的 (3认同)
  • 绝对+1。一个ID应该(几乎总是)是一个INT-其他任何意义都没有多大意义(除了少数选择的情况) (2认同)
  • -1:整数不具有良好的ID。在系统外部,可以使用几种不同的方式来处理整数,但是可以使用较少的方式来处理字符串。当您跨系统移动数据时,这会使ID更可靠(请确保有一天会这样做)。如Max所指出的,拥有空间和性能的整数还为时过早。我认为应该保留数字数据类型用于计算目的。 (2认同)

Dav*_*ave 14

有什么理由这不是个好主意吗?有什么我应该知道的吗?

是.如果需要在单个数据库之外唯一标识相同的数据,则整数ID非常糟糕.例如,如果必须将相同的数据复制到具有可能预先存在的数据的另一个数据库系统中,或者您具有分布式数据库.要注意的最重要的事情是,类似的整数7481在该数据库之外没有任何意义.如果以后需要增长该数据库,则可能无法通过手术删除您的数据.

另外要记住的是整数ID不够灵活,因此不能轻易用于特殊情况.互联网协议的设计者理解这一点并采取预防措施,将某些数字块以某种方式分配为"特殊"(广播IP,私有IP,网络IP).但这只是可能的,因为有一个围绕这些数字使用的协议.许多数据库不能在如此明确定义的协议中运行.

FWIW,有点像试图决定"强类型"编程范式是否优于"弱/动态类型"编程范例.这取决于你需要做什么.

  • IP 地址是一个特别恰当的例子。它们对于其预期目的来说已经不够大了,但它们仍然徘徊不去,因为此时改变系统是一项艰巨的任务。 (2认同)

mic*_*lbn 8

从软件的角度来看,GUID在全球范围内更为独特.

引用自:主键:ID与GUID

使用GUID作为行标识值比32位整数感觉更自然 - 当然更真实唯一.数据库大师Joe Celko 似乎同意.GUID主键很适合许多开发方案,例如复制,或者需要在数据库外部生成主键时.但它仍然是在平衡传统的4字节整数ID和16字节GUID之间的权衡的问题:

GUID优点

  • 每个表,每个数据库,每个服务器都是唯一的
  • 允许轻松合并来自不同数据库的记录
  • 允许跨多个服务器轻松分发数据库
  • 您可以在任何地方生成ID,而不必往返数据库
  • 大多数复制方案无论如何都需要GUID列

GUID缺点

  • 它比传统的4字节索引值大4倍; 如果你不小心,这可能会产生严重的性能和存储影响
  • 在userid ='{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}'的地方调试很麻烦
  • 生成的GUID应该是部分顺序的以获得最佳性能(例如,SQL 2005上的newsequentialid())并允许使用聚簇索引