我的数据库中有一个表,表示两件事之间的相似性。有点像:
+------------+------+
| Field | Type |
+------------+------+
| id_a | int |
| id_b | int |
| similarity | ??? |
+------------+------+
similarity
将保持id_a
和id_b
之间的相似度百分比,范围可以从100%相似(相同的事物)到但不包括 0%。我不会存储0%相似(即完全不同)的东西的链接。换句话说,我需要存储范围[100, 0)
。小数位数并不是非常重要,但1或2会很好。
我通常看到的建议是使用decimal(4,2)
之类的解决方案。我的用例的问题在于它存储(100,0]
。
我提出了两种可能的解决方案,都使用decimal(4,2)
,但它们看起来都像黑客一样:
存储similarity - 0.01
并在检索时添加0.01
。类似的东西:
INSERT INTO similarities (id_a, id_b, similarity) VALUES (1, 2, ? - 0.01);
然后:
SELECT id_a, id_b, similarity + 0.01 FROM similarities;
存储百分比差异从0%-99.99%,然后在检索时转换为相似度:
SELECT id_a, id_b, 100 - difference AS similarity FROM similarities;
在这两种情况下,我可能会使用MERGE
创建一个视图,而不是在查询中保留加法和减法。
有没有比这更好的选择?如果没有,你会选择哪个以及为什么?
[1,0)
,只要它能很好地代表范围。
答案 0 :(得分:1)
在符合SQL标准的dbms中,您将声明该列为decimal(5,2)类型(或使用等效小数),并使用CHECK约束来限制范围。
create table data (
id integer primary key,
pct decimal(5, 2) not null check (pct > 0 and pct <= 100)
);
但MySQL不符合SQL标准。它不强制执行CHECK约束。所以我认为你有两个选择。
如果我需要在进一步的计算中使用百分比,我更喜欢在.0001到1.0000范围内的值,因此可以直接使用它们。但是,在您的应用程序中,这看起来并不像是一个问题。
答案 1 :(得分:0)
不是将相似度指定为百分比,而是按照[1,10000]
(或(0,10000]
,如果您愿意)给出相似度得分。这样每个百分点可以得到100分(如果需要,可以有效地提高两位小数)。
存储:int(32)
查看:SELECT id_a, id_b, similarity/100 FROM similarities;