我有一个直截了当的问题。
我正在做一个使用MySQL的Web应用程序,我正在设计它。我只是对性能有一个小问题。
我想知道哪些更有效:
场景#1:
Table: Restaurant
-Name
-City
-Province
-Country
-Continent
sql =~ select * from restaurant where id = something.
或
场景#2:
Table: Restaurant
-Name
-City
Table: City
-Name
-Province
Table: Province
-Name
-Country
Table: Country
-Name
-Continent
Table: Continent
-Name
sql =~ [insert multiple sql queries that will output the name and the city,
with the corresponding province, country, and continent]
从逻辑上讲,我认为场景#1更好(更少查询),但有些人却向我发誓。
答案 0 :(得分:3)
是的,但问题是哪个选项表现更好。在这种情况下,毫无疑问:选项#1将表现更好,因为查询不必与任何其他表JOIN。 Randolph确实有一个好处,只要有可能,你应该规范化你的数据库结构。
答案 1 :(得分:2)
如果您对数据库设计没有经验,我建议您始终使用标准化版本。在大多数情况下,这是正确的做法。在某些情况下,您可能希望对数据库进行非规范化,但是您应该确切知道为什么要这样做。
请注意,在第二种情况下,它不是多个查询。它只是一个查询,其中所有表都连接在一起。例如:
SELECT *
FROM restaurant
JOIN city ON city.id=restaurant.city
JOIN province ON province.id=city.province
...
是的,编写需要更长的时间,但它比数据库中的数据不一致(维护非规范化数据库更难)。您也可以使用ORM为您执行此类操作。
答案 2 :(得分:0)
第二个选项是规范化结构,这意味着您的数据冗余更少,发生错误的机会更少等。我总是投票支持规范化数据,除非您遇到性能问题。
顺便说一下,SELECT * FROM [Table]
无论如何都不是好习惯。你需要输入列名。
答案 3 :(得分:0)
如果您使用第一个方案,则会出现空间使用增加的问题(对于所有重复的省份,国家/地区),如果您需要更改城市/国家/地区的名称,则需要在所有行中更改它被使用了。
为方便起见,我将使用第二种情况。我不认为两种情况之间会有很大的性能差异(在第一种情况下,您只触摸一个表,但从磁盘读回更多数据,在第二种情况下,您从磁盘读取的数据较少,但是从多个表中读取数据) )。这实际上取决于你在那里有什么样的数据。
编辑:为了解释我的观点:如果将所有数据保存在一个大表中,那么你需要实际读取磁盘中的所有行,即使读取的大部分数据是相同的(即市,省,国家,大陆)。即使SQL缓存数据,它也无济于事,因为它无法知道来自其他行的数据是相同的。
如果您规范化数据库并从餐厅表中读取,您将获得城市的ID。现在,如果您在多行上拥有相同的ID,SQL服务器将缓存为城市读取的数据,并且不会再次访问磁盘,因此速度会提高。这将被访问新表的需要所抵消,但是对城市ID的正确索引应该不会太多。
这就是为什么我说使用大型数据库时,性能差异并不容易评估,你最好还是有一个正确规范化的数据库。
是的,如果您使用标准化数据库(第二种情况),您可以在一个地方更改城市名称,因为城市将有一行。这同样适用于其他国家(省,国家,大陆)。
答案 4 :(得分:0)
谢谢你们的意见。 “规范化数据库设计”是关键。我用Google搜索,快速阅读它,虽然性能稍差,但专业人士确实值得。
再次感谢。 (那真的很快btw!) http://en.wikipedia.org/wiki/Database_normalization
维基百科声称非规范化具有更好的性能,但我认为我只是变得自大,并认为我可以处理一个大的非规范化数据库。
我会坚持风险较小的情景。如果shits击中风扇,我将改变硬件=)。
再次感谢你们。