代码之家  ›  专栏  ›  技术社区  ›  Eli Courtwright

最好有成百上千的列或拆分成多个表?

  •  8
  • Eli Courtwright  · 技术社区  · 16 年前

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

    使用多个表会使系统总体上更加复杂,尽管从概念上讲,处理几个小的表比处理一个大的表更容易。

    拆分会有什么性能上的好处吗?似乎查询包含几十列的表可能比查询包含数百列的表要快。

    有没有人对这类事情有经验?我正在为这个项目使用Oracle,尽管这是我将来可能会遇到的数据库不足的问题,所以任何数据库的答案都会受到赞赏。

    6 回复  |  直到 11 年前
        1
  •  10
  •   Tony Andrews    11 年前

    我想我们需要更多地了解你的设计才能正确回答。例如,我很好奇可能会有很多与故障相关的列,很多(不同的列)与堵塞相关的列等等(堵塞不是仅仅是一种故障吗?)

    你的设计标准化了吗?大概你没有“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 
       );
    

    正如下面有人评论的,这些允许您更容易地求和统计信息-在统计类型内或跨统计类型。如果需要将一个新的stat添加到stat类型中,它也很容易扩展。

        2
  •  4
  •   SmacL    16 年前

    当我在一个表中看到数百列时,我倾向于怀疑数据模式没有被正确规范化。数百列真的是唯一的吗,或者它们是由类似的东西组成的组,可以正常化为更小的表吗?

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

        3
  •  1
  •   duffymo    16 年前

    规范化确保您不会在模式中重复数据。

    当然,你应该走多远是有限制的。不执行7个或更多表的联接。

    但是一张怪兽桌?我会把它拆了。

        4
  •  1
  •   ChrisW    16 年前

    你是说100种统计数据吗?

    一些医学数据库尝试了一种称为“实体属性值”或“EAV”的模式或习语(你可以用谷歌搜索这些术语):其理由是,对于一个病人,有无数种不同类型的事实,这些事实可能已经为任何一个给定的病人捕捉到,也可能没有捕捉到,而且EAV是一种更好的方法来存储这些事实,而不是用无数的数据。表中的不同列。

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

        5
  •  1
  •   Paul Lefebvre    16 年前

    我不喜欢列太多的表。您可能会考虑的一个选项是将统计信息存储为统计表中的行:

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

    然后,您只需为跟踪的每个状态添加一个新行。从数据库的角度来看,这要干净得多,但这确实会使获取报告的数据变得更加困难。

        6
  •  0
  •   Jeremy    16 年前

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

    machine
    id
    name
    description
    
    status_flag
    id
    caption
    
    machine_history
    machine_id
    status_flag_id
    information
    

    然后你可以做如下的事情: 从机器历史记录中选择count(distinct machine_id),其中status_flag_id=23和information<5;

    唯一的事情是机器历史表中的信息字段可能需要包含数字或字符。如果是这样,我将创建两个信息字段,这样您就不会妨碍性能。

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