在进行数据库规范化时,什么是将重复的行信息集组合成新的实体?

2024-01-14

我对数据库规范化的某个部分有点困惑,我想我应该问 StackOverflow:

想象一下,您有以下将产品与颜色联系起来的关系。请注意,产品 1 和产品 2 都使用同一组颜色(蓝色和绿色)。

Product_Color                         Color
+-------------+-------------+     +-------------+-------------+
| Product*    | Color*      |     | ColorId*    | Name        |
+-------------+-------------+     +-------------+-------------+
| 1           | 1           |     | 1           | Blue        |
| 1           | 2           |     | 2           | Green       |
| 2           | 1           |     +-------------+-------------+
| 2           | 2           |
+-------------+-------------+

如果我创建两个新关系 ColorSet 和 ColorSet_Color,我可以通过将 4 个关系连接在一起来显示相同​​的信息。

Product_ColorSet:                 ColorSet_Color:             
+-------------+-------------+     +-------------+-------------+
| Product*    | ColorSetId* |     | ColorSetId* | ColorId*    |
+---------------------------+     +-------------+-------------+
| 1           | 1           |     | 1           | 1           |
| 2           | 1           |     | 1           | 2           |
+-------------+-------------+     +---------- --+-------------+

ColorSet:                         Color:
+-------------+                   +-------------+-------------+
| ColorSetId* |                   | ColorId*    | Name        |
+-------------+                   +-------------+-------------+
| 1           |                   | 1           | Blue        |
| 2           |                   | 2           | Green       |
+-------------+                   +----------[--+-------------+

此时,如果我有一个大型 Product_Color 表,并且具有合理程度的共享颜色组,那么从空间角度来看,我将获得相当大的收益。

在数据库规范化的背景下,此操作的技术名称是什么?我显然正在删除冗余信息,即使我创建的实体实际上并不存在,这更像是存在大量重叠的随机机会。我这样做具体要改变什么?

此外,似乎我可以对大多数实体任意执行此操作。让我困惑的是,当我们开始练习时,Product_Color 和 Color 已经处于第六范式(对吗?)。


您正在介绍一个“代理键 https://en.wikipedia.org/wiki/Surrogate_key“(或标识符)到name/identify产品所采用的颜色集。替代方案通常被认为是“自然键 https://en.wikipedia.org/wiki/Natural_key“(或标识符)。(尽管不同的人在细节上使用这些术语的方式不同。例如,当名称/标识符被永久分配给所指对象和/或其所指对象的唯一名称/标识符和/或其是时,有些人可能仅使用“代理”仅在数据库中可见,而在应用程序中不可见。例如,有些人会说外部可见的系统生成的任意名称/标识符(如驾驶员识别号)既是替代项又是自然项。)

代理键通常被称为“无意义(标识符)”。这反映了思想的混乱。All不是由先验命名方案生成的名称是“无意义的”且任意的。 “尼古拉斯”并不是“意思”you直到被选中;一旦被选中,它就“意味着”你。这适用于any名称/标识符。因此,“无意义”/“有意义”并不是一个有用的区别。系统中的代理名称/标识符只是系统启动后选择的名称/标识符。当在之前存在的任何系统中分配时,系统中被称为“有意义”[原文如此]的东西将被称为“无意义”[原文如此](因为分配是在之后)it开始)。

有一种“视角”是“删除冗余信息”,但这不是规范化所解决的那种冗余。您正在用其他表替换一个表,但这不是规范化分解。引入代理人并不是正常化的一部分。规范化不会引入新的列名称。它只是在替换它的表中重用原始表的名称。 (你能清楚准确地描述一下这里的“冗余”是什么意思吗?)

有时人们认为,如果相同的值子元组可以在列集或表中出现多次,那么这些子行值需要替换为 id,这些 id 是新表的 FK,将 id 值映射到子行值。 (甚至可能对于单列子行,即当单个值在列或表中出现多次时。)他们认为多个子行值出现是“冗余的”,或者只有 id 可以重复而不是“冗余”。 (id设计被视为原始数据的一种压缩。)他们可能认为这是规范化的一部分。但事实并非如此。 https://stackoverflow.com/a/32036030/3404097

