最好有数百列或拆分成多个表?

时间:2009-01-09 14:34:08

标签: database-design

我正在设计一个关于机械设备运行的统计数据库。每批数据将包含数百个统计信息,因此我尝试决定是创建包含数百列的单个表还是将其拆分为多个表,每个表包含相关的统计信息。例如,我可以有一个表格包含与故障相关的统计数据,另一个表格包含与果酱相关的统计数据等。

使用多个表会使整个系统变得更加复杂,但从概念上讲,我可能更容易处理几个较小的表而不是一个较大的表。

将事情分开会有任何性能上的好处吗?看起来查询一个包含几十列的表可能比查询一列有数百列的表更快。

有没有人有这种经历的经验?我正在使用Oracle进行这个项目,虽然这是我将来可能遇到的数据库,所以对任何数据库的答案都会很感激。

6 个答案:

答案 0 :(得分:10)

我认为我们需要更多地了解您的设计才能正确回答。例如,我很好奇可能会有很多与故障相关的栏目,许多(不同的)与果酱有关的等等(不管卡纸是不是一种故障?)

您的设计是否正常化了?大概你没有“jam1”,“jam2”等栏目?!

假设设计良好且规范化,关于是否有一个宽表或多个较宽表的决定是各种因素之间的权衡:

  • 所有/大多数记录都有所有类型的统计数据吗?是=>一张桌子,没有=>许多
  • 您是否经常需要一起查询所有类型的统计信息?是=>一张桌子,没有=>许多
  • 你是否在同一个屏幕上保存了所有不同的统计数据?是=>一张桌子,没有=>许多
  • 您是否可能达到任何数据库限制,例如每张表最多1000列?

无论您采用哪种方式,您都可以使用视图来展示替代结构,以方便开发人员:

  • 一个表:选择特定类型统计数据的许多视图
  • 许多表:将所有表连接在一起的视图

更新

根据您的评论,我现在知道您在机器上的40个不同位置有卡纸计数,而其他类型的统计数据是类似性质的计数。这表明了以下表格设计:

create table machines (machine_id ... primary key, ...);
create table machine_stats 
   ( machine_id references machines
   , stat_group -- 'jams', 'malfunctions' etc.
   , stat_name  -- 'under the hood', 'behind the door' etc.
   , stat_count 
   );

如下所述,这些可让您更轻松地对统计数据进行统计 - 在统计类型内或跨统计类型。如果需要将新统计数据添加到统计类型,也可以轻松扩展。

答案 1 :(得分:4)

当我在表中看到数百列时,我倾向于怀疑数据模式未正确规范化。数百列真的是独一无二的,还是可以归一化为较小表的类似事物的组合?

如果您可以减少列数,则可以减少交易的数据总量,从而提高多个级别的性能。例如,如果您有一个包含1000个字节数据的记录,并且您希望为每个记录更改1个字节,则存在获取和不必要地存储999个字节的风险。这确实会影响性能。

答案 2 :(得分:1)

规范化可确保您不重复架构中的数据。

当然,你应该走多远。 7个或更多表的JOINS不具备性能。

但是一张怪物桌?我会分手。

答案 3 :(得分:1)

您的意思是100种统计数据吗?

一些医学数据库尝试过一种称为“实体属性值”或“EAV”的模式或习语(你可以谷歌这些术语):推理是关于病人有无数种不同类型的事实,可能是可能没有为任何给定的患者捕获,并且EAV是一种更好的存储方式,而不是在表格中有无数不同的列。

然而,请注意EAV是有争议的:有人说它是“代码味道”和典型的新手错误;其他人说它偶尔(或很少)有用,但取决于(指定和拥有)对元数据的良好支持。

答案 4 :(得分:1)

我倾向于不喜欢列数太多的表格。您可以考虑的一个选项是将统计信息存储为统计信息表中的行:

CREATE TABLE Statistics (id AS INTEGER PRIMARY KEY, statusType As VarChar,
statusValue As Float);

然后,您只需为要跟踪的每个状态添加一个新行。从数据库的角度来看,这样做更加清晰,但它确实使报告的数据变得更加清晰。

答案 5 :(得分:0)

在这种情况下,我会创建几个表。一个是机器表。一个是问题查找表。最后,两者之间的联结表还包含与状态相关的信息。维护将更容易,编写疯狂的报告将更容易。此外,添加新类型的状态也会更容易。

machine
id
name
description

status_flag
id
caption

machine_history
machine_id
status_flag_id
information

然后你可以做以下事情: 从machine_history中选择count(distinct machine_id),其中status_flag_id = 23并且信息< 5;

唯一的事情是machine_history表中的信息字段可能需要包含数字或字符。如果是这种情况,我会创建两个信息字段,这样就不会影响性能。

此外,我假设有一个编程组件,可以让您创建一些方法来轻松处理这些数据。