Mysql 具有反向查找的多对多关系

Mysql 具有反向查找的多对多关系,mysql,sql,many-to-many,Mysql,Sql,Many To Many,MySQL版本5.5.35-log 我有一个非常大的数据集,其中包括一个多对多的关系,这与人们在商店购物密切相关。一个人可以在数百个不同的商店购物,同样,成千上万的人可以在任何特定的商店购物。总的人数和门店数量都达到了数百万 我有一种情况,检查一个人是否在某个特定的商店购物必须迅速解决,所以我选择使用反向查找;i、 e.每个“人员”行存储他们购物所在商店的ID列表。由于数据量,第三个关系表被认为是不合适的;i、 e.每个人都有一行的插座。我在这里的假设是,它别无选择,只能通过许多行生成表扫描 然

MySQL版本5.5.35-log

我有一个非常大的数据集,其中包括一个多对多的关系,这与人们在商店购物密切相关。一个人可以在数百个不同的商店购物,同样,成千上万的人可以在任何特定的商店购物。总的人数和门店数量都达到了数百万

我有一种情况,检查一个人是否在某个特定的商店购物必须迅速解决,所以我选择使用反向查找;i、 e.每个“人员”行存储他们购物所在商店的ID列表。由于数据量,第三个关系表被认为是不合适的;i、 e.每个人都有一行的插座。我在这里的假设是,它别无选择,只能通过许多行生成表扫描

然而,要在MySQL中存储此反向查找,SET也不合适,因为它最多有64个条目,这在这种情况下当然是不够的。因此,我选择了一个BLOB,它的结构只是一个包含每个4字节小endian ID的块

但是,这里出现了一个不同的问题;当使用SQL查找BLOB中是否包含插座ID时,异常情况开始出现。从其他问题来看,似乎唯一的方法是在循环中使用带有BLOB的子字符串,但是这似乎不起作用;子字符串正在返回一个空字符串。首先,这里有一些代码:

CREATE FUNCTION `DoesShopAt`(shopperID INT UNSIGNED,outletID TINYBLOB) RETURNS VARCHAR(20)
BEGIN

-- Setup a loop. We're going to loop through each ID in the blob:
declare i_max int unsigned default 0;
declare i int unsigned default 0;
declare offset int unsigned default 0;
declare storeID tinyblob;

-- Setup the blob store - all the stops a particular shopper goes to:
declare allShops blob;

-- Grab the set of ID's - a blob of each 4 byte outlet ID:
select AllStores from Shoppers where ID=shopperID into allShops;

-- How many shops?
select length(allShops)/4 into i_max;

while i < i_max do

    -- Grab the shops ID:
    set storeID=substring(allShops,offset,4);

    if outletID = storeID then
        return "Yep, they do!";
    end if;

    -- Update the ID offset in the blob:
    set offset=offset+4;

    -- Update the loop counter:
    set i=i+1;
end while;

return "Nope, they don't.";
END
确保这次偏移计数器增加8,并调整输入ID以适应。尽管allShops数据不是零,但它仍然返回一个空字符串(设置后立即返回storeID)


编辑:虽然我发现了这个问题,但我还是忍不住想,也许在MySQL中有更好的方法来反向查找这样的内容;你有什么建议吗?

我开始玩弄substring,并意识到了问题所在;偏移量应为1时被初始化为0。更改此选项,然后开始正确返回结果:

declare offset int unsigned default 0;
应该是:

declare offset int unsigned default 1;

但是,请看原始问题底部的注释。

很难相信,创建这样的函数比在具有适当索引的适当关系表上创建索引要快;它的行数很容易扩展到数十亿,这意味着平均要检查几百个条目。我个人对改进的想法是,通过对反向查找进行排序,并进行二进制搜索,而不是顺序搜索,从而提高上述速度;收到的另一个建议是,也可能使用bloom过滤器作为预检查阶段,但是这两个阶段仍然使用相同的blob查找。
declare offset int unsigned default 1;