Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 是否有一个公认的理想标记模式_Sql_Schema_Tagging - Fatal编程技术网

Sql 是否有一个公认的理想标记模式

Sql 是否有一个公认的理想标记模式,sql,schema,tagging,Sql,Schema,Tagging,我有一个照片网站,我想支持标签,因为我原来的分类扣开始失败(一些照片是家庭和假期,或学校和朋友)。是否有一个商定的标记数据库模式 我仍然希望支持将照片作为相册的一部分 现在我有几张桌子: 照片 类光 相册 标题 日期 相册 白蛋白 专辑名 相册日期 有各种有效的模式,随着标记项数量的增加,每种模式都会对您需要的常见查询产生各自的性能影响: 就我个人而言,我喜欢有一个标记表和一个链接表,它将标记与项目相关联,因为它是非规范化的(没有重复的标记名),并且我可以在必要时在链接表中存储额外

我有一个照片网站,我想支持标签,因为我原来的分类扣开始失败(一些照片是家庭和假期,或学校和朋友)。是否有一个商定的标记数据库模式

我仍然希望支持将照片作为相册的一部分

现在我有几张桌子:

照片

  • 类光
  • 相册
  • 标题
  • 日期
相册

  • 白蛋白
  • 专辑名
  • 相册日期

有各种有效的模式,随着标记项数量的增加,每种模式都会对您需要的常见查询产生各自的性能影响:

就我个人而言,我喜欢有一个标记表和一个链接表,它将标记与项目相关联,因为它是非规范化的(没有重复的标记名),并且我可以在必要时在链接表中存储额外的信息(例如项目被标记的时间)


如果您感到兴奋并希望简单地进行选择,您还可以添加一些非规范化的数据,代价是在标记表中存储使用计数所需的额外数据维护,或者存储项目表本身中使用的标记名,以避免点击每个项目的链接表和标记表,这对于显示多个项目及其所有标记以及简单的标记版本控制非常有用。。。如果你对这类事情感兴趣;)

我想到了这样一件事:把那两张桌子加起来

标签

  • 塔吉德
  • 标记名
  • 标记说明
照片标签

  • 类光
  • 塔吉德

您也可以将其扩展到相册,在相册和标签之间有一个交集表。

我建议看看现有的开源软件是如何做到这一点的。例如,它像您一样将元数据存储在数据库中,并且非常丰富


不过,我认为您不会找到“标准”模式。我能想到的最接近的东西是EXIF元数据格式,它嵌入在图像文件本身中(通过相机等)。

如果您想要数百万条记录的真实性能,您可以将标记存储在一个字段中,以逗号分隔,并使用全文索引/搜索守护程序(如sphinxsearch)检索记录。您只需添加一个表,其中列出了所有标记,并带有一个计数值,以了解它们附加到项目的频率

我知道这不是通常的方法,而且比纯数据库解决方案要复杂一些,但是搜索标签相关的项目确实非常快

您也可以使用数据库引擎的全文搜索功能,但当有大量记录时,大多数引擎往往速度较慢


如果是一个小项目,你可以按照自己的方式去做,这是一个好的和正确的方式去做。但我想和你们分享另一个解决方案。你觉得怎么样?

我在一个没有很多用户的小系统中完成了这项工作,但我以前想知道是否有一种“公认”的方式来管理标签。在阅读了insin发布的链接和大量其他关于标签的博客文章后,似乎人们接受的方法是将其完全规范化存储,并在数据集过大时缓存某些内容

因为它是一个多个关系(每个标记可以属于任意数量的照片-每个照片可以有许多标记),关系数据库理论让您创建一个照片表、一个标记表和一个交叉引用表来链接它们

photos
  photoid
  caption
  filename
  date

tags
  tagid
  tagname

phototags
  photoid
  tagid
这在从非常大的数据集中进行选择时存在缩放问题,但所有不太规范化的模式也是如此(例如,通过文本字段进行排序和过滤可能总是比使用整数慢)。如果你长得像delicious一样大,甚至可能是StackOverflow,你可能需要对你的标记集进行一些缓存

您必须面对的另一个问题是标记规范化问题。这与数据库规范化无关——它只是确保(例如)“StackOverflow”、“StackOverflow”和“stack overflow”标记是相同的。很多地方不允许空白或自动删除空白。有时你会看到标点符号的相同之处——使“StackOverflow”与“StackOverflow”相同。自动小写是相当标准的。您甚至会看到特例规范化,比如将“c#”与“csharp”相同


快乐标签

在我的应用程序BugTracker.NET中,我假设不会有太多的bug。也许数万,但不是数千万。这种假设允许我缓存标记和它们引用的项目的ID

在数据库中,标记与错误一起存储在逗号分隔的文本字段中

当添加或更改标记字段时,会启动一个后台线程,该线程选择所有BugID及其标记,解析文本,构建一个映射,其中键是标记,值是具有该标记的所有ID的列表。然后将该映射缓存在Asp.Net应用程序对象中

下面是我刚才描述的代码

代码可以进行优化,这样它就不用经历所有的bug,而是增量地修改缓存的映射,即使是未优化的映射,也可以正常工作

当有人使用标记进行搜索时,我会在映射中查找值,获取id列表,然后使用带有“whereid in(1,2,3…)子句的SQL获取这些bug

publicstaticvoidthreadproc_标记(objectobj)
{
System.Web.HttpApplicationState app=(System.Web.HttpApplicationState)obj;
SortedDictionary标记=新的SortedDictionary();
//更新缓存
DbUtil DbUtil=new DbUtil();
DataSet ds=dbutil.get_DataSet(“从错误中选择bg_id,bg_标记,其中为isnull(bg_标记)”)”);
foreach(ds.Tables[0].行中的数据行dr)
{
string[]labels=btnet.Util.split_string_使用逗号((string)dr[1]);
    public static void threadproc_tags(object obj)
    {
        System.Web.HttpApplicationState app = (System.Web.HttpApplicationState)obj;

        SortedDictionary<string,List<int>> tags = new SortedDictionary<string,List<int>>();

        // update the cache
        DbUtil dbutil = new DbUtil();
        DataSet ds = dbutil.get_dataset("select bg_id, bg_tags from bugs where isnull(bg_tags,'') <> ''");

        foreach (DataRow dr in ds.Tables[0].Rows)
        {
            string[] labels = btnet.Util.split_string_using_commas((string) dr[1]);

            // for each tag label, build a list of bugids that have that label
            for (int i = 0; i < labels.Length; i++)
            {

                string label = normalize_tag(labels[i]);

                if (label != "")
                {
                    if (!tags.ContainsKey(label))
                    {
                        tags[label] = new List<int>();
                    }

                    tags[label].Add((int)dr[0]);
                }
            }
        }

        app["tags"] = tags;

    }