这不是您应该通过表格设计来解决的冗余问题。If您知道 DBMS 对表的实施选项and您了解应用程序的使用模式and你知道原来的选项显然比某些恰好“冗余度较低”的选项更糟糕(为什么“冗余度更高”的选项不会更好?)then如果可以的话,您应该告诉 DBMS 您的设计需要什么选项,而不需要更改架构。 (这通常是通过索引和/或视图完成的。)例如,在 ColorId 上索引原始 Product_Color 会导致实现中的结构与您在第二个设计中手动创建的结构基本相同,但会自动生成和管理。 (您可能会引入代理other原因,例如用更简洁但更模糊的值和约束的外键替换多列外键。)

重新选项:您的新设计将使用更多操作(例如连接和投影)在查询文本中并且(对于典型的 DBMS 实现)执行比原始(例如查询原始表)但是fewer其他地方(例如,将一个产品的颜色设置复制到另一个产品的颜色设置)。所以这又是关于权衡 of multiple“观点”。

事实上你在另一种意义上引入冗余与代理人。还有一些附加列保存了原始中没有的一堆 id 值,但记录了相同的情况。您还给用户带来了更多命名和间接设计的负担。与原始设计相比,替代设计在这个“视角”中肯定有很多“冗余信息”。

甚至您的初始设计也可能引入了代理,即颜色名称的颜色 ID。 (如果颜色 ID 添加了“信息”,即“通知”您的不仅仅是它们的相关名称,那么它们就不是替代品,而且是必要的。)即,如果颜色 ID 是任意选择的,那么您可以:

Product_Color
+-------------+-------------+
| Product*    | ColorName*  |
+-------------+-------------+
| 1           | Blue        |
| 1           | Green       |
| 2           | Blue        |
| 2           | Green       |
+-------------+-------------+

