在关系数据库中存储(和访问)历史1:M关系的最佳方法是什么?

Dav*_*ney 4 mysql sql database-design

假设的例子:

我有汽车和车主.每辆车在给定时间属于一个(且仅一个)所有者,但所有权可能被转移.车主可以随时拥有零辆或多辆车.我想要的是将历史关系存储在MySQL数据库中,这样,在给定任意时间的情况下,我可以查找当前的车辆所有者分配.

即在时间X(X可以现在或过去的任何时间):

  • 谁拥有车Y?
  • 拥有者Z拥有哪些车(如果有的话)?

在SQL中创建M:N表(带有时间戳)很简单,但是我想避免使用相关的子查询,因为这个表会变大(因此性能会受到影响).有任何想法吗?我觉得有一种方法可以通过加入这样一个表来实现这一点,但我对数据库的经验并不十分.

更新:我想避免每行使用"start_date"和"end_date"字段,因为每次插入新行时都需要(可能)昂贵的查找.(而且,它是多余的).

HLG*_*GEM 9

制作第三个名为CarOwners的表,其中包含carid,ownerid和start_date以及end_date字段.购买汽车时填写前三个并检查表格以确保没有其他人被列为所有者.如果有,则将该数据更新为end_date.

要查找当前所有者:

select carid, ownerid from CarOwner where end_date is null
Run Code Online (Sandbox Code Playgroud)

要在某个时间点找到所有者:

select carid, ownerid from CarOwner where start_date < getdate()
and end_date > getdate()
Run Code Online (Sandbox Code Playgroud)

getdate()是特定于MS SQL Server的,但每个数据库都有一些返回当前日期的函数 - 只需替换.

当然,如果您还需要其他表中的其他信息,您也可以加入其中.

select co.carid, co.ownerid, o.owner_name, c.make, c.Model, c.year  
from  CarOwner co
JOIN Car c on co.carid = c.carid
JOIN Owner o on o.ownerid = co.ownerid
where co.end_date is null
Run Code Online (Sandbox Code Playgroud)