mysql-存储带有很​​多类别标记的项目-位掩码?

mysql-存储带有很​​多类别标记的项目-位掩码?,第1张

概述也许解决方案很明显,但是我似乎找不到一个好的解决方案.在我即将进行的项目中,将有一个主表,其数据将被频繁读取.更新/插入/删除速度不是问题.该主表中的项目与4个或更多类别相关联.一个项目在一个类别中可以有50-100个或更多的关系.将在数据库上执行的最常见的 *** 作:>选择所有已分配给类别A,B,C,...且LIMIT X,Y的项目>计算已分配给类别

也许解决方案很明显,但是我似乎找不到一个好的解决方案.

在我即将进行的项目中,将有一个主表,其数据将被频繁读取.更新/插入/删除速度不是问题.

该主表中的项目与4个或更多类别相关联.一个项目在一个类别中可以有50-100个或更多的关系.

将在数据库上执行的最常见的 *** 作:

>选择所有已分配给类别A,B,C,…且liMIT X,Y的项目
>计算已分配给类别A,…的所有项目

我对如何为上述数据库创建数据库的最初想法是这样的(我猜是经典方法):

首先,为四个类别中的每个类别创建一个类别表:

ID   - PK,int(11),index   name - varchar(100)

那么我将有一个项目表:

ID   - PK,index... some more data fIElds,about 30 or so ...

并关联类别表,将有4个或更多查找/ MM表,如下所示:

ID_item     - int(11)ID_category - int(11)

查询看起来像这样:

selectitem.*fromiteminner mm_1 on mm_1.ID_item = item.IDinner join cat_1 on cat_1.ID = mm_1.ID_category and cat_1.ID in (1,2,...,100)inner mm_2 on mm_2.ID_item = item.IDinner join cat_2 on cat_2.ID = mm_2.ID_category and cat_2.ID in (50,51,90)

当然,使用MM表的上述方法是可行的,但是由于该应用程序应提供非常好的SELECT性能,因此我使用了真实的数据量(项目表中有100.000条记录,每个类别中有50-80条关系)对它进行了测试,即使有索引,也没有我预期的快.选择时,我还尝试使用WHERE EXISTS代替INNER JOIN.

我的第二个想法是仅使用上面的项目表对数据进行非规范化.

阅读有关使用位掩码的this blog post之后,我尝试了一下,并为每个类别分配了一个位值:

category 1.1 - 1category 1.2 - 2category 1.3 - 4category 1.4 - 8... etc ...

因此,如果一个项目被标记为类别1.1和类别1.3,则它的位掩码为5,然后将其存储在字段item.bitmask中,我可以像这样查询它:

select count(*) from item where item.bitmask & 5 = 5

但是性能也不是很好.

这种位屏蔽方法的问题:当涉及到位运算符时,即使item.bitmask的类型为BIGINT,MysqL也不使用任何索引.我最多只能处理64个关系,但每个类别最多需要支持100个关系.

就是这样.我想不出什么了,除了可能污染很多项目表外,例如category_1_1到category_4_100,每个字段都包含1或0.但这可能会导致select的WHERE子句中出现许多AND且似乎没有也是个好主意.

那么,我有什么选择呢?还有更好的主意吗?

编辑:作为对Cory Petosky的回应,““一个项目在一个类别内可以具有50-100或更多的关系.”是什么意思?“:

为了更加具体,项目表表示图像.图像是按情绪分类的其他标准之一(情绪将是4个类别之一).所以它看起来像这样:

Image:     - category "mood":         - bright         - happy         - funny         - ... 50 or so more ...     - category "XYZ":         - ... 70 or so more ...

如果我的图像表是C#中的类,它将看起来像这样:

public class Image {    public List<Mood> Moods; // can contain 0 - 100 items    public List<Some> Somecategory; // can contain 0 - 100 items    // ...}
最佳答案怎么样(伪代码):

Item (image)    ID         PK,int(11)    name       varchar(100)category (mood,xyz)    ID         PK,int(11)    name       varchar(100)Relations (happy,funny)    ID         PK,int(11)    name       varchar(100)ItemCategorIEs    ID         PK,int(11)    ItemID     FK,int(11)    categoryID FK,int(11)ItemcategoryRelations    ItemCategorIEsID FK,int(11)    RelationID       FK,int(11)SELECT *  FROM Item   JOIN ItemCategorIEs ON Item.ID = ItemCategorIEs.ItemID WHERE ItemCategorIEs.categoryID IN (1,10)

以下版本使用少了一张表,但不支持没有关系的类别,并且关系无法重用.因此,如果符合您的数据结构要求,则它才有效:

Item (image)    ID         PK,int(11)    name       varchar(100)ItemRelations     ItemID     FK,int(11)    RelationID FK,int(11)SELECT *  FROM Item   JOIN ItemRelations ON Item.ID = ItemRelations.ItemID  JOIN Relations ON Relations.ID = ItemRelations.RelationsID WHERE Relations.categoryID IN (1,10)
总结

以上是内存溢出为你收集整理的mysql-存储带有很​​多类别标记的项目-位掩码? 全部内容,希望文章能够帮你解决mysql-存储带有很​​多类别标记的项目-位掩码? 所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1165516.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-01
下一篇 2022-06-01

发表评论

登录后才能评论

评论列表(0条)

保存