Mysql分页多个表

时间:2015-01-15 07:10:28

标签: mysql pagination

我正在开发一个电子商务网站,其中MySQL有两个数据库表,一个是产品,另一个是分类,产品和分类是多对多关系,分类法有树结构,这意味着分类表中的parent_id字段,用于标识分类的父ID。

当用户选择一个分类法时,我希望获得属于该分类法及其所有后代分类法的所有产品,我首先找到所选分类法的所有后代分类法,然后从那里获得分页产品结果,但在我的网站上总共有5000种分类法,我的解决方案使网站变得像狗一样慢......有关如何为了性能而实现这一目标的任何建议吗?

产品表:

+-------------------+----------------------+------+-----+---------------------+----------------+
| Field             | Type                 | Null | Key | Default             | Extra          |
+-------------------+----------------------+------+-----+---------------------+----------------+
| id                | int(10) unsigned     | NO   | PRI | NULL                | auto_increment |
| code              | bigint(20)           | NO   | UNI | NULL                |                |
| SKU               | varchar(255)         | NO   |     | NULL                |                |
| name              | varchar(100)         | NO   |     | NULL                |                |
| description       | varchar(2000)        | NO   |     | NULL                |                |
| short_description | varchar(200)         | NO   |     | NULL                |                |
| price             | decimal(8,2)         | NO   |     | 0.00                |                |
| discounted_price  | decimal(8,2)         | NO   |     | 0.00                |                |
| stock             | smallint(5) unsigned | NO   |     | 0                   |                |
| sales             | smallint(5) unsigned | NO   |     | 0                   |                |
| num_reviews       | smallint(6)          | NO   |     | 0                   |                |
| weight            | decimal(5,2)         | NO   |     | 0.00                |                |
| overall_rating    | decimal(3,2)         | NO   |     | 5.00                |                |
| activity_id       | int(10) unsigned     | YES  | MUL | NULL                |                |
| created_at        | timestamp            | NO   |     | 0000-00-00 00:00:00 |                |
| updated_at        | timestamp            | NO   |     | 0000-00-00 00:00:00 |                |
+-------------------+----------------------+------+-----+---------------------+----------------+

分类表:

+--------------+------------------+------+-----+---------+----------------+
| Field        | Type             | Null | Key | Default | Extra          |
+--------------+------------------+------+-----+---------+----------------+
| id           | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name         | varchar(100)     | YES  | UNI | NULL    |                |
| parent_id    | int(10) unsigned | YES  | MUL | NULL    |                |
| num_products | smallint(6)      | NO   |     | 0       |                |
+--------------+------------------+------+-----+---------+----------------+

product_taxonomy表:

+-------------+------------------+------+-----+---------+----------------+
| Field       | Type             | Null | Key | Default | Extra          |
+-------------+------------------+------+-----+---------+----------------+
| id          | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| product_id  | int(10) unsigned | NO   | MUL | NULL    |                |
| taxonomy_id | int(10) unsigned | NO   | MUL | NULL    |                |
+-------------+------------------+------+-----+---------+----------------+

1 个答案:

答案 0 :(得分:1)

如果单级别的深度可以使用以下查询

SELECT * FROM `product_taxonomy` 
INNER JOIN (SELECT * FROM `taxonomies` WHERE `id` = 100 OR `parent_id` = 100) `taxonomies` 
ON `product_taxonomy`.`taxonomy_id` = `taxonomies`.`id`
LEFT JOIN `products` ON `product_taxonomy`.`product_id` = `products`.`id`

您可以将限制偏移添加到上面的分页查询中。

上述查询中的

100 表示用户请求的分类标识。

除此之外,我建议: -

1)产品表中的 id ,如果可能的话,会重命名为product_taxonomy中引用的product_id,而我在其他表格中假设taxonomy_id

这种方式,当您加入查询列名称时将是相同的。

2)我希望product_taxonomyproduct_idproduct_taxonomytaxonomy_id被编入索引,以便更快地进行查询。

<强>更新

您在下面的评论中提到的是分层数据问题,而不是理想情况下的关系数据库。

解决方案1 ​​

如果您确定您将只有4个级别/代,那么您可以进行4次加入查询。

如果需要,我可以详细说明。

解决方案2

如果你不太深入或致力于这个项目的体系结构,我建议重组它,这样一种方式,服务器端脚本处理递归。即,您更改CMS /分类法管理时,无论何时添加/删除/修改分类法,脚本都会更新一个名为taxonomy_childs的表,其中包含给定类别的所有可能后代,以便您拥有平坦的数据。在需要时处理。

我个人更喜欢这个。我总是喜欢我的数据库来满足我的业务逻辑要求。

如果需要,我可以详细说明。

解决方案3

如前所述,分层数据不是关系数据库的强项。说过你可以实现一个叫做嵌套集模型的东西。

请在http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

了解详情

您需要在分类表中添加3列: - level_depth,lft,rht。

请让我知道您希望我详细说明哪种解决方案。