有些事情真的让我很困扰,我不确定什么是“正确的”方法。
如果我选择从数据库中获取联系人,则会涉及到相当多的连接。
它看起来像这样(大约60-70列):
SELECT *
FROM contacts
LEFT JOIN company
LEFT JOIN person
LEFT JOIN address
LEFT JOIN person_communication
LEFT JOIN company_communication
LEFT JOIN categories
LEFT JOIN notes
公司和个人是1:1的基数,所以它是直截了当的。
但“地址”、“通信”和“类别”是1:n基数。
因此,根据1:n表中的行数,我将得到很多“double”行(我不知道真正的术语是什么,这些行不是double,我知道地址或电话号码等是不同的)。作为一个联系人,一个相当充实的联系人,我得到了85行。
你们是怎么处理的?
在我的PHP应用程序中,我总是写一些“数据映射器”,其中数组密钥是“CONTACT.ID-AKA PROCEL”,然后检查它是否存在,然后将附加数据推送到它中。另外,PHP并不是真正严格的类型,因为它很容易实现。
现在我正在学习GO(golang),我认为looong select和data mapping只是为所有的1:n编写select。。。。是的,不,没有足够的连接来加载满桌的联系人。我知道我可以增加连接,但这个错误似乎意味着这是错误的方式。
我使用以下驱动程序:https://github.com/go-sql-driver/mysql
我也试过GROUP_CONCAT,但在解析它时遇到了问题。
我需要重新做我的映射方法还是有一些好的解决方案?我发现它很脏,对吧?
最佳答案
解决方案很简单:您需要执行多个查询!
所有“重复”行的原因是您正在生成一个名为aCartesian product的结果。您正试图连接到几个具有1:n关系的表,但是这些表中的每一个都与另一个表没有关系,因此没有连接条件限制它们之间的关系。
因此,所有1:n关系的每个组合都会得到一个结果。如果您在address
中有3个匹配项,在communication
中有5个匹配项,在categories
中有5个匹配项,那么您将得到3x5x5=75行。
因此,您需要为每个1:n关系运行单独的SQL查询。不要害怕MySQL可以处理一些查询。你需要他们。