如果我有一个表所列:

  • 艺术家
  • 专辑
  • 首歌
  • NumberOfListens

...是它更好地把集群的主要关键在艺术家、唱及歌曲或有一个自增id列和把一个独特的约束,在艺术家、唱和歌曲。

是多么的重要数据库的一致性?如果我一半的表聚集主键和其他半个id列具有独特的限制,这是坏或它没事?这两种方法似乎同我,但我不知道什么样的行业标准或是更好的和为什么。

有帮助吗?

解决方案

你真的需要保持两个问题:

1) 主钥匙 是个逻辑构造的一个候选键的唯一和可靠地识别的每一行,在你的表。这可以是任何东西,真的-一个INT,GUID,一串-拿什么最有意义对你的方案。你参照的主要钥匙在你的外国主要制约因素,所以这些都是至关重要的完整性数据库。使用他们总是期。

2) 聚集键 (将列于定义的"集群的指标"的表格)--这是一个 物理 存储相关的事情,在这里,一个小,唯一的、稳定的、不断增加的数据类型是你最好的选择-INT或BIGINT为默认选择。

默认情况下,主要的关键在SQL服务器上表也作为集群的关键,但这并不需要这样的话,你可以轻松地挑选列不是您的主要关键是你的聚集键。

然后还有另外一个问题要考虑:聚集键在表将加入到每一个条目的每一个非集群上的索引表,以及-因此你真的想要确保它尽可能地小。通常,一个INT有2亿排应足以满足绝大多数的表格相比较VARCHAR(20)或以聚集键,可以节省自己数百兆字节的存储磁盘上以及在服务器的存储器。

一些更多的思考的食粮-优秀的东西通过金伯利Tripp-读读它再次摘要它!这就SQL服务器引福音,真的。

Marc

其他提示

我绝不会把一个主要关键上列长的文本,如:艺术家、唱和歌曲。使用自动增加ID聚集PK。如果你想的艺术家、唱及歌曲是独特的、广告一个独特的索引。如果你想搜索册或歌曲的、独立的独立的艺术家,你会需要一个指数的每个,拉在PK,因此具有一个小PK节省了你上每一个其他指数。储蓄不仅仅是盘空间,但在高速缓冲存储器,并且更键在一个页面上。

聚集索引伟大的范围内根据查询。例如,一个日志中的日期或订单的日期。把一个艺术家、唱及歌曲将[可能]造成碎片的时候你插入新行。

如果数据库支持,增加一个非集群的主要关键在艺术家、唱和歌曲,并呼它好。或者只是添加一个独特的关键在艺术家、唱和歌曲。

具有自增的主要关键,只会真正有用的,如果你得到了引用完整性的另一表中。

不知道确切的要求,在一般的你可能会有一个艺术家的表,并可能册表。一首歌表将是一个独特的组合的艺术家id,册id然后曲。我会执行的唯一通过一个指数或约束取决于应用程序,并使用一个id为一个主要关键。

首先,已经有了一个问题,因为数据是不正常化。创建 任何 种指数的上一堆文字列是什么,应该尽可能避免。甚至如果这些列不是案文(和我怀疑他们正),它仍然没有意义的艺术家、唱片 歌曲同样表。一个 很多 更好地设计这将是:

Artists (
    ArtistID int NOT NULL IDENTITY(1, 1) PRIMARY KEY CLUSTERED,
    ArtistName varchar(100) NOT NULL)

Albums (
    AlbumID int NOT NULL IDENTITY(1, 1) PRIMARY KEY CLUSTERED,
    ArtistID int NOT NULL,
    AlbumName varchar(100) NOT NULL,
    CONSTRAINT FK_Albums_Artists FOREIGN KEY (ArtistID)
        REFERENCES Artists (ArtistID))

Songs (
    SongID int NOT NULL IDENTITY(1, 1) PRIMARY KEY CLUSTERED,
    AlbumID int NOT NULL,
    SongName varchar(100) NOT NULL,
    NumberOfListens int NOT NULL DEFAULT 0
    CONSTRAINT FK_Songs_Albums FOREIGN KEY (AlbumID)
        REFERENCES Albums (AlbumID))

一旦你有这样的设计,你有能力搜索的个人专辑和艺术家以及歌曲。你还可以添加的复盖指数速查询和索引将 小得多 因此速度比原来的设计。

如果你不需要做的范围内查询(其中你可能不会),然后你可以替代的 IDENTITY 关键用 ROWGUID 如果适合你的设计更好;它并不真正的问题在这种情况下,我要坚持简单 IDENTITY.

你必须小心,与聚类键。如果你集群上的一个关键,是完全不甚至远程序(和一个艺术家、唱片和首歌的名字肯定有资格作为非顺序),那么最终你页拆分和其他污秽。你不想要这个。并作为Marc说的副本这一关键添加到每一个指数,和你 肯定 不想要这个的时候你关键是300 600字节长。

如果你想要能够快速查询的号码的侦听一个具体的歌曲通过艺术家、唱和歌曲的名称,它实际上是相当简单与上述设计,你只需要指数:

CREATE UNIQUE INDEX IX_Artists_Name ON Artists (ArtistName)
CREATE UNIQUE INDEX IX_Albums_Artist_Name ON Albums (ArtistID, AlbumName)
CREATE UNIQUE INDEX IX_Songs_Album_Name ON Songs (AlbumID, SongName)
    INCLUDE (NumberOfListens)

现在这种查询将加快:

SELECT ArtistName, AlbumName, SongName, NumberOfListens
FROM Artists ar
INNER JOIN Albums al
    ON al.ArtistID = ar.ArtistID
INNER JOIN Songs s
    ON s.AlbumID = al.AlbumID
WHERE ar.ArtistName = @ArtistName
AND al.AlbumName = @AlbumName
AND s.SongName = @SongName

如果你检查了执行计划你会看到3个指数寻求-就这么快,你能得到它。我们保证完全相同的独特性,因为在最初的设计 优化的速度。更重要的是,它的规范化,所以一个艺术家和一张专辑有自己的特定身份,这使得这一伟大的处理更加容易管理的长期。它更容易搜索的"所有唱片的艺术家X。"这是多少 很多 更加容易和更加快速搜索的"上的所有歌曲的专辑Y"

当设计一个数据库,正常化应该是你的第一个关注的问题,索引,应该是你的第二个。和你很可能会发现,一旦你有标准化设计,更好索引编制战略成为一种显而易见的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top