sql - 使用 SQL Server FILESTREAM GUID 作为主键

标签 sql sql-server

我正在创建一个名为 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 就是这样) .

在此处查看她有关索引的文章:

另请参阅 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/

相关文章:

mysql - 带计数的交叉连接 MySQL 查询

sql - Sequelize 不使用模型中的字段别名

Python MySQL 连接器无法从 SELECT 查询返回所有结果

从字符串到日期时间的 SQL Server 日期比较

sql - 在 SQL Server 2008 中使用列别名指定数据类型

sql - 比较变量中的日期,检查它们是否按升序排列

sql - ISNUMERIC ('07213E71' ) = 真?

sql-server - dbGo 或 dbExpress for Delphi 2010 与 Microsoft SQL Server

sql-server - VS2013 数据库项目 - 忽略匹配过滤器的模式/表?

sql-server - 卸载过期评估版后安装 SQL Server 2012 Developer