sql-server – 总是有一个整数列作为主键的缺点是什么?

前端之家收集整理的这篇文章主要介绍了sql-server – 总是有一个整数列作为主键的缺点是什么?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在我正在处理的一个Web应用程序中,使用在Entity Framework ORM上定义的一些通用存储库抽象所有数据库操作.

但是,为了对通用存储库进行简单设计,所有涉及的表必须定义一个唯一的整数(C#中的Int32,sql中的int).到目前为止,这一直是桌子的PK和IDENTITY.

外键使用频繁,它们引用这些整数列.它们是一致性和ORM生成导航属性所必需的.

应用程序层通常执行以下操作:

>从表(*) – SELECT * FROM表加载初始数据
>更新 – UPDATE表SET Col1 = Val1 WHERE Id = IdVal
>删除 – DELETE FROM表WHERE Id = IdVal
>插入 – INSERT INTO表(cols)VALUES(…)

运营频率较低:

>批量插入 – BULK INSERT …进入表后跟(*)所有数据加载(以检索生成的标识符)
>批量删除 – 这是一个正常的删除操作,但从ORM的角度来看是“笨重的”:DELETE FROM表其中OtherThanIdCol = SomeValue
>批量更新 – 这是一个正常的更新操作,但从ORM的角度来看“庞大”:UPDATE表SET SomeCol = SomeVal WHERE OtherThanIdCol = OtherValue

*所有小表都在应用程序级别缓存,几乎所有SELECT都不会到达数据库.典型的模式是初始加载和许多INSERT,UPDATE和DELETE.

根据当前的应用程序使用情况,在任何表中达到100M记录的可能性非常小.

问题:从DBA的角度来看,有这个表设计限制我可能遇到的重大问题吗?

[编辑]

在阅读了答案(感谢很好的反馈)和参考文章后,我觉得我必须添加更多细节:

>当前的应用程序细节 – 我没有提到当前的Web应用程序,因为我想了解该模型是否可以重用于其他应用程序.但是,我的特殊情况是一个从DWH中提取大量元数据的应用程序.源数据非常混乱(以一种奇怪的方式非规范化,有一些不一致,在许多情况下没有自然标识符等),我的应用程序正在生成清晰的分离实体.此外,显示许多生成的标识符(IDENTITY),以便用户可以将它们用作业务键.除了大规模的代码重构之外,这还排除了GUID的使用.
>“他们不应该是唯一识别行的唯一方法”(Aaron Bertrand♦) – 这是一个非常好的建议.我的所有表都定义了一个UNIQUE CONSTRAINT,以确保不允许重复业务.
>前端应用驱动设计与数据库驱动设计 – 设计选择是由这些因素引起的

>实体框架限制 – 允许多列PK,但是their values cannot be updated
>自定义限制 – 具有单个整数键可以极大地简化数据结构和非sql代码.例如:所有值列表都有一个整数键和一个显示值.更重要的是,它保证标记为缓存的任何表都能够放入Unique int键 – >价值图.

>复杂的选择查询 – 这几乎不会发生,因为所有小的(<20-30K记录)表数据都在应用程序级别进行缓存.这使得编写应用程序代码时生活变得更加困难(更难编写LINQ),但数据库受到更好的打击:
>列表视图 – 在加载时不会生成SELECT查询(所有内容都被缓存)或查询如下所示:

SELECT allcolumns FROM BigTable WHERE filter1 IN (val1,val2) AND filter2 IN (val11,val12)

所有其他必需值都是通过缓存查找(O(1))获取的,因此不会生成复杂的查询.
>编辑视图 – 将生成如下所示的SELECT语句:

SELECT allcolumns FROM BigTable WHERE PKId = value1

(所有过滤器和值都是整数)

解决方法

除了额外的磁盘空间(以及内存使用和I / O)之外,添加IDENTITY列甚至对不需要它的表也没有任何损害(表不需要IDENTITY列的表)是一个简单的联结表,比如将用户映射到他/她的权限).

反对在2010年的博文中盲目地将它们添加到每个表中:

> Bad habits to kick : putting an IDENTITY column on every table

但代理键确实具有有效的用例 – 请注意不要假设它们保证唯一性(有时为什么它们会被添加 – 它们不应该是唯一标识行的唯一方法).如果您需要使用ORM框架,并且您的ORM框架需要单列整数键,即使在您的真实密钥不是整数,也不是单个列或两者都不是的情况下,请确保定义唯一约束/索引对于你真正的钥匙.

猜你在找的MsSQL相关文章