对主键或聚簇索引使用 1-1 关系?
Use 1-1 relationship for primary key or clustered index?
考虑下面的 tables T
和 U
。 T
是数据 table,U
是 table 和 附加的 数据。因此,在 TID
处完成连接的一对一关系。在我的数据库中,table U
的主键目前从未使用过。
问:考虑性能,把tableU
换成V
会不会更好(有效去掉多余的主键) ?如果我为这些 table 添加一个覆盖索引会有什么不同吗?
CREATE TABLE T (
TID int IDENTITY(1,1) NOT NULL
CONSTRAINT PK_T PRIMARY KEY CLUSTERED (TID ASC)
)
GO
CREATE TABLE U (
UID int IDENTITY(1,1) NOT NULL,
TID int NOT NULL CONSTRAINT FK_U_TID FOREIGN KEY REFERENCES T(TID)
CONSTRAINT PK_U PRIMARY KEY CLUSTERED (UID ASC)
)
GO
CREATE UNIQUE NONCLUSTERED INDEX U_TID_Index ON U (TID ASC)
GO
CREATE TABLE V (
TID int NOT NULL CONSTRAINT FK_V_TID FOREIGN KEY REFERENCES T(TID)
CONSTRAINT PK_V PRIMARY KEY CLUSTERED (TID ASC)
)
GO
这样试试,
CREATE TABLE T
(
TID INT IDENTITY(1, 1) NOT NULL
CONSTRAINT PK_T PRIMARY KEY CLUSTERED (TID ASC)
)
GO
CREATE TABLE V
(
TID INT NOT NULL CONSTRAINT FK_V_TID FOREIGN KEY REFERENCES T(TID)
CONSTRAINT PK_V PRIMARY KEY CLUSTERED (TID ASC)
)
GO
您的第二个 table 根本不需要。您可以使用两个 tables table-1 和 table-3.
这种方法比向 table-2 添加非聚集索引或覆盖索引提供更好的性能。
如果关联确实是 1:1,那么拥有一个额外的主键是没有意义的 - 它所做的只是迫使您创建另一个索引,而且它甚至没有聚集。通过添加单独的主键,您有效地将 table 的大小增加了一倍(据推测,TID
索引将覆盖整个 table)。
添加另一个 key/id 只有在关系不是 1:1 时才有意义 - 最明显的例子当然是 1:n 关系。但是,即使在那种情况下,您通常也会在一对 ID 上创建主键和聚簇索引 - TID
和 "uniquizer".
当您需要使用独立于父级的 "child" 时,完全独立的 ID 是一个不错的选择 - 如果您通常通过其父级查询它,那么拥有一个单独的 ID 就没有什么意义了。
考虑下面的 tables T
和 U
。 T
是数据 table,U
是 table 和 附加的 数据。因此,在 TID
处完成连接的一对一关系。在我的数据库中,table U
的主键目前从未使用过。
问:考虑性能,把tableU
换成V
会不会更好(有效去掉多余的主键) ?如果我为这些 table 添加一个覆盖索引会有什么不同吗?
CREATE TABLE T (
TID int IDENTITY(1,1) NOT NULL
CONSTRAINT PK_T PRIMARY KEY CLUSTERED (TID ASC)
)
GO
CREATE TABLE U (
UID int IDENTITY(1,1) NOT NULL,
TID int NOT NULL CONSTRAINT FK_U_TID FOREIGN KEY REFERENCES T(TID)
CONSTRAINT PK_U PRIMARY KEY CLUSTERED (UID ASC)
)
GO
CREATE UNIQUE NONCLUSTERED INDEX U_TID_Index ON U (TID ASC)
GO
CREATE TABLE V (
TID int NOT NULL CONSTRAINT FK_V_TID FOREIGN KEY REFERENCES T(TID)
CONSTRAINT PK_V PRIMARY KEY CLUSTERED (TID ASC)
)
GO
这样试试,
CREATE TABLE T
(
TID INT IDENTITY(1, 1) NOT NULL
CONSTRAINT PK_T PRIMARY KEY CLUSTERED (TID ASC)
)
GO
CREATE TABLE V
(
TID INT NOT NULL CONSTRAINT FK_V_TID FOREIGN KEY REFERENCES T(TID)
CONSTRAINT PK_V PRIMARY KEY CLUSTERED (TID ASC)
)
GO
您的第二个 table 根本不需要。您可以使用两个 tables table-1 和 table-3.
这种方法比向 table-2 添加非聚集索引或覆盖索引提供更好的性能。
如果关联确实是 1:1,那么拥有一个额外的主键是没有意义的 - 它所做的只是迫使您创建另一个索引,而且它甚至没有聚集。通过添加单独的主键,您有效地将 table 的大小增加了一倍(据推测,TID
索引将覆盖整个 table)。
添加另一个 key/id 只有在关系不是 1:1 时才有意义 - 最明显的例子当然是 1:n 关系。但是,即使在那种情况下,您通常也会在一对 ID 上创建主键和聚簇索引 - TID
和 "uniquizer".
当您需要使用独立于父级的 "child" 时,完全独立的 ID 是一个不错的选择 - 如果您通常通过其父级查询它,那么拥有一个单独的 ID 就没有什么意义了。