Sql 常数包最佳实践与高度规范化的数据库

Sql 常数包最佳实践与高度规范化的数据库,sql,oracle,constants,Sql,Oracle,Constants,我有一个非常标准化的Oracle数据库。它有许多大的表,以及20个或更多的非常小的表(小于10条记录) 例如,有一个状态表。要了解其中的数据,它看起来如下所示: ID Status 1 Cancelled 2 In Progress 3 Completed 目前,在整个代码中都有可怕的幻数引用,如下所示: SELECT * FROM [somewhere] WHERE [something] = ( SELECT Status

我有一个非常标准化的Oracle数据库。它有许多大的表,以及20个或更多的非常小的表(小于10条记录)

例如,有一个状态表。要了解其中的数据,它看起来如下所示:

ID    Status
1     Cancelled
2     In Progress
3     Completed
目前,在整个代码中都有可怕的幻数引用,如下所示:

SELECT *
FROM   [somewhere]
WHERE  [something] = (
         SELECT Status
         FROM   [StatusTable]
         WHERE  Id = 2
       )
我讨厌这些随机数,更喜欢用常数来代替它们

我最初的想法是一个常量包。在这里,我可以有一个全局变量2,它返回正确的状态。它位于一个位置,所以问题得以解决——当然,它会使表变得过时,并且无法从表中获取信息

我的最佳实践解决方案是什么?我确实喜欢常数。我认为他们的代码更清晰,即:

SELECT Status
FROM   [StatusTable]
WHERE  Id = CONSTANTS.Status_In_Progress

但是,我担心表数据没有附件。

从我多年设计PL/SQL应用程序的经验来看,没有比您建议的更好的方法(主要是在代码可读性和维护方面),也就是说,将这些常量存储在单独的包规范中,并在查询和/或其他处理中引用它们

我认为它是数据的“接口”,而不是表数据


但是,让我再强调一点:从现在开始,您可以在新代码或因变更请求而重写的代码中开始,然而,仅仅因为“我不喜欢它看起来的样子”就重写现有的、经过测试的、在生产中运行的代码是极其薄弱的原因,在应用程序功能方面没有附加值,但存在导入错误的非零风险…,我宁愿再喝一杯咖啡或回答新的SO问题,而不是这样的工作。

如果你想改变什么,更改为联接到包含单词值而不仅仅是int的表。否则,您会遇到将常量dat与实际值保持同步的问题,因为这些常量可能会不时更改。可能会添加更多,文本值可能会更改。因此,您已经在一个规范化数据库中加入了一些东西来获取这些值。使用它。至少这样你就不会有保持常量同步的额外问题了

然而,即使是这样,也可能发生变化。与使用幻数作为查找值相比,可能会导致更多问题

假设您在一个表中有一个状态列表,状态ID 2的状态为“InProgress”,稍后有人将其修改为“InProgress”,您是否希望更改代码,因为文本已更新?假设你有一个客户ID?公司名称经常变化。事实上,在使用查找的这些年里,我在尝试使用逐字逐句而不是神奇数字时遇到了更多的问题

现在,我承认处理幻数并不有趣,但要小心更改它们和引入新的bug,特别是如果查找的文本值可能会发生更改(例如“Sears,Inc.”可能变成“Sears and Roebuck,Inc.”的客户名称)。不太可能更改的查找(如状态名称)可以通过其详细信息进行引用,但这将需要向查找表中添加当前查询中没有的联接。更多联接可以开始为查询增加一点处理时间。这可能会更改数据库用于查找数据和数据的计划然后突然使查询速度出乎意料地变慢。添加您需要的连接是一件好事,添加一个您可能不会的连接可能是更快的查询和陷入困境的查询之间的断点(当然,在大多数情况下,它也可能不会添加任何可测量的连接)。任何时候更改代码,都可能导致新的错误或性能变化


现在你还必须考虑为这个系统编写代码的其他开发者。如果每个人都知道Stistud 10是“完整的”,他们可能继续使用这类代码,而你正在打一场失败的战斗。您的偏好。

您的间接性水平将“降至最低”“在什么地方。如果您不想使用magic number
2
,您需要接受使用magic string
“进行中”
,因为没有其他方法来识别该行。@dasblinkenlight:我可以看到,我认为这是一个非常公平的建议。有什么我可以帮忙的吗?这些神奇的数字/字符串中的一些在代码中的数百个地方都被使用。严重规范化到哪种形式?在这种情况下,你是如何进行大量量化的?@LalitKumarB:这对我来说太主观了,你是对的——我无法量化。我的意思是,有很多小表都有这样的标志,用于将其他表连接在一起。我想以某种方式对它们进行常量化,但不知道如何在不破坏与表的关系的情况下做到这一点,使我的常量不受这些我难以实现的小表的更新的影响。PL/SQL可以访问SQL。但是您不能从SQL访问PL/SQL包变量。“唯一”选项(尽管不实用)是系统上下文变量。