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)
(更小并且比较是二元的)更好的选择,但它实际上只是一个“不太糟糕”的选择,而不是“更好/好的选择”。
归档时间: |
|
查看次数: |
10356 次 |
最近记录: |