【发布时间】:2012-01-27 13:03:26
【问题描述】:
我正在进行一个调查项目,正在寻找在关系数据库中跟踪响应数据的最佳方法。假设调查记录了人们最喜欢的食物。稍后我将为新食物(卡路里)添加额外的数据。我相信我认为表格应该是这样的:
人
id | name
==================
1 | John
2 | Suzy
3 | Joe
4 | Laura
5 | Bob
食物
id | food | calories
============================
10 | spaghetti | 950
11 | meatloaf | 850
12 | tofu | 600
13 | cake | 550
选择
**people_food**
------------------
1 | 10
2 | 11
3 | 12
4 | 13
5 | 10
这很好地允许我使用整数来连接表之间的连接——这使得JOINs 的操作速度更快,并且让我不会有重复的数据。我认为不利的一面是,在插入新数据之前,我必须首先在 foods 表上进行 ID 查找,以确保您添加的食物不存在。
这对于一个小型数据库来说已经足够简单了,但是如果我决定询问人们最喜欢的 100 种食物,并且这个调查要发送给成千上万的人呢?即使在 foods 表上有一个索引,这意味着每次我们插入 100 个选项时,我们都需要查询 foods 以获取现有食物的 ID。 (这是否意味着 100 个查询?)我想我可能会这样做:
foreach($response as $food)
{
$food_id = my_mysql_function('select id from foods where food = "spaghetti"');
if( ! $food_id ){
$food_id = my_mysql_function_return_query_id( "insert into foods (NULL, '$food')" );
}
my_mysql_function( "insert into people_foods ($person_id, $food_id)" );
}
我想另一个人会使用食物名称作为食物表的主键并去掉整数,但这似乎是一种不好的做法,不适合重复数据删除,而且还会减慢查询什么我明白了。
问题
对于这样的架构,记录新响应并获取现有食物的 ID 或插入食物的最有效方法是什么?如果我要插入 100 种食物,我通常会这样做:
$existing = my_mysql_function('select id, food from foods where food in ('.implode($response,',').')');
foreach($existing as $food){
my_mysql_function_return_query_id( "insert into people_foods ($person_id, '$food['id']')" );
unset($response[$food]);
}
foreach($response as $food){
//same code as above mentioned earlier in the question
}
或者,是否有另一个表架构更适合做这样的事情?
【问题讨论】:
-
谁能想到他们最喜欢的一百种食物?假设每个人都可以做到这一点。我可以保证大多数人的清单上都会有比萨饼、汉堡包、炸薯条等,所以很多选择可能已经在数据库中。你是如何获得卡路里的?您是否担心响应时间?
-
是的 - 你是对的。但是,无论人们能提出多少最喜欢的食物,我关心的问题的一个方面是如何最好地优化现有数据集上的数据插入以适应这种模式(你可能有大量、无限数量的“选择” )。关于那部分的想法?卡路里用于说明链接数据的用途(因此我们不只是将所有内容存储在平面表中)。最后,响应时间可能还可以,但我真的想知道是否有比做这么多查询和在所有插入之间使用 PHP 操作数据更好的方法。
-
考虑到一些合理的索引,数据库端对于您正在绘制的负载应该可以正常运行。但是,如果没有找到食物,您必须小心锁定食物桌,以免查看食物并将其插入。否则两个会话可能会寻找相同的食物,但没有找到它并尝试插入它。
标签: php mysql database performance database-design