我正在创建一个名为 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 列更简单,但我不知道它是否“正确”。
最佳答案
我个人使用INT IDENTITY
对于我的大部分主键和集群键。
您需要将主键分开,它是一个逻辑结构 - 它唯一标识您的行,它必须是唯一且稳定的,并且 NOT NULL
。一个GUID
对于主键也很有效 - 因为它保证是唯一的。一个GUID
因为如果您使用 SQL Server 复制,您的主键是一个不错的选择,因为在这种情况下,您需要一个唯一标识 GUID
无论如何,列。
SQL Server 中的聚集键是一种物理构造,用于数据的物理排序,并且更难以正确获得。通常,SQL Server 上的索引女王 Kimberly Tripp 还需要一个良好的集群键,该键必须是唯一的、稳定的、尽可能窄的,并且理想情况下是不断增加的(INT IDENTITY
就是这样) .
在此处查看她有关索引的文章:
- GUIDs as PRIMARY KEYs and/or the clustering key
- The Clustered Index Debate Continues...
- Ever-increasing clustering key - the Clustered Index Debate..........again!
- Disk space is cheap - that's not the point!
另请参阅 Jimmy Nilsson 的 The Cost of GUIDs as Primary Key
一个GUID
对于集群键来说,这是一个非常糟糕的选择,因为它很宽,完全随机,从而导致糟糕的索引碎片和糟糕的性能。此外,聚集键行也存储在每个非聚集(附加)索引的每个条目中,因此您确实希望保持较小的值 - GUID
是 16 字节 vs INT
是 4 字节,并且具有多个非聚集索引和数百万行,这会产生巨大的差异。
在 SQL Server 中,默认情况下您的主键是集群键 - 但并非必须如此。您可以轻松使用GUID
作为您的非聚集主键,以及 INT IDENTITY
作为您的聚类键 - 只需要稍微注意一下即可。
关于sql - 使用 SQL Server FILESTREAM GUID 作为主键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19730742/