标准化/组合具有相似数据的多个表

Lar*_*y B 4 mysql schema normalization database-design mysql-workbench

我正在根据第三方供应商的数据建立车辆记录数据库。有 3 种模型:车辆、变速器和适配器。

车辆和变速器都是 1:n 适配器。从技术上讲,变速箱只是带有附加变速箱柱的车辆,而车辆除了车辆柱之外还包含燃油系统柱。我无法确定将我的数据组合成一个标准化集合的最佳方式。

以下是我的一些数据示例:

传输表

**传输表**

车辆表 在此处输入图片说明

数据透视表

在此处输入图片说明

如您所见,传输和车辆在trans_type/ fuel_system columns(分别)和之后基本相同。例如,我突出显示的 Vehicle 与用 engine_code 显示的第二个传输相同LML

理想情况下,我希望最终只得到一张车辆数据表。例如,如果我要合并突出显示的记录,我最终应该只有 2 个记录2013 GMC Sierra 3500 HD:一个使用 6.0L V8 发动机,另一个使用 6.6L V8 发动机,以及相应的燃油系统和变速箱列每个。

数据透视表也将被合并,这意味着我需要以某种方式用合并数据中的新 ID 替换旧 ID。

以下是我对如何解决这个问题的想法:

  1. 标准化相似的列(品牌、型号、发动机、变速箱)
  2. 简单地将fuel_systemtrans_type列拆分到他们自己的表中(但这对我合并没有任何帮助,它只会使事情更易于管理,直到我弄清楚如何合并)
  3. 创建一个包含两个表中所有列的新表,并插入来自 Vehicles 和 Transmissions 的数据,填空(即更新fuel_system,其中记录匹配,反之亦然),然后开始清理重复项。

对于这篇冗长的帖子,我深表歉意,但我还没有在我的搜索中找到任何能真正概括这个过程的内容。欢迎任何意见或建议,并在此先感谢您。

MDC*_*CCL 7

功能依赖规范化

为了进行归一化的运动,涉及第二和进一步范式-as%的数据的关系模型通过E.˚F科德博士- ,首先必须知道什么是相关的函数依赖属性之间(FDS为了简洁) (通常描绘为)的改编的数学关系(通常描绘为表格)。这种练习属于数据库的逻辑抽象级别。这就是为什么,为了解决您声明的获得规范化集合的意图,我通过评论请求有关适用 FD 的信息。

例如,涉及假设属性FooBar的 FD可以描述为Foo ? Bar,这又可以读作“属性 Foo 决定属性 Bar”或“属性 Bar 由属性 Foo 决定”。通过这种方式,人们可以区分 (a) 一个或多个属性,或一个或多个属性的组合,它们是关系的一个或多个键,以及 (b) 区分不是或不是关系的一部分的属性,键或键。

关于您描述的场景,让我们假设题为“传输”的网格是数学关系的具体表示。对于标记为submodel, body_code, engine_code, engine, desplacement, cylinders, trans_type, trans_codequalifier的列的值,可以说:

  • 一些(engine_codetrans_code)似乎由称为Vehicle的关系的键的值决定,例如,Vehicle - 即(model, make, year) 的组合

  • 有些(传输类型限定符)似乎由称为传输适配器的关系的键值决定,即trans_code

  • 一些(engine_type排量汽缸)似乎由一个关系的键值决定,让我们说,Engine - 即engine_code

但这些都是简单的假设,基于我对上述网格中包含的信息的个人解释,显然我根本不熟悉所讨论的业务背景。因此,为了摆脱那些不必要的和有问题的假设,您必须采访业务专家,他们将帮助您识别 FD,进而指导您执行正确以数据库管理行业要求的精度规范化和布局数据库结构。如果没有您可以求助的业务专家,那么您将不得不深入研究数据集,观察数据的用途和含义,并仔细分析感兴趣的信息之间的相互关联,以自己确定重要的 FD。

归一化集合

