假设我有一个类似于以下内容的数据库:
Table: People
id | name | age
---+------+-----
1 | dave | 78
Table: Likes
id | userid | like
---+--------+-------
1 | 1 | apples
---+--------+-------
2 | 1 | oranges
---+--------+-------
3 | 1 | women
处理更新daves
数据的最佳方法是什么?目前,我执行以下操作:
Update his age
UPDATE People SET age = 79 WHERE id = 1;
Update his likes
DELETE FROM Likes WHERE userid = 1;
INSERT INTO LIKES (userid, like) VALUES (1, 'new like');
INSERT INTO LIKES (userid, like) VALUES (1, 'another like');
我从表中删除了所有用户数据,然后读取了他们的新内容。这似乎效率低下。还有更好的方法吗?
答案 0 :(得分:2)
我不清楚为什么建议更新父表中的记录与子表中的依赖项之间的链接。具有单独表格的关键在于我们可以修改People
中的非键列而不触及Likes
。
在更新Likes
时,有两种不同的业务交易。第一个是当戴夫说,“我不是说'橘子',我的意思是说我喜欢插花”。纠正错误将使用更新:
update likes
set like = 'flower arranging'
where userid = 1
and like = 'oranges'
/
WHERE子句可以使用LIKES.ID列。
另一种情况是偏好实际发生了变化。也就是说,当戴夫说“现在我79岁时,我不再喜欢女人了。我有新的口味。”这可能如下所示:
delete from likes
where userid = 1
and like = 'women'
/
insert into likes (userid, like)
values (1, 'dominoes')
/
insert into likes (userid, like)
values (1, 'Werthers Orignals')
/
这两个陈述之间的区别主要在于清晰度。我们可以将第二组语句实现为更新和单个插入,但这会产生误导。保持对数据的有意义的改变和纠正错误之间的区别是一个有用的学科。当我们保留历史记录和/或审核更改时,它尤其有用。
删除所有Dave的Likes
记录然后重新插入它们绝对是一个坏主意。您的应用程序应该能够跟踪哪些记录已更改。
答案 1 :(得分:1)
根据DBMS,您可以使用“MERGE”“REPLACE”“INSERT OR REPLACE”, 大多数DBMS支持此功能,但语法变化很大,因此您需要使用RTFM来了解如何使用您正在使用的数据库。
答案 2 :(得分:0)
您可以在Likes中添加一个新列来存储实际年龄。通过这样做,您可以获得历史记录功能,您可以通过请求年龄最高的人来确定他的喜好:
SELECT * FROM Likes WHERE userid = 1 AND age = (SELECT MAX(age) FROM Likes WHERE userid = 79 GROUP BY userid);
当你想要覆盖一些喜欢时,你也可以添加另一列“overriden_by”,其中包含新Like的id。这将导致更简单的查询:
SELECT * FROM Likes WHERE userid = 1 and overriden_by is null;