Php MySQL大型关系查询
我有几张桌子: 信件(邮件)Php MySQL大型关系查询,php,mysql,sql,json,Php,Mysql,Sql,Json,我有几张桌子: 信件(邮件) index sent from to template public stamp stationery title content opened index username password 字母用户 index sent from to template public stamp stationery title conte
index
sent
from
to
template
public
stamp
stationery
title
content
opened
index
username
password
字母用户
index
sent
from
to
template
public
stamp
stationery
title
content
opened
index
username
password
除了索引、public和opened之外,letter_mail中的所有行都与另一个表相关
信函中的“发件人”和“收件人”对应于信函用户的索引。我想要的是从数据库中提取所有数据,如果可能,最好是在一个查询中。在信件
行中选择*将产生如下结果:
index:1
sent: 2013-10-03
from:1
to:2
template:1
public:1
stamp:1
stationery:1
title: 1
content: 1
opened : 0
index:1
sent: 2013-10-03
from: {1, John}
to: {2, Jane}
template: {index: 1, template: "standard template", url: "template_name"}
public: 0
stamp: {index: 1, stamp: "standard stamp", url: "some/url"}
stationery: {index: 1, stamp: "standard stationery", url: "some/url"}
title: {index: 1, title: "some title"}
content: {index: 1, content: "some text content"}
opened : 0
select
sent, from.username, to.username, template_table.name, template_table.url, public,
stamp_table.stamp, stamp_table.url, stationary_table.stamp, stationary_table.url, title_table.title,
content_table.content, opened
from
letter_mail l,
letter_user from,
letter_user to,
template template_table,
stamp stamp_table,
stationairy stationary_table,
title title_table,
content content_table
where
l.from = from.idex
and l.to = to.index
and template = template_table.index
and stamp = stamp_table.index
and stationairy = stationary_table.index
and title = title_table.index
and content = content_table.index
where l.index = X
我需要的是用相关表格中的数据填充上述信息,并对其进行JSON
编码。看起来有点像这样:
index:1
sent: 2013-10-03
from:1
to:2
template:1
public:1
stamp:1
stationery:1
title: 1
content: 1
opened : 0
index:1
sent: 2013-10-03
from: {1, John}
to: {2, Jane}
template: {index: 1, template: "standard template", url: "template_name"}
public: 0
stamp: {index: 1, stamp: "standard stamp", url: "some/url"}
stationery: {index: 1, stamp: "standard stationery", url: "some/url"}
title: {index: 1, title: "some title"}
content: {index: 1, content: "some text content"}
opened : 0
select
sent, from.username, to.username, template_table.name, template_table.url, public,
stamp_table.stamp, stamp_table.url, stationary_table.stamp, stationary_table.url, title_table.title,
content_table.content, opened
from
letter_mail l,
letter_user from,
letter_user to,
template template_table,
stamp stamp_table,
stationairy stationary_table,
title title_table,
content content_table
where
l.from = from.idex
and l.to = to.index
and template = template_table.index
and stamp = stamp_table.index
and stationairy = stationary_table.index
and title = title_table.index
and content = content_table.index
where l.index = X
这完全疯了吗?我应该把查询分成几个部分,还是把所有内容都整理成一个表
如果您需要更多信息,请告知:)
解决方案如下所示:
select
mail.index,
mail.sent,
mail.opened,
mail.public,
FromU.username as FromUser,
ToU.username as ToUser,
T.template as TemplateName,
T.url as TemplateURL,
S.stamp,
S.url as StampURL,
S.stamp Stamp,
STA.url StationaryURL,
Ttl.title,
C.content
from
letter_mail mail
JOIN letter_user FromU
on mail.from = FromU.index
JOIN letter_user ToU
on mail.to = ToU.index
JOIN letter_templates T
on mail.template = T.index
JOIN letter_stamps S
on mail.stamp = S.index
JOIN letter_stationery STA
on mail.stationery = STA.index
JOIN letter_title Ttl
on mail.title = Ttl.index
JOIN letter_content C
on mail.content = C.index
查询可以工作,但不返回任何行。简而言之,您可以使用表别名多次联接同一个表。我对其他相关的表名做了一些假设,但基本上最终得到的查询如下所示:
index:1
sent: 2013-10-03
from:1
to:2
template:1
public:1
stamp:1
stationery:1
title: 1
content: 1
opened : 0
index:1
sent: 2013-10-03
from: {1, John}
to: {2, Jane}
template: {index: 1, template: "standard template", url: "template_name"}
public: 0
stamp: {index: 1, stamp: "standard stamp", url: "some/url"}
stationery: {index: 1, stamp: "standard stationery", url: "some/url"}
title: {index: 1, title: "some title"}
content: {index: 1, content: "some text content"}
opened : 0
select
sent, from.username, to.username, template_table.name, template_table.url, public,
stamp_table.stamp, stamp_table.url, stationary_table.stamp, stationary_table.url, title_table.title,
content_table.content, opened
from
letter_mail l,
letter_user from,
letter_user to,
template template_table,
stamp stamp_table,
stationairy stationary_table,
title title_table,
content content_table
where
l.from = from.idex
and l.to = to.index
and template = template_table.index
and stamp = stamp_table.index
and stationairy = stationary_table.index
and title = title_table.index
and content = content_table.index
where l.index = X
您将遇到的主要问题是,这将导致多次扫描letter_用户表。。。。这可能是可以避免的,但如果这个数据库有任何实际的重要大小,您应该记住这一点
这样做的好处是,与整理多个db调用不同,您可以让db完成其设计的工作,并且只对数据库进行一次调用
当然,这个查询可以重新处理一点,专门使用连接。。。但对我来说,这种形式更容易阅读和理解,假设你只想要严格相关的记录。
如DMCNELIS所指出的,你可以考虑使用连接(更大的语法,而不是更大的ANSI格式的列表和应用标准)。这是他使用连接语法的版本。。我还改为在表上使用更短的别名引用。请注意,JOIN/ON准确地显示了tableX与tableY的关系,而不是隐藏在WHERE子句中。如果OOps忘记where子句,这有时会导致问题和笛卡尔结果。通过加入,您将立即看到您的关系标准
select
L.sent,
FromU.username as FromUser,
ToU.username as ToUser,
T.name as TemplateName,
T.url as TemplateURL,
L.public,
S.stamp,
S.url as StampURL,
STA.stamp StationaryStamp,
STA.url StationaryURL,
title.title,
C.content,
L.opened
from
letter_mail L
JOIN letter_user FromU
on L.from = FromU.index
JOIN letter_user ToU
on L.to = ToU.index
JOIN template T
on L.Template = T.index
JOIN stamp S
on L.Stamp = S.index
JOIN stationary STA
on L.Stationary = STA.index
JOIN title
on L.title = title.index
JOIN content C
on L.Content = C.index
既然所有的表都是相关的,那么运行查询,它就会得到所需的一切。但是,如果您要查找某一组标准的内容,只需添加WHERE子句。。。比如
WHERE
L.From = 27
OR L.To = 27
获取任何发送至或来自用户27的电子邮件
如果您只需要特定的文具、图章、标题等,只需根据需要添加即可。这并不疯狂-尽管您最终会得到大量重复数据,在一个查询中一次获取所有数据。这是否是一个好主意取决于数据的数量以及从Web服务器到数据库的接近程度/连接。我只是想避免9个select查询,但如果这是需要的话……是的。我可以将查询中的所有数据存储在主表中,但这也会在查询一件事情时增加开销。还有,如果人们投了票,请告诉我为什么:不是我——有些人只是把他们认为基本的问题记下来。不要将所有数据放在一个表中,除非它应该放在一个表中,否则应避免数据重复,并且数据重复是关系数据库的主要点。您应该只需要两个查询,尽管每个表一个查询。链接可以在PHP中完成。这有意义吗?或者我应该重组DB吗?我看你是怎么把事情搞糟的没有什么错。。。在数据库中有许多查找表是很常见的。想想看,如果你有100000条记录,并且不得不重复固定类型“标准固定”与内部ID 8。那你拼写错了?在查找表中进行修复,您就完成了。你的上下文看起来不错,很有效!非常感谢。我已经用你的答案更新了这个问题,并用投票数奖励任何获得这个答案的人。@Eirinn,更大的元素。。。您现在看到了连接与来自/来自组合的相关性了吗,如dmcnelis所示,两者都是有效的,但是连接在实际查询中更为活跃。嗯,这是为了防止多次扫描表?