数据
假设我有一个网格,代表房间里的所有人以及他们彼此交谈时的对话。
约翰 | 苏珊 | 布莱恩 | 雷切尔 | |
---|---|---|---|---|
约翰 | 放心 | 工作 | 运动的 | 电影 |
苏珊 | 工作 | 咕哝着 | 旅行 | 音乐 |
布莱恩 | 运动的 | 旅行 | 没有什么 | 食物 |
雷切尔 | 电影 | 音乐 | 食物 | 自嘲 |
数据库
最初我考虑只制作一个常规表格People
和Conversations
桌子Conversations
是一把钥匙,topic
participant1
participant2
困境
参与者的顺序完全无关。一个简单的问题“Rachel 和 Brian 谈论什么”变成了一个需要运行的复杂查询。
因此必须做以下两件事之一:
- 冗余数据添加到数据库中:(Rachel 和 Brian)或(Brian 和 Rachel)
- 查询非冗余数据需要一个极其复杂的查询,因为您不知道 Rachel 是参与者1还是参与者2。
采用上面的 1 会创建一个不可持续的 O(n^2) 数据库模型,而 2 似乎是 DBA 试图查询有意义的数据的噩梦。
问题
如何对这样的数据结构进行建模?SQL 是否是适合这项工作的工具,还是我应该完全研究其他东西?
数据
将相同的参与者组合存储两次是一个严重的标准化错误,不应被视为一种选择。唯一的数据位于相应的三角矩阵之一中,例如:
数据库
数据库应该强制执行必要的约束。
查询
假设您不能仅使用 Participant1 和 Participant2 的有序对构造 WHERE 子句,则查询上表类似于:
我不明白事情怎么会变得如此复杂。
风景
您始终有可能获得包含所有排列的数据的非标准化视图。
“多对多”关系通常使用具有指向各个实体的外键的“联结”(或“链接”)表来建模。
在您的例子中,您将有一个Person表、一个Conversation表和一个具有两个属性的PersonConversations表:
ConversationId
和PersonId
。话虽如此,该任务也可以通过图来建模,并使用图数据库来实现,这可能更自然。