MySQL 1:N 数据映射

MySQL 1:N Data Mapping

有些东西真的让我很烦恼,我不确定 "correct" 方法是什么。 如果我创建 select 从我的数据库中获取联系人,则涉及相当数量的连接。

它看起来像这样(大约 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 基数,所以很简单。 但是 "address"、"communication" 和 "categories" 是 1:n 基数。

所以根据 1:n table 中的行数,我会得到很多 "double" 行(我不知道真正的术语是什么,行不是双行我知道地址或 phone 数字等是不同的)。对于我自己作为一个联系人,一个相当完整的联系人,我得到了 85 行。

你们是如何使用它的? 在我的 PHP 应用程序中,我总是写一些 "Data-Mapper",其中数组键是 "contact.ID aka primary",然后检查它是否存在,然后将其他数据推送到其中。另外 PHP 并不是真正的类型严格,这使得它变得容易。

现在我正在学习 GO(golang),我认为太糟糕了 select 和数据映射只是为所有 1:n 编写 selects...是的,不,没有足够的连接来加载 table 个完整的联系人。我知道我可以增加连接,但错误似乎暗示这是错误的方式。 我使用以下驱动程序:https://github.com/go-sql-driver/mysql

我也试过 GROUP_CONCAT 但后来我 运行 无法解析它。

我是否必须再次执行我的映射方法,或者是否有一些不错的解决方案?我发现它有些地方很脏?

解决方法很简单:您需要执行多个查询!

所有 "duplicate" 行的原因是您生成了一个名为 Cartesian product 的结果。您正在尝试连接到具有 1:n 关系的多个表,但其中每个表彼此之间没有任何关系,因此没有连接条件限制它们彼此之间的关系。

因此,所有 1:n 关系的每个组合都会得到一个结果。如果您在 address 中有 3 个匹配项,在 communication 中有 5 个匹配项,在 categories 中有 5 个匹配项,您将得到 3x5x5 = 75 行。

因此您需要 运行 为每个 1:n 关系单独 SQL 查询。不要害怕——MySQL 可以处理一些查询。你需要它们。