每个费用只与一张卡相关联,每张卡只与一个用户相关联。用户可能有多张卡存档。
如果我将这些数据保存在三个不同的表中的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
然后费用将直接与用户相关联。但是,这是冗余信息,因为相同的数据存储在卡表中。
思想?
答案 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 = ?