我正在创建一个名为Photo
的简单表来存储User
表中定义的人/组的照片。我正在使用Microsoft SQL Server的FILESTREAM
功能,因为所有其他用户数据已经存储在SQL Server中,对我来说比编写一种单独的方法从磁盘直接手动检索对象更有意义与数据库中的条目相关。
每个用户一次只能有一张与他们相关联的照片(目前,但未来可能会发生变化),FILESTREAM
需要GUID
列来引用其存储的文件磁盘,所以这是我为Photo
提出的模型:
UserID int NOT NULL UNIQUE
PhotoID uniqueidentifier ROWGUIDCOL NOT NULL
PhotoBitmap varbinary(MAX) FILESTREAM NULL
我的问题是(如果这个模型对我的应用程序是正确的),我应该使用PhotoID
作为主键,看看它是如何已经是唯一的并且是必需的?在我看来,它比为主键创建单独的INT
列更简单,但我不知道它是否“正确”。
答案 0 :(得分:3)
我个人使用INT IDENTITY
来处理我的主要和群集密钥。
您需要将主键分开,这是一个逻辑结构 - 它唯一标识您的行,它必须是唯一且稳定的NOT NULL
。 GUID
也适用于主键 - 因为它保证是唯一的。如果使用SQL Server复制,则GUID
作为主键是一个不错的选择,因为在这种情况下,无论如何都需要唯一标识GUID
列。
SQL Server中的集群密钥是一个物理结构,用于数据的物理排序,并且更难以正确使用。通常,SQL Server上的索引女王,Kimberly Tripp,也需要一个好的聚类密钥,以便尽可能地独特,稳定,并且理想地不断增加(INT IDENTITY
GUID
是)。
请参阅她关于索引的文章:
还可以看到Jimmy Nilsson的The Cost of GUIDs as Primary Key
对于群集密钥,GUID
是非常糟糕的选择,因为它很宽,完全随机,因此导致错误的索引碎片和性能不佳。此外,群集密钥行也存储在每个非群集(附加)索引的每个条目中,因此您确实希望保持较小 - INT
是16字节而不是{{ 1}}是4字节,并且有几个非聚集索引和几百万行,这会产生巨大差异。
在SQL Server中,您的主键默认情况下是您的群集密钥 - 但它不一定是。您可以轻松地使用GUID
作为非群集主键,使用INT IDENTITY
作为群集密钥 - 只需要了解一点。