拥有规范化的数据库有助于避免更新/修改异常(影响 INSERT、UPDATE 和 DELETE 操作),当所考虑的关系(表)的属性(列)之间存在不合需要的依赖关系时,这些异常最终会出现。在这种情况下,例如,有关系的属性 (i) 依赖于非键属性,或 (ii) 依赖于复合——即多属性——键的部分,设计者必须分解关于两个或更多的关系。

因此,大多数情况下,规范化集合由各种关系组成,每个关系都旨在在其元组(行)中准确包含一种特定类型的事实。相反,非规范化非完全规范化的集合由一个或多个关系组成,这些关系在其元组中包含不止一种类型的事实。

从抽象的概念级别开始的数据库设计

在另一方面,你可以设计从不同的角度出发的相关数据库,首先分析了结构和关联关系-或者一个或连接-类型的从一个纯粹的概念点自己感兴趣的东西,没有约关系的思考(表)、属性(列)、约束和规范化。当然,这种方法还需要数据库设计者和业务专家之间的密切沟通,或者在没有业务专家的情况下,数据库设计者对信息需求和业务环境的特征有深入的了解。

示例业务规则

因此,我会将一些假设的业务规则放在一起,这些规则将有助于基于对您的问题中包含的信息的仅仅假设来创建说明性概念模式。

一个车辆是:

  • 主要由ModelMakeYear 的一个组合标识
  • 仅由一台发动机移动
  • 仅配备一个变速器适配器

一个引擎

  • 主要由一个EngineCode 标识
  • 仅按一种EngineType编目
  • 正好有一个位移
  • 仅容纳一种类型的气缸
  • 只提供一个燃油系统
  • 安装在零、一辆或多辆汽车上

一个TransmissionAdaptor是:

  • 主要由一个传输码识别
  • 仅按一种传输类型分类
  • 安装在零、一辆或多辆汽车上

一个FuelSystem

  • 主要由一个名称标识
  • 仅按一种FuelSystemType分类
  • 正好有一个压力
  • 安装在零、一辆或多辆汽车上

如图所示,(a)可能相关实体类型属性之间的假设关联类型,以及 (b) 可能实体类型本身之间的假设关联类型,已经以相对清晰的方式进行了说明。

显然,这些规则只是阐述设计数据库时可以遵循的方法的媒介。作为个人的解读,当然应该根据实际的商业环境特征进行确认、驳斥或改编。

有时,数据库设计人员会绘制描绘概念模式定义的图表,以便提供一种图形工具,帮助所有感兴趣的(技术和非技术)方进行交流。

当这一阶段的结果稳定到一定程度时,就可以更加自信地开始考虑通过逻辑层次结构来表示这些概念方面。

a顺便指出,概念关系与逻辑关系非常不同。

说明性 SQL-DDL 逻辑级设计

先后,我创建了以下四个表格,代表上面阐述的概念级公式:

CREATE TABLE TransmissionAdaptor ( 
    TransmissionAdaptorCode CHAR(10) NOT NULL,
    TransmissionType        CHAR(30) NOT NULL,
    --
    CONSTRAINT TransmissionAdaptor_PK PRIMARY KEY (TransmissionAdaptorCode)
);

CREATE TABLE FuelSystem ( 
    Name           CHAR(6)  NOT NULL,
    FuelSystemType CHAR(10) NOT NULL,
    Pressure       CHAR(10) NOT NULL,
    FuelSystemName CHAR(30) NOT NULL,
    --
    CONSTRAINT FuelSystem_PK PRIMARY KEY (Name)
);

CREATE TABLE MyEngine ( 
    EngineCode     CHAR(3) NOT NULL,
    EngineType     CHAR(8) NOT NULL,
    Displacement   CHAR(3) NOT NULL,
    Cylinders      CHAR(3) NOT NULL,
    FuelSystemName CHAR(6) NOT NULL,
    --
    CONSTRAINT Engine_PK               PRIMARY KEY (EngineCode),
    CONSTRAINT Engine_to_FuelSystem_FK FOREIGN KEY (FuelSystemName)
        REFERENCES FuelSystem (Name)
);

