我正在与程序员一起开发数据库解决方案。他们希望添加一个计算列来模拟旧查询、过程和系统的旧键并对其进行索引。新键将是 GUIDS。
为此,他们希望为计算列创建一个函数,该函数创建一个值并将其持久化。它不会让他们保留该列。我对这个想法没有任何热情的模糊,我也无法在网上找到任何关于该技术的信息(它是一种技术吗?)。
我认为他们需要添加一个触发器。有没有人有任何想法?
该函数将按以下方式运行:
(SELECT [INT Identity field] FROM TABLE WHERE [GUID COLUMN] = @GUIDKEY
它根据 GUID 返回一个 INT 身份字段。
这将在插入相关表时运行。因此,如果表一持有主键,则相关表二将更新(使用传入的 GUID)以从表一中获取键并将其插入表二。
仍然不明白为什么这需要成为表中的一列,更不用说持久化的列了。
为什么不创建一个表值函数,当(且仅当)查询真正需要它时交叉应用?由于旧密钥永远不会改变,因此无论如何都不需要计算或持久化它。
如果您真的希望旧密钥存在于多个地方(听起来不应该做出这种决定的人已经做出了这种决定),只需在触发器中进行查找并在写入时填充它. 那么它只是表中的一个静态列。
我仍然强烈推荐一个表值函数来促进这一点,这样您就可以编写触发器以处理多行操作......而无需编写循环或调用标量值函数每一行都重来一遍。
只是为了展示这些东西实际上有多相似(并质疑“不喜欢它”的首席开发人员):
现在,如果您有一个表值函数,代码非常相似,但是您会发现多行操作的性能要好得多,而单行操作的性能几乎相同。
我不确定您为什么认为需要一个函数或计算列来执行此操作。您可以使用默认值向表中添加一个新列,并根据需要对其进行索引。
既然你更新了你的问题,让我们来谈谈这是一个多么糟糕的想法。我将稍微简化一下这个例子。
如果他们执行数据访问,尝试基于标量函数(即使是具有SCHEMABINDING的确定性函数)持久化计算列将失败。
你也不能索引它:
您还会遇到很多问题,因为该函数将逐行运行以检索数据,并将强制针对表的所有查询以串行方式运行。
如果您正在修改函数引用的表中的数据,并从调用计算列中的函数的表中选择数据,您最终可能会遇到一些非常令人困惑的阻塞场景,其中函数被阻止将数据返回到查询在看似无关的桌子上。
这是一个坏主意。亚伦在他的评论中给出了我认为最好的建议:
您可以阅读BOL 中的 Persisted Computed Columns以及 Computed Columns 上的相关索引。
可以在持久计算列中使用的表达式有一些限制。表达式“必须在指定 PERSISTED 时具有确定性”。
如果我理解正确,您有:
t
。t
有一个 guid 列,我们称之为gc
。t.gc
到不同类型的不同键值的查找,用于遗留代码。让我们调用 tablelt
和 legacy key columnlk
。lt.lk
以这样的方式出现,t
以便t.lk
可以继续使用它的遗留代码。我会使用视图进行调查。
t
,类似t_base
.t
连接并t_base
返回和lt
的列。t_base
lt.lk
实际问题
开发人员试图解决的问题是一个相当标准的迁移问题,从一种数据类型到一种新数据类型。他们有一个在最初设计数据库时没有预料到的新问题;也就是说,他们现在需要跨数据库同步数据。这往往是一项代价高昂的工作,尤其是在大量代码中依赖数据类型的情况下。寻找成本节约措施并非完全不合理。
他们的解决方案
数学说不
首先,重要的是要认识到这个问题在数学上可能是难以解决的。GUID 或 UUID 只是一个 128 位或 16 字节的数字。列的大小
IDENTITY
取决于使用的数据类型,但通常是INT
(32 位,4 字节);有时BIGINT
使用(64 位,8 字节)。没有数学方法可以将 GUID 的范围完全映射到 INT 甚至 BIGINT 的范围。如果该列DECIMAL(38,0)
足够大,则在数学上是可能的,但这种情况非常罕见。实用性
即使可以将 GUID 映射到
DECIMAL
类型,但这并不意味着它是实用的。几乎没有人这样做,因此您将不得不花费时间(=金钱)确保映射正常工作。他们的解决方案引入了一个不小的风险,即产生奇怪且难以诊断的错误。此外,您不会使用他们的解决方案保留数据的现有 ID。这很可能会破坏最终用户拥有的任何包含 ID 的书签。
最后,他们的解决方案很可能是根深蒂固的。由于上述所有原因,这不是一个好习惯,但如果他们得到了它,他们很可能不会很快摆脱它,因为在所有新的情况下继续使用整数键太“容易”了代码。
更标准的方法
将同步引入现有系统的一种相对标准的方法是添加一个新的唯一 ID。除了旧的现有键之外,此新 ID 还放置在数据中。然后代理键不同步。
这有一些主要好处:
这种方法有两个小烦恼:
不过,这两个问题都是可以管理的,如果现在将所有内容都切换到 GUID 成本太高,那么它们是合理的权衡取舍。
还值得注意的是,此解决方案完全启用了他们要求能够执行的查询。
现在可能为时已晚,无法为您提供帮助,但我认为这是很好的信息。