是的,对于主键使用字符串而不是数字类型绝对会带来负面影响,并且如果PK是集群的(在您的情况下确实如此),甚至会带来更多负面影响。但是,您看到使用字符串字段的效果的程度取决于以下情况:a)此表中有多少行,b)其他表中有多少行被此PK外键了。如果您在此表中只有1万行,而在其他一些表中只有10万行,那么您可以通过该字段将该表FK链接到该表,那么也许不会那么引人注意。但是随着行数的增加,这些影响肯定会变得更加明显。
您需要考虑将聚集索引中的字段转移到非聚集索引中。因此,您不仅要查看每行最多40个字节,还需要查看(40 * some_number)个字节。并且在任何FK表中,行中具有相同的40个字节,而且经常在该字段上使用非聚集索引,因为在JOIN中使用了该索引,所以现在在FK到的任何表中它实际上都增加了一倍这个。如果您倾向于认为40字节* 100万行* 10份副本无关紧要,请参阅我的文章“ 磁盘便宜”!奥利?详细说明了此决定影响的所有(或至少大部分)领域。
要考虑的另一件事是,对字符串进行过滤和排序,尤其是在不使用二进制归类(我假设您使用的是数据库默认值,通常不区分大小写)的情况下,效率要低得多(即花费的时间更长),而在使用INT
/时BIGINT
。这会影响对该字段进行过滤/联接/排序的所有查询。
因此,CHAR(5)
对于集群式PK ,使用类似的命令可能是可以的,但是大多数情况下,如果它也是用COLLATE Latin1_General_100_BIN2
(或类似的)定义的。
[CODE]
永远的价值会改变吗?如果是,那么甚至有更多理由不将其用作PK(即使将FK设置为ON UPDATE CASCADE
)。如果它不能或永远不会改变,那很好,但是仍然有足够多的理由不使用它作为集群PK。
当然,该问题的措词可能不正确,因为您当前在PK中已经具有此字段。
无论如何,到目前为止,最好的选择是[ID_CODE]
用作群集PK,将相关表中的该字段用作FK,并保持[CODE]
为a UNIQUE INDEX
(这意味着它是“备用键”)。
在此答案的评论中根据此问题更新更多信息:
如果我使用[CODE]列查找表,则[ID_CODE]作为主键是最好的选择吗?
这一切都取决于很多因素,我已经提到了其中一些因素,但将重申一下:
主键是识别单个行的方式,无论是否被任何外键引用。您的系统如何在内部标识该行与(或不一定)与用户如何标识自己/该行相关。任何具有唯一数据的NOT NULL列都可以工作,但是要考虑实用性问题,特别是如果PK实际上是由任何FK引用的。例如,GUID是唯一的,出于某些原因,某些人真的很喜欢使用它们,但是它们对于聚簇索引是很不利的(NEWSEQUENTIALID
更好,但不是完美的)。另一方面,GUID可以很好地用作备用键,并由应用程序用来查找行,但是JOIN仍然使用INT(或类似)PK来完成。
到目前为止,您还没有告诉我们该[CODE]
字段如何从各个角度适应系统,在此之前,您还没有提到这是您查找行的方式,但是对于所有查询还是仅某些查询?因此:
关于[CODE]
值:
- 它是如何产生的?
- 它是增量的还是伪随机的?
- 是统一长度还是可变长度?
- 使用什么字符?
- 如果使用字母字符:区分大小写还是不区分大小写?
- 插入后是否可以更改?
关于此表:
- 该表还有其他表吗?或者这些字段(
[CODE]
或[ID_CODE]
)是否在其他表中使用,即使未明确使用外键?
- 如果
[CODE]
是唯一用于获取单个行的[ID_CODE]
字段,那么该字段起什么作用?如果不使用它,为什么要首先使用它(这可能取决于对“该[CODE]
领域是否可以改变?” 的回答)?
- 该表中有多少行?
- 如果其他表引用该表,那么每个表中有多少行?
- 该表的索引是什么?
不能仅基于“ NVARCHAR是或否?”问题做出此决定。我会再次说,总的来说,我并不认为这是一个好主意,但是肯定有很多时候是可以的。由于该表中的字段太少,因此不可能再有索引,或者至少没有索引。因此,无论哪种方式都可以[CODE]
作为聚集索引。并且,如果没有其他表引用该表,那么也可以将其设为PK。但是,如果其他表确实引用了该表,那么[ID_CODE]
即使非聚集,我也会选择该字段作为PK。