首先,我知道这是一个相当主观的问题,但我需要一些正式的文档来帮助我教育我的客户。
后台 - 一个包含数百个表和SP的大型企业应用程序,所有这些都使用标识列整齐地设计了规范化表和外键。
我们的客户有一些员工使用我们的生产Db的复制副本在Crystal企业中编写复杂的报告。
我们有表格存储我将其归类为“系统”基本信息,例如办公地点列表,公司内部部门,用户的标准角色集,其他对象的状态(打开/关闭等),基本上是数据这不会经常改变。
问题 - 报表设计人员和财务分析师正在编写带有硬编码标识值的查询。 像这样的东西
SELECT xxx FROM OFFICE WHERE OFFICE_ID = 6
我在这里大大简化了,但基本上他们在他们的程序中使用这些硬编码的int值。
对于SQL开发人员而言,这显然会让你成为facepalm,因为它只是一种内在的本能,不会这样做。
然而,令人惊讶的是,我找不到任何文档甚至最佳实践文章, 为什么不应该这样做。
他们认为这样做很好,因为价值永远不会改变,而且他们是正确的,在这个单一系统中这些价值观不会改变,但是在多个环境(登台/ QA / Dev)中,这些价值观可以绝对不同,使他们的报告设计方法不可移植,只能在一个独立的服务器环境中运行。
任何SQL大师都有更深入的信息/文章等我可以用来帮助教育我的客户为什么他们应该避免这种方法?
在我看来,你的报告撰写人最强烈的论据是你的第二句也是最后一句“......这些价值观可以并且绝对不同[在环境之间]”。 这几乎是我对他们的回应的要点。
当然,任何问题都有灰色区域。 标识列本质上是幻数 。 他们对数据库有益...
...但是具有完全没有意义的缺点,并且实际上是随机分配的(以一种方式将插入排序到该表中,每行获得的不同于以另一种方式排序的身份)。 因此,在你必须查找类似特定内容的情况下,它的常见用途还包括“业务/自然/备用”键(例如,可能(一个完全组成的例子) [CategoryName]
,其中CatgoryName是短的,独特的和人类可读,而。 [CategoryId]
是一个身份,但不是要寻求的东西)
如果你有一个带有下拉菜单的网站,通常将自然键放入下拉列表的可见部分,并且代理/身份密钥在后端传递,对最终用户不可见。
当人们直接针对数据库编写查询时,这会变得有点棘手。 如果他们是数据的所有者,他们可能知道更大的数据结构,他们可以利用咳嗽“聪明”的方式。 如果您知道密钥不会改变,并且您知道这些值是什么,那么可能只会引用这些值。 但是,再次,当你查询不同的服务器时,它们会不同。
当然另一方面,如果你不希望他们使用身份值,你必须给他们一个替代方案。 如果您的表格尚未包含业务/自然/备用密钥,那么您将不得不在尚不存在的地方添加一个。
此外,备用密钥也是一个整数也没有错(也许你的办公室已经拥有公司范围的1,2,3等标识符),但重点是无论你在哪里运行查询,它都是确定性的。