通用数据库设计:有意创建非规范化表是否“好”?

时间:2012-05-04 18:12:07

标签: database database-design lookup-tables normalize

编辑后:哇,这个问题很长。请原谅= \

我正在创建一个包含30多列的新表。这些列主要由下拉列表中的选项填充,其选项在很大程度上与逻辑相关。例如,标记为“审核周期”的下拉列表将包含“每月”,“每半”和“每年”等选项。我想出了一个可行的方法,通过创建一个存储每月,每半年和每年等值的基元查找表,将这些选项标准化为数字标​​识符。然后,我将这些基元的ID存储在记录表中,并使用视图将该表连接到我的查找表。有了这个视图,记录表可以包含只有应用程序理解的原始数据,同时允许外部应用程序和管理员对视图运行SQL并返回转换为友好信息的数据。

它变得复杂了。现在这些下拉列表将具有非逻辑相关的项目。例如,“审核期间”下拉列表现在需要具有“NA”和“手动”选项。这使我的整个分组计划脱离了水。

此应用程序中使用的类似构造已经使用了跨多个记录存储重复的字符串值。这意味着您可以在表的ReviewPeriod列中存储数百条记录,其中包含字符串“Monthly”。自从我开始在这里工作以来,这种情况的发生让我感到畏缩,但现在我开始认为非标准化数据可能是最好的选择。

我能想到的另一种方法是使用我的初始方法,同时允许它是动态的,并支持随时向任何下拉列表添加新选项,这是:将数据保存到数据库时,迭代通过我的业务对象的每个属性(在本例中为.NET类)并检查基元表中存在的任何字符串值。如果没有,请添加它并返回自动生成的唯一标识符以存储在记录表中。它似乎很复杂,但这是为了规范化数据而经历的事情吗?

2 个答案:

答案 0 :(得分:2)

一切皆有可能。没有人会把你拖到非规范化监狱并撤销你的DBA卡。我会说你应该知道规则以及破坏它们意味着什么。一旦掌握了这些内容,就可以按照自己的最佳判断来做你认为最好的事情。

答案 1 :(得分:2)

  

我提出了一种可行的方法来将这些选项标准化为   数字标识符,通过创建存储的基元查找表   每月,半年和每年的价值。然后我存储了   记录表中这些原语的ID,并使用视图进行连接   那张表到我的查询表。

用ID号替换文本与标准化没有任何关系。您正在描述自然键上的代理键选择。有时代理键是一个不错的选择,有时代理键是一个糟糕的选择。 (通常情况下,这是一个糟糕的选择。)

  

这意味着你可以拥有数百条带字符串的记录   'Monthly'存储在表格的ReviewPeriod列中。思想   自从我开始在这里工作以来,这种情况让我感到畏缩,但是   现在我开始认为非标准化数据可能是最好的   选项在这里。

将字符串“Monthly”存储在多行中与规范化无关。 (或者使用非规范化。)这似乎与标准化意味着“用id号替换所有文本”这一概念有关。在数据库中存储文本不应该让你感到畏缩。 VARCHAR(n)是有原因的。

  

我能想到的另一种方法是使用我的初始方法   同时允许它是动态的,并支持不断添加新的   任何时候任何下拉列表的选项是:保存数据时   到数据库,遍历我的业务的每个属性   object(在本例中为.NET类)并检查任何字符串值   存在于基元表中。如果没有,添加它并返回   自动生成的唯一标识符,用于存储在记录表中。

让我们非正式地思考这一点。

外键提供参照完整性。它们的目的是限制列中允许的值。非正式地,引用的表提供了一组有效值。在其他表的引用列中不允许不在该表中的值。

但无论用户输入什么内容,您都会将其添加到有效值表中。

如果您要接受用户首先输入的所有内容,为什么要使用外键呢?

这里的主要问题是你教导你(误解了你)关系模型的人很难得到你的服务。 (而且,教你SQL的人也可能同样糟糕。)我希望你能迅速忘掉那些错误的观念,并很快取得真正的进展。