Mysql 表格设计中的困惑
我正在使用Mysql,我有两个表-Mysql 表格设计中的困惑,mysql,schema,Mysql,Schema,我正在使用Mysql,我有两个表- BusDetails +-------+-----------+ | busId | BusName | +-------+-----------+ | 1 | A TRAVELS | | 2 | B TRAVELS | | 3 | C TRAVELS | +-------+-----------+ AreaDetails +--------+----------+ | ci
BusDetails
+-------+-----------+
| busId | BusName |
+-------+-----------+
| 1 | A TRAVELS |
| 2 | B TRAVELS |
| 3 | C TRAVELS |
+-------+-----------+
AreaDetails
+--------+----------+
| cityId | cityName |
+--------+----------+
| 1 | ABC |
| 2 | DEF |
| 3 | GHI |
| 4 | JKL |
+--------+----------+
现在我必须创建第三个表,它将bus表映射到city表。假设busId 1在城市ID 2和3停,busId 2在城市ID 1和4停。要创建此场景,我有两个选项-
first option-
+-------+--------+
| busId | areaId |
+-------+--------+
| 1 | 3,2 |
| 2 | 4,1 |
+-------+--------+
second option-
+-------+--------+
| busId | areaId |
+-------+--------+
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 4 |
+-------+--------+
将来当有大量记录时,哪个表的性能更好?为什么?答案取决于您的使用情况 虽然不建议使用第一个选项,但如果您有非常大的数据,并且不打算执行广泛的数据库操作(可能是针对自己或小型项目),则可以使用它
第二种选择有其自身的优势,是关系模型推荐的。它将为您提供更大的灵活性和可扩展性,因为这样可以最大限度地减少冗余 亲爱的第二个表之所以更好,是因为在很长一段时间内,您有大数据第二种类型,可以保存这么多行,但更适合于轻松获取报表,便于SQL查询。您可以轻松地键入join。第一个选项很差,因为逗号分隔的列表不会被索引。如果你想找到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中无法枚举逗号分隔列表中的所有区域。我认为第二个选项是batter。因为您将在本场景中管理一对多关系。所以您可以轻松找到与总线或区域相关的任何信息。了解数据库规范化。逗号分隔列表在关系数据库中是有害的。@Barmar那么冗余呢?如果我选择第二个选项,我会一次又一次地重复busId。如果每个选项都描述了一个独立的关系,这并不是多余的。如果映射表中也有busName
,则这将是多余的。这是关系数据库模型与层次和网络模型之间的区别。当你有一个多对多的关系时,你必须列出所有的对。