创建表设计时的困惑

时间:2014-07-31 06:57:51

标签: mysql schema

我使用的是Mysql,我有两个表 -

BusDetails
    +-------+-----------+
    | busId | BusName   |
    +-------+-----------+
    | 1     | A TRAVELS |
    | 2     | B TRAVELS |
    | 3     | C TRAVELS |
    +-------+-----------+

AreaDetails
+--------+----------+
| cityId | cityName |
+--------+----------+
| 1      | ABC      |
| 2      | DEF      |
| 3      | GHI      |
| 4      | JKL      |
+--------+----------+

现在我必须创建第三个表,它将总线表映射到城市表。假设busId 1在cityId 2和3处停止,bustId在cityId 1和4处停止。要创建此场景,我有2个选项 -

first option-
+-------+--------+
| busId | areaId |
+-------+--------+
| 1     | 3,2    |
| 2     | 4,1    |
+-------+--------+

second option-
+-------+--------+
| busId | areaId |
+-------+--------+
| 1     | 2      |
| 1     | 3      |
| 2     | 1      |
| 2     | 4      |
+-------+--------+

将来会有大量的记录,那么哪个表会提供更好的性能以及为什么?

3 个答案:

答案 0 :(得分:2)

第一个选项很差,因为逗号分隔的列表没有被索引。如果要查找区域2中的所有公共汽车,则必须使用

SELECT busID
FROM bus_areas
WHERE FIND_IN_SET('2', areaID)

这必须执行全表扫描,解析每行的areaID列,并测试2是否是结果数组的成员。

您可以使用第二个版本:

SELECT busID
FROM bus_areas
WHERE areaID = 2

如果您在areaID上有索引,这将非常有效。

如果你想知道每个区域有多少辆公共汽车,第二种选择很容易:

SELECT areaID, COUNT(*)
FROM bus_areas
GROUP BY areaID

使用第一个选项会更麻烦:

SELECT cityID, COUNT(*)
FROM areaDetails a
JOIN bus_areas ba ON FIND_IN_SET(a.cityID, ba.areaID)
GROUP BY cityID

这将是非常低效的,因为它必须执行M * N FIND_IN_SET操作,并且如上所述,这不能被索引。请注意,我必须加入areaDetails表,因为无法枚举SQL中逗号分隔列表中的所有区域。

答案 1 :(得分:0)

答案取决于您的使用。

虽然不建议使用第一个选项但是如果您有非常大的数据并且您不打算执行各种数据库操作(可能是自我项目或小项目),您可以使用它。

第二种选择有自己的优势,并由关系模型推荐。它将为您提供更大的灵活性和可扩展性,从而最大限度地减少冗

答案 2 :(得分:0)

亲爱的第二张桌子因为所有原因而更好Baecause很长一段时间你有大数据第二类型保存这么多行,但更容易获得报告,方便SQL查询。你们都可以轻松加入。