zey*_*zey 0 sql-server primary-key uniqueidentifier sql-server-2008-r2 alter-table
我有带有 id(primary key - int) 和身份规范 (1,1) 的表。
我想将此列更改为uniqueidentifier默认值 ( newid()) 。
我尝试过的是
ALTER TABLE myTable ALTER COLUMN id uniqueidentifier default NEWID();
Run Code Online (Sandbox Code Playgroud)
但我收到了这条消息
Incorrect syntax near the keyword 'default'.
Run Code Online (Sandbox Code Playgroud)
此外,我的数据库的每个表都有id主键列,我想通过循环或其他方式将它们更改uniqueidentifier为默认值。newID()
我的数据库的每个表都有 id 主键列,我想将它们更改为 nvarchar(36) 并使用默认的 newID()
不。您不想做出这样的改变,因为这样做不会带来任何好处。
您当前的 PK(我认为是集群)是:
您想要将其更改为集群 PK,即:
NVARCHAR)。UNIQUEIDENTIFIER它并没有那么糟糕,因为它仍然是二进制比较,就像 with 一样INT,但它是 16 个字节,INT而不是 4 个字节。将其存储为字符串现在是 36 个字符的比较(36 个字节 inVARCHAR和 72 个字节 in NVARCHAR)这比 16 字节慢UNIQUEIDENTIFIER。最后,大多数将 GUID 存储为字符串的人忘记使用二进制排序规则(例如Latin1_General_100_BIN2)来至少进行逐字节比较,因为不需要语言规则。使用不区分大小写的排序规则,甚至区分大小写的排序规则,肯定会更慢,因为它将应用基于区域设置的语言规则。FILLFACTOR页面拆分的数量,那么您也会降低索引的性能,因为索引分布在大量页面上。请记住此更改对下游的负面影响,原因如下:
聚集索引键被复制到非聚集索引中。再次假设该 PK 是聚集的,则该表上的每个非聚集索引都将复制该 72 字节值。这个表上的三个非聚集索引是72字节*3=216字节加上原来的聚集索引的72=288字节。另一方面,当前的大小INT只有 4 个字节 * 3 = 12 个字节加上原来的 4 = 16 个字节。每行。
PK 通常由 FK 使用,FK 是将 PK 复制到一个或多个其他表中。每行 72 字节仅用于此表。如果此 PK 在其他 2 个表中用作外键,则为 72 字节 * 2 = 144 额外字节。另一方面,当前INT只有 4 字节 * 2 = 8 字节。
FK列是否有索引?如果是,则又是 72 个字节,而不是 4 个字节。
数据页在其行可以被读取和使用之前被加载到内存(即缓冲池)中。较大的行和/或较低的FILLFACTOR行意味着需要更多的数据页来保存这些行。这意味着需要更多的时间将它们从磁盘读取到内存中,显然它们需要更多的内存。此需求与其他查询、计划缓存等竞争。
如果您需要一个 GUID 来获得外部系统知道的值,只需添加一UNIQUEIDENTIFIER列并为其建立索引即可;然后您可以查找它以获取INT用于所有其他 JOIN 等的值。并且,如果必须将其存储为字符串,则使用VARCHAR给定的唯一字符是A, B, C, , D, E,F和-(NVARCHAR是完全不必要的浪费空间)并确保指定二进制排序规则(以 结尾_BIN2)。
但不要改变当前的结构。
关于问题的更新,其中澄清了要更改为的预期数据类型是 trueUNIQUEIDENTIFIER而不是NVARCHAR(36):总体建议不会从“不这样做”改变。虽然UNIQUEIDENTIFIER是一个比NVARCHAR(36)(更小并且比较是二元的)更好的选择,但它实际上只是一个“不太糟糕”的选择,而不是“更好/好的选择”。