假设我有一个简单的表,例如:
CREATE TABLE authors (
id INT PRIMARY KEY,
name VARCHAR(40),
born DATE,
died DATE
);
born
和died
日期都是可选的,因此它们可以包含NULL
。
可能是尚未出生的作者,不会将其列入表格,因此解释NULL
的明显方法是日期未知。
但是,died
日期存在一些歧义。 null可能意味着日期未知,或者作者尚未死亡。
允许未知日期和尚未发生的事件的首选方式是什么?
对于它的价值,我经常使用PostgreSQL,MySQL / MariaDB和SQL Server,所以这个问题不是特定于特定的DBMS。
答案 0 :(得分:1)
处理此问题的一种方法是添加一个新列deceased
,指示给定作者是否已过期。这使您的died
日期字段免于对作者是否已经死亡负责。根据这种设计,如果作者尚未死亡(deceased
是假的),那么我们就不会关心死亡日期。如果作者已经死亡,那么NULL
值只会意味着日期真的未知。
答案 1 :(得分:1)
可能的解决方案是删除died
列并添加下表:
CREATE TABLE deaths (
id INT PRIMARY KEY REFERENCES authors(id),
died DATE
);
在这种情况下,没有记录可能意味着作者没有死亡,而NULL
died
意味着作者已经死亡,但日期未知。
然后可以如下提取数据数据:
SELECT
a.id, a.name, a.born,
CASE WHEN d.id IS NULL THEN 'living' ELSE coalesce(d.died,'unknown') END
FROM authors a LEFT JOIN deaths d ON a.id=d.id;
d.id
列用于确定是否存在匹配的行,否则作者被视为活着。如果存在匹配的行,则结果为died
日期或合并的替代。
答案 2 :(得分:1)
这详细阐述了蒂姆的答案。我认为最好的方法是:
event
此代码验证以下条件:
CREATE TABLE authors (
id INT PRIMARY KEY,
name VARCHAR(40),
isDead int not null, -- well, could be a bit or boolean or tinyint
bornDate DATE,
diedDate DATE,
constraint chk_authors_isDead check (isDead in (0, 1)), -- valid values
constraint chk_authors_isDead_diedDate check (isDead = 1 or diedDate is NULL),
constraint check_authors_bornDate_diedDate check (bornDate <= diedDate) -- you might want to require that they are actually old enough to have written somthing
);
列仅采用0和1的值。isDead
不是DiedDate
,则NULL
为1。检查约束是标准SQL,并且受大多数数据库的支持 - 但不是MySQL的支持。