CREATE TABLE Vehicle ( 
    Model                   CHAR(20) NOT NULL,
    Make                    CHAR(10) NOT NULL,
    MyYear                  SMALLINT NOT NULL,
    EngineCode              CHAR(3)  NOT NULL,
    TransmissionAdaptorCode CHAR(10) NOT NULL,
    --
    CONSTRAINT Vehicle_PK                 PRIMARY KEY (Model, Make, MyYear),
    CONSTRAINT Vehicle_to_Engine_FK       FOREIGN KEY (EngineCode)
        REFERENCES MyEngine (EngineCode),
    CONSTRAINT Vehicle_to_Transmission_FK FOREIGN KEY (TransmissionAdaptorCode)
        REFERENCES TransmissionAdaptor (TransmissionAdaptorCode)
);
Run Code Online (Sandbox Code Playgroud)

由于现在将处理逻辑级元素,表中明确声明了基于清晰概念模式的键,因此需要进行适当的范式评估练习,以测试设计的合理性。

就个人而言,我发现上面描述的设计顺序,即,

  • (1)概念表述 ? (2) 逻辑表示 ? (3) 通过范式测试

比直接使用“孤立的”函数依赖更自然,因为它可以帮助设计者从不同的抽象层次以彻底的方式理解场景。

进一步的考虑

系统分配的代理

如您所见,我没有将额外的Id列(通常添加以包含系统生成的代理键值)附加到这些表中的任何一个,因为这样做只会阻碍(概念)建模和(逻辑)规范化任务。一旦您拥有具有相应约束的稳定结构,就可以评估添加该非数据工件有益的特定情况。

列数据类型

未详细讨论的一个重要因素是与每列相关联的特定。因此,当您继续设计数据库时,您必须确定最适合的数据类型和每列的大小。

数据推导

具有与上述类似的逻辑布局,您必须利用派生表(例如,通过 SELECT 操作声明的表,这些表从一个或多个表或 - 其他 -派生表中收集列)来获取如图所示的信息,例如, 在您的传输网格中。

当然,派生表可以定义为可以进一步查询的视图,以便例如方便编写未来数据操作操作的代码。

研究这一点可能会很有用,看看您是否可以实现您的既定目标,理想情况下,最终只得到一张Vehicle数据表。

物理层面

抽象的物理级别是另一个需要注意的点,因为最方便的索引的配置与数据库的最佳功能(例如,读写速度、可扩展性)直接相关。不用说,您必须在这方面考虑数据操作操作(或查询)的趋势。通常,您修复支持所涉及列的索引,例如,在 WHERE 和 JOIN 子句中。

MySQL 作为数据库管理系统的众多缺点和缺点之一是它不提供对“索引”或“物化”视图的内置支持,因此如果您想构建一个数据库,这个因素绝对值得考虑这有效地工作。

其他重要的物理级方面是,例如,以最佳方式设置所涉及的硬件(硬盘驱动器、内存、处理器等)、数据库管理系统、操作系统、网络带宽等。


附录

在最近的一次评论互动中出现了在设计数据库时拥有所关注业务领域的完整知识的重要性的证据,其中@Rick James提出了有关某些实体类型、它们对应的关联类型和您场景中的基数比率的相关考虑:

看起来传输:适配器是多:多,而不是 1:多。请说清楚。

……您对此的回应如下:

是的,这是正确的。变速箱有自己的适配器,而燃料系统有自己的适配器。一个传输属于零个、一个或多个传输适配器,一个传输适配器可以属于零个、一个或多个传输。

因此,如您所知,有必要对这些概念实体类型进行建模,即:

  • 传输传输适配器燃料系统燃料系统适配器

和连接关联类型,即:

  • 变速箱-变速箱适配器燃料系统-燃料系统适配器

以便它们以所需的精度反映您的业务领域特征。

一旦所有相关方面都在具有相应表(为每个实体/关联类型放置一个)、列、数据类型和约束的逻辑级 DDL 设计中表示后,您可能希望评估所涉及的功能依赖性以提供强大的、规范化, 系统.