我有一个事件表和一些不同类型的子表来定义每个事件。
事件表有一个ID,一个(可能是非唯一的)Datetime,userId和一个事件类型代码。
对于事件类型表,比如说ExerciseStart ...是EventId一个足够的主键吗?每个事件只有一种类型,因此不应该加倍。将日期时间包含在子类别中是否有用,甚至可能作为复合主键来避免意外加倍并可能使查询编写更容易? (虽然我觉得这也是多余的。)
(除非我使用Datetime和事件类型代码作为复合键,但这对我来说似乎更有潜在风险)
答案 0 :(得分:0)
我认为你需要的是被称为类表interitance: 你有一个包含所有常见属性的envent_table和许多不同类型事件的tabele。
可能是这样的:
CREATE TABLE events(
event_id SERIAL PRIMARY KEY,
... other fields
);
CREATE TABLE event_typeN(
event_id BIGINT UNSIGNED PRIMARY KEY,
...other fields,
FOREIGN KEY(event_id) REFERENCES events(event_id)
);
答案 1 :(得分:0)
使用标准SQL ...
执行'inheritence'或'subclassing'的常用方法是在(event_type, event_ID)
上使用复合键,并在引用'subtype'表中使用此键并使用CHECK
约束来确保{ {1}}适用于该'子类型',例如event_type
。
另外一种方法是让“子类型”表中的CHECK (event_type = 'Exercise start')
再次与相应的类型匹配,例如event_type DEFAULT
。
结构可能如下所示:
event_type VARCHAR(20) DEFAULT 'Exercise start' NOT NULL
然而,mySQL存在一个很大的问题,即它不会强制CREATE TABLE EventTypes
(
event_type VARCHAR(20) NOT NULL PRIMARY KEY
);
CREATE TABLE Events
(
event_ID CHAR(10) NOT NULL,
event_type VARCHAR(20) NOT NULL
REFERENCES EventTypes (event_type),
event_date DATE NOT NULL,
PRIMARY KEY (event_type, event_ID)
);
CREATE TABLE ExerciseStartEvents
(
event_ID CHAR(10) NOT NULL,
event_type VARCHAR(20) DEFAULT 'Exercise start' NOT NULL
CHECK (event_type = 'Exercise start'),
FOREIGN KEY (event_type, event_ID)
REFERENCES Events (event_type, event_ID),
PRIMARY KEY (event_type, event_ID),
exercise_description VARCHAR(30) -- etc --
);
约束:( [任何人都可以容忍这种情况超出我的范围!]所以回答你的问题,在{上设一个简单的密钥仅{1}}是不够的,因为您无法在“子类型”表中强制执行适当的类型。
虽然将'CHECK
'推广'作为子类型表中的候选键可能很诱人,但这可能不是一个好主意。虽然它只允许给定event_ID
的一行显示在表中,但如果该行的类型错误,则会阻止插入具有正确类型的行!
解决方案?转向更好的SQL实现;)