存储倒数数据的规范方式 sql
Canonical way to store reciprocal data sql
我有很多相同的实例 Class。现在这些对象可以被 linked 并且这个 link 可以有一个权重。就像在无向图中一样。现在我想在我的 mysql 数据库中存储每两个对象之间的关系。
数据看起来像这样
a ===WEIGHT=== b
a ===WEIGHT=== c
b ===WEIGHT=== a
...
我可以用这种结构创建一个 table:
object1_id | object2_id | weight
但是在搜索两个物体之间的重量时,我不知道哪个是object1
,哪个是object2
。所以我需要写两个查询。此外,如果我想添加权重并想先检查它是否已经在我的数据库中,我必须编写两个查询以确保它不在其中。
两个查询是:
SELECT weight from tableName where object1_id = AND object2_id = ;
SELECT weight from tableName where object1_id = AND object2_id = ;
确保检查这两种可能性,因为我不知道它是如何存储的。
我想有更好的方法来存储这样的数据。可能已经有很多针对这个特定问题的答案,但我不知道这是怎么称呼的,因此很难找到解决方案。
感谢您的建议。
如果数据中只有一条边,那么可以使用:
select t.*
from t
where (object1_id, object2_id) in ( (, ), (, ) );
如果两条边都在 table 中而您任意想要一个,则添加 limit 1
.
如果你想强制数据库中只有一条边,你可以在表达式上使用唯一索引:
create unique index unq_t_object1_id_object2_id on
t( (least(object1_id, object2_id)), (greatest(object1_id, object2_id)) );
您可能还想添加检查约束,以便它们始终按顺序排列:
alter table t add constraint chk_object1_id_object2_id check (object1_id < object2_id);
强制执行这些条件后,您可以将上述查询更改为:
select t.*
from t
where object1_id = least(, ) and
object2_id = greatest(, );
这样其实优化器更容易优化
我有很多相同的实例 Class。现在这些对象可以被 linked 并且这个 link 可以有一个权重。就像在无向图中一样。现在我想在我的 mysql 数据库中存储每两个对象之间的关系。
数据看起来像这样
a ===WEIGHT=== b
a ===WEIGHT=== c
b ===WEIGHT=== a
...
我可以用这种结构创建一个 table:
object1_id | object2_id | weight
但是在搜索两个物体之间的重量时,我不知道哪个是object1
,哪个是object2
。所以我需要写两个查询。此外,如果我想添加权重并想先检查它是否已经在我的数据库中,我必须编写两个查询以确保它不在其中。
两个查询是:
SELECT weight from tableName where object1_id = AND object2_id = ;
SELECT weight from tableName where object1_id = AND object2_id = ;
确保检查这两种可能性,因为我不知道它是如何存储的。
我想有更好的方法来存储这样的数据。可能已经有很多针对这个特定问题的答案,但我不知道这是怎么称呼的,因此很难找到解决方案。
感谢您的建议。
如果数据中只有一条边,那么可以使用:
select t.*
from t
where (object1_id, object2_id) in ( (, ), (, ) );
如果两条边都在 table 中而您任意想要一个,则添加 limit 1
.
如果你想强制数据库中只有一条边,你可以在表达式上使用唯一索引:
create unique index unq_t_object1_id_object2_id on
t( (least(object1_id, object2_id)), (greatest(object1_id, object2_id)) );
您可能还想添加检查约束,以便它们始终按顺序排列:
alter table t add constraint chk_object1_id_object2_id check (object1_id < object2_id);
强制执行这些条件后,您可以将上述查询更改为:
select t.*
from t
where object1_id = least(, ) and
object2_id = greatest(, );
这样其实优化器更容易优化