如何将数据与不同数量的值进行比较

时间:2017-08-24 13:47:27

标签: php mysql data-comparison

我会尽力解释我的问题。

我必须比较相同类型的数据,保存在MySql数据库中,但包含不同数量的值。

我像这样构建我的数据库(可能不是最好的):

result = root.findall('Document/Folder')

每次新数据到达时,都会创建一个配置文件,并在必要时创建新标记和新数量。

  • 配置文件具有固定数量的标记(9,16,24)
  • 对于每个配置文件,其每个标记可以包含0,1或2个数量

这意味着个人资料最多可包含48个值。我计划将来在数据库中至少拥有20000个配置文件。

我的目标:如果我选择了一个配置文件,我必须找到所有其他配置文件,这些配置文件的标记的X值至少为1。 (其中X是必须匹配的最小标记数)

目前,我逐一将所有配置文件与测试的配置文件进行比较。这需要一些时间(我目前在数据库中只有大约50个配置文件),这对我的应用程序的未来来说不是一个好的解决方案。

我想到的另一个解决方案是缓存(或保存在数据库中),每个mark_amount关联的所有配置文件ID ......但似乎不是一个好主意:(

我需要一些建议来优化这种比较。 (我对其他数据库开放,缓存系统比php / mysql等...)

EDIT1:个人资料匹配的示例是否与8个标记匹配

  

https://jsfiddle.net/gafy2w4k/

2 个答案:

答案 0 :(得分:2)

返回具有完全 profile_mark.id_profile标记的所有@matched_marks的查询与至少与给定@target_profile_id的个人资料相同的金额:

SELECT `match`.id_profile, count(*) as X FROM (
    SELECT DISTINCT `all`.id_profile, `all`.id_mark FROM profile_mark as `all`
    INNER JOIN profile_mark as `one` 
      ON `one`.id_mark = `all`.id_mark 
      AND `one`.id_amount = `all`.id_amount
    WHERE `all`.id_profile <> @target_profile_id
      AND `one`.id_profile = @target_profile_id
) as `match`
GROUP BY 1
HAVING X = @matched_marks; // can be >= if you need at least X matching marks

作为旁注,id_profile smallint(2)似乎不足以至少20000个配置文件

答案 1 :(得分:0)

问题需要更多详细信息,但我看到一些在这里有用的一般改进: 首先,我没有看到任何索引,请为每个id制作PRIMARY KEY 示例:

CREATE TABLE `mark` (
  `id` tinyint(1) UNSIGNED NOT NULL PRIMARY KEY, 
  ...

如果更改表格为时已晚,请使用CREATE INDEX

其次,为了保持一致,请使REFERENCES声明外键依赖 例如:

FOREIGN KEY (id_mark) REFERENCES mark(id)

最后,对您的查询运行EXPLAIN语句,并根据结果查看可以改进的内容(您可以为经常使用的查询添加索引) EXPLAIN SELECT ...