我最近参与了一个项目,该项目必须管理大量用于湖泊读数的数据样本。在这个项目中,我们有类似于以下的表格,其中records
是按位置和上传者收集的湖泊读数,并samples
包含实际的湖泊读数——比如温度和强度。
CREATE TABLE records(
email TEXT REFERENCES users(email),
lat DECIMAL,
lon DECIMAL,
depth TEXT,
upload_date TIMESTAMP,
comment TEXT,
PRIMARY KEY (upload_date,email)
);
CREATE TABLE samples(
date_taken TIMESTAMP,
temp DECIMAL,
intensity DECIMAL,
upload_date TIMESTAMP,
email TEXT,
PRIMARY KEY(date_taken,upload_date,email),
FOREIGN KEY (upload_date,email) REFERENCES records(upload_date,email)
);
samples
被建模为一个弱实体,依赖于records
. 如您所知,这意味着所有外键都继承自records
并用于标识samples
. 但是如果我们决定把它变成一个实体会发生什么?好吧,你可以用几种不同的方式来看待它,要么:
正如您所建议的,主键 fromrecords
将不存在samples
,我们将不得不分配某种任意的自动增量类型 ID。每条记录都包含数千个样本,用户将样本视为他们在现场记录的记录的一部分。他们希望按记录浏览样本,因此我们将有一个非常大的
samples
表,没有明显的映射到他们在现实生活中所属的记录。
或者我们根本不将其建模为弱实体,而是认识到它需要能够用records
一行来标识自己,所以我们分配一个upload_date
and email
。如果我们将这两个条目设为外键,那么我们只是在没有意识到的情况下创建了一个弱实体。如果我们不这样做,那么我们的应用程序层必须负责检查以确保每个upload_date
和email
也存在于 中records
,而不是由数据库执行。
在这种情况下,创建samples
一个弱实体(在其主键中包括外键)是最简单的选择(也是最有意义的)。
概括
当实体在现实生活中实际上很弱时,您应该将实体建模为弱。如果您有一个实体需要不同键的一部分来标识自己(具有作为其主键一部分的外键),那么它可能很弱。
你能改造系统以避免使用弱实体吗?可能,如果我们想要有未关联的样本,那么我们需要能够将它们设为空upload_date
,email
这意味着它们不会在主键中,也不会是弱实体。我们将不得不做我在 1 中描述的事情。