我有一个名为videos
的表。它具有三列id
,title
,tags
。由于视频的标签可能很多,因此我创建了另一个名为videos_tags
的表,该表具有id
,life
,school
和activity
作为其列,而id
的videos_tags
匹配id
的videos
。videos_tags
表是这样的:
id life school activity
123 0 1 0
我的目标是能够获取视频的相应标签。我所做的就是给表
tag
中的videos
列提供了一个数字,该数字应为表id
中的videos_tags
,如下所示 id title tags
1 avideo 123
因此,我将通过以下方式获取标签参考ID:
SELECT tags FROM videos WHERE id=1
然后,我将再次运行
SELECT
语句,以通过在表id
中获取的标签的videos
来获取视频的相应标签,如下所示SELECT * FROM videos_tags WHERE id=123
我们到了,我们有了所需的标签。
我的问题是:是否可以通过某种关系表(例如,使用外键)来获取标签,它会进一步简化查询代码吗?
我担心的是,我使用的方法在表
tags
的videos
和表id
的videos_tags
之间的连接较弱,因为当您修改例如id
的video_tags
时, ,tags
中的videos
不会更改,这有时可能会给程序造成很大的问题。 最佳答案
您无法理解:
标签存在(独立于任何对其进行了标签的视频)
您的Video :: Tag的关系是多个,一对一
您已将其设置为3,并且它是固定的
如果标签少于三个,则为NULL
您将来无法添加标签...如果这样做,将是心痛,结构更改和代码更改。
结果,您使事情变得比实际复杂得多。除了将表固定在具体位置(将来很难更改)之外,还必须更改所有代码。
Recommended SQL database design for tags or tagging的可能重复项
是。但是,那里的“已接受”解决方案没有关系,因此没有完整性。功率;关系系统的速度或速度。我将逐步指导您从您的外观到最佳设计。
1960年代的备案档案系统•退化和混乱
如果您遵循被认为是“关系”的“文学”,“教科书”或“文章”,则会得出以下结论:
我的所有数据模型均以IDEF1X(自1993年以来的关系数据库建模标准)呈现
我的IDEF1X Introduction是必读的。
1960年的记录归档系统•退化
如果您按照Codd的关系模型的方向提升它,同时又保持物理Record Id
的心态,这就是Yaakov Ellis所说的“适当的索引等”(我为您提供的更多)...我们得到了这个:
这样可以防止重复行(RM中的基本要求)
它删除了重复的声明,并消除了循环引用以及这种特定疯狂所确保的可怕后果。
每张表仍然需要一个额外的Record Id
和一个额外的索引,以支持使用原始记录对数据进行物理化,这是完全不必要的(这些拐杖对于诸如Date和Darwen以及它们的知识分子残障至关重要关注者)。
当然,您可以在“混乱的”和“退化的”之间进行补充,但仍保留在1960年的“记录归档系统”类别中,没有关系能力。
关系型数据库
由于已标记SQL & Relational Database
,因此您可能希望消除黑噪声并遵循Codd的关系模型。如果这样做,您将获得以下信息:
人类用户将不会使用VideoId
号。 FullTitle
太长且麻烦。他们将使用简短的标题,该标题在原始系统中丢失
他们都不使用TagId
。他们想要标签
我给出了更多相关的谓词,以便您可以自己检查它们
轻松添加或删除标签
将来没有结构上的变化,因此代码也没有变化。
的SQL
我担心的是,我使用的方法在表格视频中的标签和表格video_tags的ID之间关系较弱,因为当您修改video_tags的ID时,视频中的标签不会更改,这可能会导致在某个时候,这个程序确实是一个巨大的问题。
是的,所有这些担忧都消失了。
删除Id
字段并正确规范标签,可以消除该问题
并且消除了可怕的两步法。
真正的关系数据库的标志之一是,任何报告都可以通过单个SELECT
命令生成。
我的问题是:是否可以通过某种关系表(例如,使用外键)来获取标签,它会进一步简化查询代码吗?
另一个特点是简单,直接的SQL代码。给定视频标题(人们自然会使用的简短标题),找到具有以下任何标签的视频:
选择VT.VideoTitle
FROM VideoTitle VT-外部查询
标记在哪里
(选择VT_IN.Tag
FROM VideoTag VT_IN-内部子查询
哪里VT_IN.VideoTitle = @VideoTitle
)
如果要在报告中包含完整标题,请执行以下操作:
选择VT.VideoTitle,
五,全标题
FROM VideoTitle VT-外部查询
加入视频V
开启VT.VideoTitle = V.VideoTitle
标记在哪里
(选择VT_IN.Tag
FROM VideoTag VT_IN-内部子查询
哪里VT_IN.VideoTitle = @VideoTitle
)