设计SQL数据库以表示OO类层次结构

我正在将类层次结构转换为存储在sql数据库中.

原伪码:

abstract class Note
{
   int id;
   string message;
};

class TimeNote : public Note
{
   time_t time;
};

class TimeRangeNote : public Note
{
   time_t begin;
   time_t end;
};

class EventNote : public Note
{
   int event_id;
};

// More classes deriving from Note excluded.

目前我有几个想法如何存储在一个数据库.

A.将所有音符存储在单个宽表中

该表将包含从注释导出的所有类所需的所有信息.

CREATE TABLE t_note(
   id INTEGER PRIMARY KEY,message TEXT,time DATETIME,begin DATETIME,end DATETIME,event_id INTEGER
);

从Note导出的未来类需要在此表中添加新列.

将每个类映射到一个

CREATE TABLE t_note(
   id INTEGER PRIMARY KEY,message TEXT
);

CREATE TABLE t_timenote(
   note_id INTEGER PRIMARY KEY REFERENCES t_note(id),time DATETIME
);

CREATE TABLE t_timerangenote(
   note_id INTEGER PRIMARY KEY REFERENCES t_note(id),end DATETIME
);

CREATE TABLE t_eventnote(
   note_id INTEGER PRIMARY KEY REFERENCES t_note(id),event_id INTEGER
);

从Note引出的未来类需要创建一个新表.

C.使用数据库规范化和VARIANT / sql_VARIANT

CREATE TABLE t_note(
   id INTEGER PRIMARY KEY,message TEXT
);

CREATE TABLE t_notedata(
   note_id INTEGER REFERENCES t_note(id),variable_id TEXT,-- or "variable_id INTEGER REFERENCES t_variable(id)".
                     -- where t_variable has information of each variable.
   value VARIANT
);

来自Note的未来类需要添加新的variable_id.

D.将每个具体类映射到一个表(根据当前答案新添加)

CREATE TABLE t_timenote(
   id INTEGER PRIMARY KEY,time DATETIME
);

CREATE TABLE t_timerangenote(
   id INTEGER PRIMARY KEY,end DATETIME
);

CREATE TABLE t_eventnote(
   id INTEGER PRIMARY KEY,event_id INTEGER
);

从Note引出的未来类需要创建一个新表.

sql中最合理的表示是什么?
有更好的选择吗?

解决方法

一般来说,我更喜欢使用“B”(即,一个表为基类和一个表为每个“具体”子类).

当然这有一些缺点:首先你必须加入至少2个表,每当你读完一个子类的完整实例.此外,任何必须以任何类型的笔记操作的人将不断访问“基础”表.

但这通常是可以接受的,除非你有极端的情况(数十亿行,需要很快的响应时间等等).

还有第三个可能的选项:将每个子类映射到一个不同的表.这有助于分区对象,但一般来说在开发工作中花费更多.

参见this进行完整的讨论.

(关于您的“C”解决方案,使用VARIANT:我不能评论优点/缺点,因为它看起来像一个专有的解决方案 – 它是什么?Transact-sql?我不熟悉它).

相关文章

SELECT a.*,b.dp_name,c.pa_name,fm_name=(CASE WHEN a.fm_n...
if not exists(select name from syscolumns where name=&am...
select a.*,pano=a.pa_no,b.pa_name,f.dp_name,e.fw_state_n...
要在 SQL Server 2019 中设置定时自动重启,可以使用 Window...
您收到的错误消息表明数据库 'EastRiver' 的...
首先我需要查询出需要使用SQL Server Profiler跟踪的数据库标...