php - 在 RDBMS 中将 ids 存储为逗号分隔的字符串是否有任何性能原因?

标签 php mysql database-design

<分区>

Possible Duplicate:
Is storing a delimited list in a database column really that bad?

我一直致力于几个 PHP/MySQL 项目,其中所有关系都存储为逗号分隔的字符串。

例如,一个共同的关系就像

(在伪代码中)

table people
id - integer
name - string
age - integer
teams - string (CSV OF integers, ex '1,3,9,21')

table teams
name - String
id - integer

管理关系变得很麻烦。

获取一个人的所有团队:

$person = 'SELECT * FROM People WHERE id= x';

然后在 php 中我一直在做类似的事情

$person['teams'] = SELECT * FROM teams WHERE id IN ($person['teams']);

当我写这篇文章时,我意识到我可以将它们组合在一个 mysql 查询中,比如:

SELECT 
  people.id, 
  people.name, 
  people.teams, 
  teams.name 
FROM people 
JOIN teams ON FIND_IN_SET(teams.id, people.teams) WHERE people.id=x

通过这种类型的设置,我发现自己经常使用 FIND_IN_SET

最后,我的问题是:创建这样的关系对性能有好处吗?

根据我目前的经验,FIND_IN_SET 通常进行全表扫描。如果没有性能优势,在哪些情况下使用逗号分隔的整数列表有好处?似乎 mysql 设计者在创建 FIND_IN_SET 时考虑到了一些事情。

最佳答案

你是对的,FIND_IN_SET() 不能使用索引,所以它会导致全表扫描。从技术上讲,该函数是对关系数据库的伪造操作,但毫无疑问,对它的需求很大,因此 MySQL 实现了它。

将数据存储在逗号分隔的列表中是非规范化 的一个示例。任何偏离规范化设计的行为都可以提高一种查询的性能,但通常是以牺牲针对同一数据的所有其他类型查询为代价的。

例如,如果您将球员及其球队存储为以逗号分隔的列表,则无需执行联接即可轻松获取给定球员的球队列表。这就是性能提升。但是获取给定球员球队的详细信息要困难得多。同样搜索给定团队中的所有球员。

仅当该列表被视为离散的“黑盒”数据时,才使用逗号分隔的列表。 IE。您的应用程序需要将该列表作为一个整体来获取,而不是列表的子集,并且您永远不需要编写 SQL 来使用该列表中的元素进行搜索、连接、排序、小计等。

另请参阅我对 Is storing a delimited list in a database column really that bad? 的回答

关于php - 在 RDBMS 中将 ids 存储为逗号分隔的字符串是否有任何性能原因?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14467007/

相关文章:

mysql - 在MYSQL中将文本转换为tinyint

php - 我期待不同的 sql 结果

mysql - 在这种情况下我应该使用面向对象的方法来设计数据库表吗

php - Laravel DB select 在某些数据绑定(bind)后生成意外的 SQL 错误

php - 加快用 PHP 进行的 MySQL 查询

php - 为每个文件创建上传状态 JQuery 和 AJAX

php - 将 CSV 文件导入 MySQL 数据库

php - 在 MySQL 中通过单个查询获取今天、本周、本月和今年的数据?

mysql - 当该表上已有记录时,在表中添加 FK 字段

database - 在模式中对 postgresql 表进行分组