冗余数据还是两个查询?

时间:2013-05-24 20:08:47

标签: mysql redundancy

例如,拿一张持有信用卡费用的桌子,一张持有信用卡的桌子,以及一张存放用户的桌子。

每个费用只与一张卡相关联,每张卡只与一个用户相关联。用户可能有多张卡存档。

如果我将这些数据保存在三个不同的表中的MySQL数据库中,如下所示:

费用:

---------------------------------------------
id | card | amount | description | datestamp
---------------------------------------------
5  | 2    | 50.00  | Example     | 1369429422

卡:

------------------------------------------------------------------
id | user | name       | number           | cvv2 | exp_mm | exp_yy
------------------------------------------------------------------
2  | 1    | Joe Schmoe | 4321432143214321 | 555  | 1      | 16

用户:

-------------------------------------------
id | first_name | last_name | email
-------------------------------------------
1  | Joe        | Schmoe    | joe@schmoe.co

现在,让我们说我想要收取用户的费用。为了联系用户,我首先要查找与费用相关联的卡,然后查找与该卡相关联的用户。显然,在这样的例子中,速度可以忽略不计。但在其他情况下,我认为这是两个查询。

但是,如果我这样存储数据:

----------------------------------------------------
id | card | user | amount | description | datestamp
----------------------------------------------------
5  | 2    | 1    | 50.00  | Example     | 1369429422

然后费用将直接与用户相关联。但是,这是冗余信息,因为相同的数据存储在卡表中。

思想?

2 个答案:

答案 0 :(得分:1)

您不直接在费用表中包含用户信息是正确的;但是,它仍然只有一个查询:

select first_name, last_name, email
from users, cards, charges
where users.id = cards.user
and cards.id = charges.card
and charges.id = 5;

这将为您提供ID为5的费用的用户信息。这是关系数据库最擅长的事情:)这种事情被称为“连接”,因为它将多个表连接在一起为您提供您需要的信息。有多种方法可以编写此查询。

顺便说一句,也许这是一个人为的例子,但如果这是一个你从头开始编写的应用程序,有很多理由可以避免在你自己的数据库中存储信用卡。通常,支付处理商可以为您处理详细信息,同时仍允许您对信用卡收费。 More info.

答案 1 :(得分:1)

您可以通过将用户ID添加到费用表来进行非规范化。鉴于表的预期大小,您需要知道是否有必要。如果有必要进行此优化,请使用它。如果你不知道,那么在将来必要时进行优化。

目前,您不需要两个查询

SELECT users.* FROM charges
JOIN cards ON charges.card = cards.id
JOIN users ON cards.user = users.id
WHERE charges.id = ?