你应该有一个reason引入颜色 ID,以及就此而言的产品 ID,而不是已经存在的自然键。你可以吗justify您的多个表、名称和间接寻址与只有一个?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在进行数据库规范化时,什么是将重复的行信息集组合成新的实体? 的相关文章

  • 用户评级的 ER 模型

    我有很多 用户 每个用户最多有 5 个 服务 用户应该能够对每项服务进行评分 0 5 我还想保留用户的平均评分 这是我的想法 但是还有更好的方法吗 User id user name dob 服务 固定数量的服务 id service de
  • 如何设计多租户mysql数据库[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 假设我需要设计一个数据库来托管多个公司的数据 现在 出于安全和管理目的 我需要确保不同公司的数据正确隔离 但我也不想启动 10 个 m
  • 数据库、表和列命名约定? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 每当我设计数据库时 我总是想知道是否有命名数据库中项目的最佳方法 我经常问自己以下问题 表名应该是复数吗 列名应该是单数吗 我应该为表或列添加前
  • 子查询与连接

    我重构了从另一家公司继承的应用程序的一个缓慢部分 以使用内部联接而不是子查询 例如 WHERE id IN SELECT id FROM 重构后的查询运行速度提高了约 100 倍 50 秒到 0 3 我预计会有改进 但谁能解释为什么它如此剧
  • 设计 Cassandra 数据模型的最佳实践是什么? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 以及需要避免哪些陷阱 您有任何交易中断吗 例如 我听说导出 导入 Cassandra 数据非常困难 这让我想知道这是否会妨碍将生产数据
  • 如何在 SQL 中存储目标(例如 RPG Quest)

    今天有人问我他们应该如何将任务目标存储在 SQL 数据库中 在这种情况下 请考虑角色扮演游戏 目标可能包括以下一些内容 发现 地点 杀死 n MOB 类型 获取 对象 的 n 个 实现 技能组 中的 技能 你在角色扮演游戏中获得的所有其他东
  • 如何使组合键唯一?

    I am making a database of students in one school Here is what I have so far 如果您不喜欢阅读 请跳至 简而言之 部分 问题是我对这个设计并不满意 我想要的组合gra
  • Django 选择性转储数据

    是否可以有选择地过滤哪些记录Django的dumpdata管理命令输出 我有几个模型 每个模型都有数百万行 我只想转储一个模型中符合特定条件的记录 以及引用任何这些记录的所有外键链接记录 考虑这个用例 假设我有一个生产数据库 其中我的用户模
  • 当两个表非常相似时,什么时候应该将它们合并?

    我有事件和照片 然后对两者进行评论 现在 我有两个评论表 一个用于与事件相关的评论 另一个用于照片评论 架构与此类似 CREATE TABLE EventComments CommentId int EventId int Comment
  • 数据库分区 - 水平与垂直 - 规范化和行拆分之间的区别?

    我试图理解不同的概念数据库分区这就是我的理解 水平分区 分片 将表拆分为不同的表 其中将包含初始表中的行的子集 如果按大陆拆分用户表 我见过很多这样的示例 例如北美的子表 欧洲的另一个子表 ETC 每个分区位于不同的物理位置 理解 机器 据
  • parent_id 是外键(自引用)并且为 null?

    浏览 Bill Karwin 的书 SQL Antipatterns 第 3 章 Naive Trees 邻接表 父子关系 有一个注释表的示例 CREATE TABLE Comments comment id SERIAL PRIMARY
  • 列太多的表的缺点

    我有一些数据需要放入 PostgreSQL 数据库中 这些数据与学校有关 所以有很多与学校相关的属性 大部分是小整数 浮点数或小文本 所有数据每年都会发生变化 所以我正在创建一个名为的实体YearlyData并将属性放在那里 但问题是 属性
  • 软删除最佳实践(PHP/MySQL)

    Problem 在处理产品和订单的 Web 应用程序中 我想维护前员工 用户 与他们处理的订单之间的信息和关系 我想维护过时产品和包含这些产品的订单之间的信息和关系 然而 我希望员工能够整理管理界面 例如删除前员工 过时的产品 过时的产品组
  • 非规范化如何提高数据库性能?

    我听说过很多关于非规范化的内容 它是为了提高某些应用程序的性能而进行的 但我从来没有尝试过做任何相关的事情 所以 我只是好奇 规范化数据库中的哪些地方会使性能变差 或者换句话说 非规范化原则是什么 如果我需要提高性能 如何使用此技术 非规范
  • 是否需要连续编号?

    我正在开发一个 winform NET 应用程序 其中包括订单 发票 服务订单 票务等 这些实体在对其 ID 进行编号时是否必须按顺序排列 国际海事组织没有 以一个订单为例 它只有通过业务层才有效 在此过程中 可能已经创建了另一个订单 批准
  • 数据库设计1对1关系

    我的数据库设计不正确 我应该在开发过程中解决这个问题吗 假定 user 表与 userprofile 表具有 1 1 关系 然而 实际设计中 用户 表与 用户配置文件 表具有 1 关系 一切正常 但无论如何应该修复它吗 做一件事 User
  • “多对二”关系

    我想知道 多对二 关系 孩子可以与两个父母中的任何一个有联系 但不能与两个父母都有联系 有什么办法可以加强这一点吗 另外我想防止孩子重复输入 现实世界的例子是电话号码 用户和公司 一个公司可以有很多电话号码 一个用户可以有很多电话号码 但理
  • Rails 5:迭代的数据库设计

    我目前有一个包含用户 餐食和订单表的网站 Users表保存用户信息 餐食表包含餐食名称 描述 img url 我目前正在使用迭代来显示餐食 span class mealname span p p p p div class qty INP
  • 核心数据模型设计

    假设我有一个关于烹饪食谱的应用程序 具有两个基本功能 第一个涉及我正在准备的当前食谱 第二个存储了我决定保存的食谱 标准场景 我目前的食谱是 芝士蛋糕 RecipeDetailViewController我可以看到我为此食谱添加的当前成分
  • 修订:算法和数据结构

    我需要通过修订来构建和处理数据的想法 例如 我有一个对象数据库 例如汽车 每个对象都有许多属性 这些属性可以是任意的 因此没有一个固定的模式来描述这些对象 这些对象可能保存为键值对 现在我需要更改对象的属性 我不想完全重写它 我希望能够返回

随机推荐