dm0*_*514 1 php mysql database-design
可能重复:
在数据库列中存储分隔列表真的那么糟糕吗?
我一直致力于几个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
Run Code Online (Sandbox Code Playgroud)
管理关系变得很麻烦.
让一个人获得所有团队:
$person = 'SELECT * FROM People WHERE id= x';
然后在PHP我一直在做类似的事情
$person['teams'] = SELECT * FROM teams WHERE id IN ($person['teams']);
Run Code Online (Sandbox Code Playgroud)
当我写这篇文章时,我意识到我可能会将它们组合在一个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
Run Code Online (Sandbox Code Playgroud)
通过这种类型的设置,我发现自己FIND_IN_SET经常使用
最后,我的问题是:创建这样的关系是否有性能优势?
根据我迄今为止的经验,FIND_IN_SET通常都在进行全表扫描.如果没有性能优势,在哪些情况下使用逗号分隔的整数列表是否有益? 在创建FIND_IN_SET时,似乎mysql设计者已经想到了一些东西.
你是对的,FIND_IN_SET()不能使用索引,因此它会导致全表扫描.从技术上讲,该函数对于关系数据库来说是一种虚假的操作,但毫无疑问对它有很多需求,因此MySQL实现了它.
将数据存储在以逗号分隔的列表中是非规范化的示例.任何偏离规范化设计都可以为一种类型的查询提供性能提升,但通常以牺牲针对相同数据的所有其他类型的查询为代价.
例如,如果您将玩家及其团队存储为以逗号分隔的列表,则可以非常轻松地获取给定玩家的团队列表,而无需进行连接.这是性能提升.但是获取给定玩家团队的详细信息要困难得多.同样搜索特定团队中的所有玩家.
仅当该列表被视为离散的"黑匣子"数据时,才使用逗号分隔列表.即您的应用程序需要将该列表作为整个项目获取,但从不是列表的子集,并且您永远不需要编写SQL来使用该列表中的元素进行搜索,加入,排序,小计等.
另请参阅我的答案是否将分隔列表存储在数据库列中真的那么糟糕?
| 归档时间: |
|
| 查看次数: |
270 次 |
| 最近记录: |