在我的数据库中的所有表中,我有两个目前有Many-to-Many
个连接。但是,实际捕获的数据几乎总是具有One-to-Many
关联。
考虑到我希望数据库查找(学说查询)尽可能不受阻碍,我应该改为:
text
/ tinyblob
)以记录2个(或技术上甚至3个)关联记录的迷你数组?这就是我目前所拥有的(虽然TableB-> JoinTable通常只是一对一):
TableA.id --< a_id.JoinTable.b_id >-- TableB.id
所以,我希望看看我是否可以捕捉'例外'。以下是正确的方法吗?
TableA.id TableB.id
+----< TableB.A_id1
+----- TableB.A_id2
+----- TableB.A_id3
答案 0 :(得分:1)
更改关联的数据类型(例如更改为text / tinyblob)?
请不要这样做。如果你这样做,那么维护数据库的人就会把你的名字诅咒到千代。不开玩笑。
这里最好的选择是建立一对多的关联。我们假设您的表a
有一个整数主键a_id
。
然后,将a_id
作为外键列放在第二个表b
中。
您可以按如下方式检索您的信息。对于a
中的每一行,这总是会在结果集中为您提供一行。
SELECT a.this, a.that, GROUP_CONCAT(b.value) value
FROM a
LEFT JOIN b ON a.a_id = b.a_id
GROUP BY a.this, a.that
如果你不介意为百万分之一的情况增加额外的行,那就更容易了。
SELECT a.this, a.that, b.value
FROM a
LEFT JOIN b ON a.a_id = b.a_id
LEFT JOIN
操作允许您的a
行没有相应的b
行。
在b.a_id
上添加索引。
答案 1 :(得分:1)
您似乎对以下内容感兴趣:
-- a and b are related by the association of interest
Foo(a, b)
-- foo(a, b) but not foo(a2, b) for some a2 <> a
Boring(a, b)
unique(b)
FK (a, b) references Foo
-- foo(a, b) and foo(a2, b) for some a2 <> a
Rare(a, b)
FK (a, b) references foo
如果您希望查询不受阻碍,只需定义Foo即可。您可以查询稀有。
Rare = select * from Foo f join Foo f2
where f.a <> f2.a and f.b = f2.b
任何其他设计都会因更新复杂性而使数据库保持一致。
你有一些模糊的担心,稀有比Foo小得多。但是你的要求只有百万Foo记录中有多少:很多你会选择其他设计吗?
下一个复杂程度是拥有Foo和Rare。更新必须保持上述等式。
似乎极不可能通过仅使用Boring + Rare并从中重建Foo来减少Foo + Rare的2或3百万个冗余。但是为Boring定义一个唯一的索引(b)可能是有益的,它将保持其中的b只有一个a。当你需要Foo:
Foo = select * from Boring union select * from Rare
但是您的更新必须保持
not exists (select * from Boring b join Rare r where b.b = r.b)