SQL:查找哪条记录与给定记录相关的最快查询是什么

时间:2013-12-05 08:11:25

标签: mysql sql

我有这个表结构

Table A
-------
id , name
1  , A1
2  , A2
3  , A3
4  , A4
5  , A5
6  , A6

Table B
-------
id , name , tableA_id
1  , B1   , 1
2  , B2   , 2
....

Table C
-------
id , name , tableA_id
1  , C1   , 3
2  , C2   , 4
....

Table D
-------
id , name , tableA_id
1  , C1   , 5
2  , C2   , 6
....

问题

  • 如果给我表A id:3找到的最快方法是什么 来自B,C,D表的相关行?
  • 我会经常跑这个会没事吗?
  • 如何确保表A中的每条记录在B,C,D中只有1条且只有1条记录
  • 有什么我可以做的改进结构,所以我可以使用更快的查询实现我正在寻找的东西?我在想2个解决方案,但我不确定这是不是一个好的做法

解决方案1:

Table A
-------
id , name , B_id, C_id, D_id
1  , A1   ,  1  ,     ,
2  , A2   ,  2  ,     ,
3  , A3   ,     ,  1  ,
4  , A4   ,     ,  2  ,
5  , A5   ,     ,     , 1
6  , A6   ,     ,     , 2

解决方案2:

Table A
-------
id , name , table, id
1  , A1   ,  B  ,  1
2  , A2   ,  B  ,  2
3  , A3   ,  C  ,  1
4  , A4   ,  C  ,  2
5  , A5   ,  D  ,  1 
6  , A6   ,  D  ,  2

但我对两种解决方案都不满意,因为我认为我不能应用限制/将其映射为正确的外键

2 个答案:

答案 0 :(得分:1)

如果表A中的记录与表B或C或D的一个或多个记录相关,那么您的设计是好的。但是,您可以将B,C和D表合并为一个,并仅添加一个以区分它,例如CategoryType。假设我们将合并表命名为M.结构可能会这样。

ID, Name, CategoryType, tableA_id

使用示例数据:

ID  Name  CategoryType tableA_id
1   C1     C             1
2   B1     B             2
3   A1     A             3

但是,如果表A中的记录与表B或C或D中的一个且仅有一个记录相关,那么它应该在一个表中。

另一方面,使用您当前的数据库结构,您可以使用UNION ALL合并结果和LIMIT 1,以确保只显示一个匹配项,例如:

SELECT a.id, b.name as OneName
FROM tableA A
INNER JOIN tableB B
ON a.id = b.tableA_id
UNION ALL
SELECT a.id, b.name as OneName
FROM tableA A
INNER JOIN tableC C 
ON a.id = c.tableA_id
UNION ALL
SELECT a.id, b.name as OneName
FROM tableA A
INNER JOIN tableC D 
ON a.id = d.tableA_id
LIMIT 1

答案 1 :(得分:1)

我会使用不同的选项,特别是如果您将来要销售超过三种商品类别。
粗略地说,你需要4个表格(在任何语言/本地化之前):

Product_Category
----------------
id  -- autoincrement id
name  --  varchar

Product
----------
id  -- autoincrement id
productCategoryId  -- fk referenct to Product_Category.id
name  -- varchar
price  -- decimal/numeric
(other columns as needed)

Attribute
------------
id  -- autoincrement id
name  -- varchar
type  -- code
description  -- varchar

Product_Attribute
-------------------
productId  -- fk reference to Product.id
attributeId -- fk reference to Attribute.id
value  -- varchar

(是的,我一般厌恶EAV设置,这就是它的用途)

为什么会这样?好吧,一般来说,每次添加新产品类型时添加新表都不是很好。实际上,您希望在Product本身内放置尽可能多的属性 - 这需要是一个平衡的行为 - 尝试找出一些常见查询的属性并将它们放在该表中,甚至如果不是每个类别都有它们(显然,这将需要可以为空的列) 此外,一些Product列可能会在此处拉出“双重职责”(... ... ...);汽车显然有颜色,家具也是如此 - 只有一个是油漆,另一个是污渍 其他一切都进入Product_Attribute。请注意使用Attribute来帮助保持属性拼写错误和重复条目(这应该是您的产品入口团队策划的内容,而不是客户)。虽然,你可能会对你的标题/描述的良好索引和搜索功能产生什么感到惊讶。