在MySQL中表示百分比高达100%

时间:2013-02-08 13:47:23

标签: mysql percentage

我的数据库中有一个表,表示两件事之间的相似性。有点像:

+------------+------+
| Field      | Type |
+------------+------+
| id_a       | int  |
| id_b       | int  |
| similarity | ???  |
+------------+------+

similarity将保持id_aid_b之间的相似度百分比,范围可以从100%相似(相同的事物)到但不包括 0%。我不会存储0%相似(即完全不同)的东西的链接。换句话说,我需要存储范围[100, 0)。小数位数并不是非常重要,但1或2会很好。

我通常看到的建议是使用decimal(4,2)之类的解决方案。我的用例的问题在于它存储(100,0]

我提出了两种可能的解决方案,都使用decimal(4,2),但它们看起来都像黑客一样:

选项1

存储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;

选项2

存储百分比差异从0%-99.99%,然后在检索时转换为相似度:

SELECT id_a, id_b, 100 - difference AS similarity FROM similarities;

在这两种情况下,我可能会使用MERGE创建一个视图,而不是在查询中保留加法和减法。

有没有比这更好的选择?如果没有,你会选择哪个以及为什么?

注意:

我不介意使用其他表示法,例如[1,0),只要它能很好地代表范围。

编辑以澄清:

插入很少完成,只能由我完成,而不是由用户完成,并且是大批量完成的。我知道我插入的数据总是在[100,0]中,所以这不是强制执行的问题,而是最有效/最自然的表示是什么

2 个答案:

答案 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约束。所以我认为你有两个选择。

  1. 编写触发器以检查范围,并回滚插入和更新 超出你选择的范围。
  2. 使用对有效值表的外键引用。在你的 case,那个表只有10,000行,对吧?
  3. 如果我需要在进一步的计算中使用百分比,我更喜欢在.0001到1.0000范围内的值,因此可以直接使用它们。但是,在您的应用程序中,这看起来并不像是一个问题。

答案 1 :(得分:0)

不是将相似度指定为百分比,而是按照[1,10000](或(0,10000],如果您愿意)给出相似度得分。这样每个百分点可以得到100分(如果需要,可以有效地提高两位小数)。

存储:int(32)

查看:SELECT id_a, id_b, similarity/100 FROM similarities;