您需要一个缓慢变化的维度:
我只会为电子邮件和电话执行此操作,以便您理解(注意我使用两个键的事实,一个在表中是唯一的,另一个是它所关注的用户唯一的。这就是表key 标识记录,user key 标识用户):
table_id、user_id、电子邮件、电话、created_at、inactive_at、is_current
- 1, 1, mario@yahoo.it, 123456, 2012-01-02, , 2013-04-01, 没有
- 2, 2, erik@telecom.de, 123457, 2012-01-03, 2013-02-28, 否
- 3, 3, vanessa@o2.de, 1234568, 2012-01-03, null, 是
- 4, 2, erik@telecom.de, 123459, 2012-02-28, null, 是
- 5, 1, super.mario@yahoo.it, 654321,2013-04-01, 2013-04-02, 没有
- 6, 1, super.mario@yahoo.it, 123456,2013-04-02, null, 是
数据库的最新状态
select * from FooTable where inactive_at is null
或者
select * from FooTable where is_current = 'yes'
mario 的所有更改(mario 为 user_id 1)
select * from FooTable where user_id = 1;
2013 年 1 月 1 日至 2013 年 5 月 1 日之间的所有更改
select * from FooTable where created_at between '2013-01-01' and '2013-05-01';
并且您需要与旧版本进行比较(借助存储过程、java 或 php 代码...您选择)
select * from FooTable where incative_at between '2013-01-01' and '2013-05-01';
如果你愿意,你可以做一个花哨的 sql 语句
select f1.table_id, f1.user_id,
case when f1.email = f2.email then 'NO_CHANGE' else concat(f1.email , ' -> ', f2.email) end,
case when f1.phone = f2.phone then 'NO_CHANGE' else concat(f1.phone , ' -> ', f2.phone) end
from FooTable f1 inner join FooTable f2
on(f1.user_id = f2.user_id)
where f2.created_at in
(select max(f3.created_at) from Footable f3 where f3.user_id = f1.user_id
and f3.created_at < f1.created_at and f1.user_id=f3.user_id)
and f1.created_at between '2013-01-01' and '2013-05-01' ;
正如您所看到的多汁查询,将 user_ 与预览用户行进行比较...
2013-03-01 数据库的状态
select * from FooTable where table_id in
(select max(table_id) from FooTable where inactive_at <= '2013-03-01' group by user_id
union
select id from FooTable where inactive_at is null group by user_id having count(table_id) =1 );
我认为这是实现您想要的最简单的方法...您可以实现数百万个表的关系模型,但是查询它会很痛苦
您的数据库不够大,我每天都在使用更大的数据库。现在告诉我,你在新服务器上节省的钱是否值得你花时间在超级复杂的关系模型上?
顺便说一句,如果数据变化太快,这种方法就不能用了……
奖金:优化: