1

我正在创建一个论坛页面,为此我创建了以下数据库架构:

Forum(questionId, postedByUserId, questionSubject, questionBody, TagIds);

Tags(tagId, tagName);

论坛中的条目将类似于:

(1, 1, 'sample subject', 'sample body', '1 4 2') ...

标签的示例条目将是:

(1, 'C'), (2, 'C++'), (3, 'Java'), (4, 'Data Structure') ...

现在的问题是,第一个范式表示所有字段都应该是原子的,在这种情况下不满足,但我认为节省了空间,就好像我正在创建一个新表一样,forum_tag(questionId, tagId); 然后我认为这将在数据库上占用更多空间,但是在概念上是正确的。

所以我不知道我应该做什么,是做我现在正在做的事情,还是按照规范化使列原子化。

请解释哪个更好以及为什么,因为在很多情况下我发现了这样的问题,但我一直模棱两可,我应该怎么做!

所以请帮忙。

提前致谢 :)

4

3 回答 3

1

数据库中的空间很便宜。随空间变化的检索时间要便宜得多。但是,检索时间也可能受到键控访问策略是否有效的影响,并且将由查询优化器选择。效果可能是戏剧性的。

考虑对您提出的架构进行以下检索:查找相关标签之一为“4”的所有论坛条目。对于大多数 DBMS,此查询将需要对整个 Forums 表进行顺序扫描。根据数据量,这可能是数百万个磁盘 I/O。

现在考虑一个连接表

ForumTags (ForumId, TagId) primary key (ForumId, TagId)

此外,假设除了 (ForumId, TagId) 上的自动索引之外,TagId 上还有一个索引

相同的查询将导致在其中一个索引中查找值为“4”的索引,并且只需要十几个磁盘 I/O。

规范化的目标之一是对所有数据进行密钥访问。第一范式就是按照这个目标来的。

我有过现实生活中的情况,其中第一个范式或更好的模式可以与嵌入列表的模式进行比较。在这些情况下,速度差异大约是 50 比 1。

于 2011-05-17T15:27:26.513 回答
1

我会让你的领域原子化。大多数情况下,您有一个字段将值混杂到一个字段中,当您必须不断地将这些数据分开以进行报告或分析时,您最终会感到头疼。如果你想做一些简单的事情,比如计算你的标签数量怎么办?由于非原子数据,您甚至无法快速完成SELECT COUNT(). 在创建交叉引用具有不同标签的论坛帖子的查询时,您也会遇到很大的问题。假设您想查询所有标记为“编程”的论坛帖子?

当您尝试查询或分析数据时,预先使数据原子化可以更容易地使用它。这么说吧,数据在进入您的数据库之前就开始泛化,但您总是希望从中获得细节。尝试将数据保存在离散的块中,以便更容易获得细节。

于 2011-05-17T18:56:06.193 回答
0

您应该制作第三个表格来表示论坛和标签之间的关系:

论坛标签(ftID、论坛、标签)

这样,您的数据库就可以正确规范化,因此向论坛添加和删除标签变得更加容易。不要担心它可能会占用数据库中的额外空间,就像 Walter Mitty 所说: 空间很便宜,而检索则要少得多。作为一般规则:规范化总是一个好主意,除非另有明确证明

于 2011-05-17T14:43:07.570 回答