与数据库表中的原子性相关的问题



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

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"的所有论坛条目。 对于大多数 DBMS,此查询需要对整个论坛表进行顺序扫描。 根据数据量,这可能是数百万个磁盘 I/O 秒。

现在考虑一个连接表

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

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

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

规范化的目标之一是对所有数据的键控访问。 第一种范式是根据该目标。

我遇到过现实生活中的情况,可以将第一个普通形式或更好的模式与具有嵌入式列表的模式进行比较。 在这些情况下,速度差异约为 50 比 1。

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

预先将数据原子化可以使您在尝试查询或分析数据时更轻松地处理数据。 这样说吧,数据在进入数据库之前就开始了通用化,但你总是需要从中得到细节。 尝试将数据保存在离散块中,以便更容易获得细节。

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

论坛标签(ftID, 论坛, 标签)

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

最新更新