发现后,我最好将主键从非集群更改为集群。比照有关标识列的聚集索引这个问题,下一步就是如何在prcatical的方式做到这一点。
我很惊讶我没有在 SO 上找到这个问题。
在我的表之间有参考引用,我不能简单地做
if object_id('MyChild') > 0 drop table MyChild
if object_id('Mytable') > 0 drop table Mytable
create table Mytable(
id int Not NULL
)
go
create table MyChild(
id int Not NULL,
masterid int NULL
)
go
alter table Mytable add constraint PK_Mytable primary key (id)
alter table MyChild add constraint FK_MyChild_MyTable foreign key (masterid) references Mytable(id)
go
-- Now I want to change the primary key into a clustered primary key
-- this throws …
Run Code Online (Sandbox Code Playgroud) 在 Sql Server (2008) 中,是否可以PRIMARY KEY
在一组列上有一个而没有同一组列上的任何一个CLUSTERED
或NONCLUSTERED
索引?
我知道PRIMARY KEY
和CLUSTERED INDEX
key 是不同的概念,我们可以在PRIMARY KEY
没有CLUSTERED INDEX
它的情况下创建(见下文)。
ALTER TABLE dbo.Sample
ADD CONSTRAINT PK_Sample_SeqGUID_Col1 PRIMARY KEY NONCLUSTERED (SeqGUID_Col1)
Run Code Online (Sandbox Code Playgroud)
但我的问题是看看是否可以PRIMARY KEY
在没有CLUSTERED
或NONCLUSTERED
索引的表上创建。
我和 Rick James 就这个问题进行了很长时间的讨论,我们提出了用复合键替换自动增量 pk 的想法,其中 int 限制接近 20 亿。我的表将在几个月内轻松达到此限制,因为我们每月捕获近几亿数据。下面是我的桌子的样子。关键表是gdata
所以我使用 3 个字段组合主表PRIMARY KEY (alarmTypeID,vehicleID,gDateTime)
。然后我有另一个表称为警报表。两者之间的联系是一对多的。这意味着其中的一个数据gdata
可以有零个或多个alarms
与之相关。它们之间的链接是vehicleID
和gDateTime
。
CREATE TABLE `gdata` (
`alarmTypeID` tinyint(4) NOT NULL DEFAULT '0',
`fleetID` smallint(11) NOT NULL,
`fleetGroupID` smallint(11) DEFAULT NULL,
`fleetSubGroupID` smallint(11) DEFAULT NULL,
`deviceID` mediumint(11) NOT NULL,
`vehicleID` mediumint(11) NOT NULL,
`gDateTime` datetime NOT NULL,
`insertDateTime` datetime NOT NULL,
`latitude` float NOT NULL,
`longitude` float NOT NULL,
`speed` smallint(11) NOT NULL
-- (see full text) …
Run Code Online (Sandbox Code Playgroud) 根据前端开发人员的建议,我考虑使用 UUID 作为新系统中一堆表的主键。从了解随机 UUID 与顺序 UUID 的优缺点,到将非聚集主键与可排序类型的聚集索引结合使用,我的研究向我指出了UUIDv6及其实现。
它能够生成如下所示的 UUID(即顺序的):
UUIDv1 UUIDv6 ------------------------------------ -------------- --------------- 5714f720-1268-11e7-a24b-96d95aa38c32 1e712685-714f-6720-a23a-c90103f70be6 68f820c0-1268-11e7-a24b-96d95aa38c32 1e712686-8f82-60c0-ac07-7d6641ed230d 7ada38f0-1268-11e7-a24b-96d95aa38c32 1e712687-ada3-68f0-93f8-c1ebf8e6fc8c 8cc06fd0-1268-11e7-a24b-96d95aa38c32 1e712688-cc06-6fd0-a828-671acd892c6a 9ea6a6b0-1268-11e7-a24b-96d95aa38c32 1e712689-ea6a-66b0-910c-dbcdb07df7a4
我认为 SQL Server 会很乐意在群集主键(唯一标识符)列中为我排序。
我几乎不知道 SQL Server 如何对 uniqueidentifier 列进行排序。这是升序排序结果:
UUIDv6 唯一标识符排序 --------------------- 1e712688-cc06-6fd0-a828- 67 1acd892c6a 1e712686-8f82-60c0-ac07- 7D 6641ed230d 1e712687-ada3-68f0-93f8- c1 ebf8e6fc8c 1e712685-714f-6720-a23a- c9 0103f70be6 1e712689-ea6a-66b0-910c- db cdb07df7a4
这会导致碎片,就像使用随机 UUID 一样。这篇文章解释了它们实际上是如何排序的。
幸运的是,该系统仍在开发中。接下来我应该选择哪些选项?
UUIDv6 UUIDv6 重新排序的字节 ------------------------------------ -------------- --------------- 1e712685-714f-6720-a23a-c90103f70be6 c90103f7-0be6-a23a- 6720-1e712685 714f 1e712686-8f82-60c0-ac07-7d6641ed230d 7d6641ed-230d- …