我正在建立一个小型的内部电话号码扩展名单。
在数据库中,我有两个表,一个people
表和一个numbers
表。该关系分别为one-to-many
。
我想在单个HTML表格中显示结果,每行一个人,但如果它们有多个数字,则会在单个列中显示这些结果,并在人员行上设置行数来补偿。
现在,为了从数据库中获取结果,我可以这样做:
(pseudocode)
SELECT id, name
FROM people
foreach result as row {
SELECT number
FROM numbers
WHERE numbers.person_id = row['id']
}
这意味着我正在进行一次查询以获取所有用户,但如果我有100个用户,我会执行100个额外查询来获取每个用户的数字。
相反,我可以这样做:
(pseudocode)
SELECT number, person_id
FROM numbers
SELECT id, name
FROM people
foreach people as person {
echo name
foreach numbers as number {
if (number.id = person.id) {
echo number
}
}
}
所以,基本上它做的完全相同,除了我做两个查询将所有结果都放到数组中然后循环遍历数组以格式化我的表。
我应该使用哪种方法,还是有更好的方法?
答案 0 :(得分:4)
常见的方法是定期加入:
SELECT id, name, number
FROM people, numbers
WHERE people.id = numbers.person_id;
您可以添加ORDER BY
以按顺序获取数字,也可以创建一个数组,只需对结果集进行一次传递,然后循环遍历该数组。
您还可以考虑使用GROUP_CONCAT来连接同一个人的所有数字:
SELECT id, name, GROUP_CONCAT(number SEPARATOR ', ')
FROM people, numbers
WHERE people.id = numbers.person_id
GROUP BY people.id;
因为你甚至在问这个问题:我不能强调你应该拿起关于数据库设计的入门书的事实。它帮助我学习了关系数据库背后的理论。
答案 1 :(得分:4)
您可能想要执行一个查询。像
这样的东西select people.id, people.name, group_concat(numbers.number)
from people
inner join numbers on numbers.id = people.id
group by people.id, people.name
order by people.name
然后你可以用简单的PHP代码循环遍历结果集。
答案 2 :(得分:1)
这取决于你,你可能需要时间来找出答案。如果您的数据库与Web服务器位于不同的计算机上,则执行多个查询会导致很多网络转换,因此通常需要更长时间。但是,如果您的数据库服务器与Web服务器位于同一台计算机上,则可能不是问题。
还要考虑查找数组中的数字所需的时间。作为一个数组,您正在进行线性顺序O(N)搜索。如果你可以把它放在一个哈希中,那么查找速度会快得多,而且两种查询方法可能会更快,但如果你花费大量时间在数组中查找答案则不会。
使用连接将其连接到一个查询中可能是最快的,因为数字将与人员关联,具体取决于您将数据存储到foreach循环中的容器结构。
答案 3 :(得分:0)
使用存储过程或函数检索数据,不要在程序中编写sql
答案 4 :(得分:0)
你不应该这样做。您可以对表进行一个查询(加入):
select name, number
from people p, numbers n
where p.id = n.person_id
order by name, number;
然后只是一个循环:
$link = mysqli_connect(...);
$query = 'select name, number from people p, numbers n where p.id = n.person_id order by name, number';
if ($result = mysqli_query($link, $query)) {
$person = '';
while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
if ($row['name'] !== $person) {
$person = $row['name'];
echo $person;
}
echo $row['number'];
}
}