我喜欢做的是有一些代表原始数据的表,所以在这种情况下你会有
Items (ID pk, Name, <properties>)
Tags (ID pk, Name)
TagItems (TagID fk, ItemID fk)
这在写入时间上工作得很快,并保持一切正常化,但您可能还注意到,对于每个标签,您需要为每个想要 AND 的其他标签连接表两次,因此读取速度很慢。
改进读取的一种解决方案是通过设置一个存储过程来在命令上创建一个缓存表,该存储过程本质上是创建一个以扁平格式表示数据的新表......
CachedTagItems(ID, Name, <properties>, tag1, tag2, ... tagN)
然后,您可以考虑 Tagged Item 表需要多久更新一次,如果每次插入都需要更新,则在游标插入事件中调用存储过程。如果是每小时任务,则设置每小时作业来运行它。
现在要真正聪明地进行数据检索,您需要创建一个存储过程来从标签中获取数据。您不想在大量 case 语句中使用嵌套查询,而是希望传入一个包含要从数据库中选择的标签列表的参数,并返回 Items 的记录集。这将是最好的二进制格式,使用按位运算符。
在二进制格式中,很容易解释。假设有四个标签要分配给一个项目,在二进制中我们可以表示
0000
如果将所有四个标签都分配给一个对象,则该对象将如下所示...
1111
如果只是前两个...
1100
那么这只是在您想要的列中找到具有 1 和 0 的二进制值的情况。使用 SQL Server 的位运算符,您可以使用非常简单的查询来检查第一列中是否有 1。
检查此链接以了解更多信息。