[英]How to query huge MySQL databases?
我有2个表,一个purchases
表和一个users
表。 购买表中的记录如下所示:
purchase_id | product_ids | customer_id
---------------------------------------
1 | (99)(34)(2) | 3
2 | (45)(3)(74) | 75
用户表如下所示:
user_id | email | password
----------------------------------------
3 | joeShmoe@gmail.com | password
75 | nolaHue@aol.com | password
为了获得用户的购买历史记录,我使用如下查询:
mysql_query(" SELECT * FROM purchases WHERE customer_id = '$users_id' ");
问题是,当成千上万条记录插入购买表时会发生什么。 我觉得这会影响演出。
因此,我正在考虑将购买的商品直接存储在用户行的其他字段中:
user_id | email | password | purchases
------------------------------------------------------
1 | joeShmoe@gmail.com | password | (99)(34)(2)
2 | nolaHue@aol.com | password | (45)(3)(74)
当我在用户的表中查询用户名等信息时,使用该查询就可以轻松获取他们的购买历史记录。
这是一个好主意吗?它会帮助改善性能,还是收益微不足道,不值得使数据库看起来更混乱?
我真的很想知道专家在这些情况下的工作方式,例如,由于亚马逊拥有数百万的客户,因此亚马逊如何查询用户购买历史的数据库。 查询为何不花几个小时?
好的,所以我想将它们分开是可行的方法。 现在的问题是一个设计:
我应该继续使用前面说明的“购买”表吗? 在该设计中,我使用括号将每次购买的产品ID分开,并将其用作分隔符,以在通过PHP提取ID时区分ID。
相反,我应该将每个产品ID分别存储在“购买”表中,这样看起来是这样吗?:
purchase_id | product_ids | customer_id
---------------------------------------
1 | 99 | 3
1 | 34 | 3
1 | 2 | 3
2 | 45 | 75
2 | 3 | 75
2 | 74 | 75
不,这是一个非常非常非常糟糕的主意。
您正在打破第一个范式,因为您不知道如何分页浏览大型数据集。
亚马逊和雅虎! Google会带回(潜在地)数百万条记录-但它们一次只能以10或25或50的块显示给您。
他们也很聪明地猜测或计算出您最可能感兴趣的那些-他们首先向您展示。
我最可能对我的历史记录中的哪些购买感兴趣? 当然是最新的。
在违反关系数据库基础知识之前,您应该考虑将它们构建到设计中。
首先,成千上万的记录是什么。 除非您在内存和硬盘空间有限的青少年计算机上运行,否则数据库甚至不会闪烁100,000条记录。
至于将购买详细信息存储在用户表中……如果用户进行了多次购买,会发生什么?
MySQL具有极大的可扩展性,不要让它免费的事实使您信服。 将两个表分开可能是最好的,这不仅是因为它使数据库更正常,而且具有更多的索引将加快查询速度。 10,000个记录数据库相对于亿万个记录健康记录数据库而言相对较小。
就亚马逊和谷歌而言,他们雇用了数百名开发人员来为他们的特定应用程序需求编写专门的查询语言……没有像我们这样的开发人员有足够的资金来资助。
由于您将多个product_ids
存储在单个字段中,而不是像这样创建“关联”表,因此数据库看起来已经很混乱。
_____product_purchases____
purchase_id | product_id |
--------------------------
1 | 99 |
1 | 34 |
1 | 2 |
您仍然可以在一个查询中获取它:
SELECT * FROM purchases p LEFT JOIN product_purchases pp USING (purchase_id)
WHERE purchases.customer_id = $user_id
但这也为您提供了更多的可能性,例如找出购买了#99产品的数量,获得购买了#34产品的所有客户的清单等。
当然,不要忘记索引,这将使所有这些过程变得更快。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.