背景:-
目前,我在 Oracle 数据库中有一个非常宽的事实表,有近 800 列和近 1 亿行,用于存储事件,每个事件都有多个属性。每个属性对应于数据库中的一列。事件和属性的加入来自产品端,并且步骤是自动化的,因此在开发端我们无法对其进行任何控制。
在产品团队方面,我们为每个事件(预先计算)创建了物化视图,以便更快地检索。因此,从一个巨大的事实表中,我们为每个事件创建了多个较小的 MV。
问题:-
Oracle数据库的容量只有1000列。随着产品团队加入新的事件和属性,列的 1000 个限制将被突破。我想了解我应该如何扩展它。
几种方法:-
方法 1:添加另一个事实表,为接下来的 1000 个属性提供支持。但问题是,当违反列限制时,我需要继续添加多个事实表。另外,我需要跟踪哪个事实表中存在哪个属性或事件。另外,我怀疑在某些情况下需要连接多个事实表的属性进行某些计算。
方法2:使用实体关系模型将相似的属性分组到一个单独的表中并使用外键关系。这种方式有一个单一的事实表与多个属性组的外键关系。基于属性的聚合将会很复杂,因为属性现在是一层深,现在我将拥有多个包含数百万行的窄表,而不仅仅是单个宽表。
方法3:重新设计表,将Events存储为事实表。但是公共属性将成为每个事件的一部分,并且会有冗余存储。我看到的另一个问题是将多个事件关联在一起会很复杂。
请帮助/建议解决问题的更好方法。
如果您有一张看起来像这样的桌子:
CREATE TABLE events (
-- Common to all events
id NUMBER PRIMARY KEY,
start_date DATE,
end_date DATE,
-- Task Related columns
task_owner VARCHAR2(50),
task_expected_duration NUMBER(6,2),
-- Meeting Related columns
meeting_organiser VARCHAR2(50),
meeting_required VARCHAR2(4000),
meeting_optional VARCHAR2(4000),
meeting_location VARCHAR2(200)
)
当您插入任务时,您会将数据插入到公共列和任务列中,但会议列将是
NULL
。同样,对于事件,公共列和会议列中会有值,但任务列将为 NULL
。
那么你不应该只有一张表,它应该是(至少)3张通过关系约束相关联的表:
CREATE TABLE events (
id NUMBER PRIMARY KEY,
start_date DATE,
end_date DATE
);
CREATE TABLE task_events (
id PRIMARY KEY REFERENCES events(id),
owner VARCHAR2(50),
expected_duration NUMBER(6,2),
);
CREATE TABLE meeting_events (
id PRIMARY KEY REFERENCES events(id),
organiser VARCHAR2(50),
required VARCHAR2(4000),
optional VARCHAR2(4000),
location VARCHAR2(200)
);
如果您想查看与任务相关的列,您可以使用:
SELECT e.*, t.owner, t.expected_duration
FROM events e INNER JOIN task_events t ON .id = t.id;
如果您想参加会议:
SELECT e.*, m.organiser, m.required, m.optional, m.location
FROM events e INNER JOIN meeting_events m ON .id = m.id;