标签: normalization

第一范式:明确定义

我试图获得什么是第一范式的明确版本。我阅读的所有内容都略有不同。

许多权威,例如 Date,说根据定义,关系总是处于第一范式,而其他人则给出了要求列表。这意味着对 1NF 的要求从零到很多。

我想区别在于表和关系之间的区别:表可能是一团糟,而关系遵循某些限制。关系在 SQL 中表示为表的事实因此造成了一些混淆。

我特别关注 1NF,因为它与 SQL 数据库有关。问题是:需要什么属性来确保表处于第一范式?


许多权威建议,如果一个表代表一个关系,那么它已经在 1NF 中。这将 1NF 的定义推回到关系的定义。

以下是 1NF 中表的一些属性:

  • 列顺序无关紧要 [1]
  • 行顺序无关紧要
  • 所有行的长度相同(即行数据与列标题匹配)
  • 没有重复的行(这可以使用代理主键来保证,但 PK 本身不是必需的)
  • 没有重复的列
  • 每一列包含一个单一值(原子)

[1] 技术上属性是无序的,但在表格中,行数据必须与列标题的顺序相同。然而,实际的顺序是微不足道的。

多个数据上

原子数据的概念是一个项目不能被进一步分解。这个概念是有限制的,因为虽然从技术上讲,一切都可以令人厌烦地分解,但实际上不能进一步分解所讨论的数据,这取决于数据的使用方式。

例如,完整地址或全名通常应该进一步细分,但可能不应该进一步细分诸如给定名称或城镇名称之类的组件,尽管它们可以作为字符串。

至于重复的列,它是一个设计不良列具有重复列,例如phone1phone2等。通常,重复数据指示用于一个附加的相关表的需要。

依赖

行之间不应该有任何关系,除了它们符合相同的标题。

列之间也应该没有关系,但我相信这是更高范式的主题。

问题是:1NF 的定义中有多少上述内容?独立行位也进入了吗?

normalization database-design relational-theory

10
推荐指数
2
解决办法
1052
查看次数

没有主键的表是否标准化?

在一次讲座中,我的讲师向我们展示了一张没有主键的表格。经询问,他说在 3NF 中,当您删除传递依赖项时,可以使用没有主键的表。

然而,没有主键意味着没有函数依赖——但是 3NF 是去除传递依赖,我被教导每个表都需要有一个主键来规范化,因为它完全是关于函数依赖的。

我知道完全有可能创建一个没有主键的表,但是如果该表存在,该数据库是否被认为是规范化的?

我应该补充一点,该表没有任何“唯一键”,没有主键,没有复合键,没有外键。

显示的表具有三个属性,其中没有一个被标记为主要或唯一的。我问是不是搞错了,他说没有也没关系。我对这句话提出了质疑,因为表格中的所有信息都无法唯一标识,他声称可以这样。这与我学到的关于规范化的内容背道而驰。

normalization database-design relational-theory

9
推荐指数
1
解决办法
3095
查看次数

我是否违反了数据库设计中的任何 NF 规则?

我是创建数据库的新手...我需要为我的招聘网络应用程序创建它。

我的申请需要安排申请人的筛选、考试和面试,并将结果保存在数据库中。

我的数据库架构如下:

在此处输入图片说明

我的问题是我applicant_id在其他表格中包含了...例如考试、面试、考试类型。

我是否违反了任何规范化规则?如果我这样做了,你有什么建议来改进我的设计?

normalization database-design

8
推荐指数
2
解决办法
595
查看次数

代理键违反什么范式?

我有以下问题:

“代理键违反了什么标准形式?”

我的想法是第三范式,但我不太确定这只是我所做的假设。有人可以向我解释一下吗?

normalization surrogate-key relational-theory

8
推荐指数
4
解决办法
4407
查看次数

库存数据库的单独归档表或软删除

我正在构建一个跟踪计算机设备和其他硬件设备的库存数据库。在任何设备生命周期的某个时刻,它都会退役并被归档。归档后,需要对其进行跟踪,因为它已从服务中移除并妥善处置。我最初使用活动数据库的精确副本设计了归档机制,该副本将使用从活动数据库中删除时的触发器接收其数据。存档数据库包括所有相关表的副本,因为由于某些外来相关记录不再相关,因此用户不应访问它们以用于新设备,但需要使用存档表进行引用完整性和查询。请记住,此处存档的概念不仅仅是保存历史记录或日志。归档是业务流程的一部分,

下面的 ERD 使用该Inventory.DeviceType表作为示例,其中所有条目和更新都复制到该Archive.DeviceType表中。当用户不再能够输入某种设备类型的库存记录时,它会从Inventory.DeviceType表中删除,但保留在存档表中。此模式用于所有表以确保存档引用有效数据,因此是所有表的副本。

活动表示例(省略其他相关表) 主动ERD

归档表示例(省略其他相关表) 存档 ERD

问题

我想弄清楚如果我不知道设备是活动的还是存档的,我将如何查询数据库?例如,如果用户有一个序列号并想查找有关设备的信息,而他们不知道它是否已存档。

选项 1:基于联合创建一个视图?

选项 2:如果第一个查询没有返回任何内容,则查询活动数据库,然后查询存档?

传奇还在继续……

一位同事建议我删除存档数据库并使用软删除方案。我使用这个想法构建了一个模型,然后开始遇到许多其他问题。

以下是使用软删除方案的相同表。

软删除示例

软删除 ERD

使用此设置,通过将IsArchivedfield设置为 true 并输入ArchivedDate. 我可以轻松查询任何设备是否处于活动状态或已存档。(请忽略该IsActive字段,因为它用于不相关的概念)。

请注意电话子类型表,我必须在其中传播 DeviceID 和 IsArchived 标志的索引,因为活动设备的电话号码必须是唯一的。我也必须对其他子类型表执行此操作。我不知道这是一个好还是坏的设计。

这部分真的让我很困惑......

在外键值可以标记为已删除的情况下,处理软删除的最佳做法是什么。我唯一能想到的就是创建一个例程来搜索与已删除数据相关的所有记录,并为用户创建一个报告来解决差异。例如,如果位置表与设备表相关,并且某些位置被软删除,则设备指的是不再存在且必须移动的位置。

顺便说一下,我使用的是 MS SQL Server 2008 R2,我计划在我的应用程序中使用 Entity Framework 4。我更看重数据库的可维护性而不是性能。

感谢您的阅读。

sql-server-2008 normalization database-design sql-server

8
推荐指数
1
解决办法
6625
查看次数

此数据的最佳关系数据库结构

我正在为以下场景创建数据库方案:

  • 有用户
  • 用户具有角色(例如“开发人员”或“CEO”)
  • 角色有应用程序(例如“Topdesk”)
  • 应用程序具有权限(例如“更新知识库”)
  • 如果角色已经有权访问应用程序,则该角色可以拥有权限

假设没有高性能环境(无需优化速度),实现此模式的最佳方法是什么?数据库环境可以是MySQL、MSSQL……更多的是关系型数据库的设计。

我自己提出了以下几点:

ERD图

我最不确定的部分当然是 Applications_Permissions_Roles 表。它是另一个链接表之上的链接表。我以前从未使用或见过这个。另一种方法是用角色和权限之间的链接表替换它,然后使用代码或约束来确保所需的关系......但这对我来说似乎不是一个好的解决方案。如果可能的话,这些事情应该在数据库级别强制执行(并且看起来可能),而不是在代码级别执行。

其次,是否需要 Permissions.Application 和 Applications.Id 之间的链接?我使用它是因为 Roles_Applications 中可能没有任何行(例如,当您刚刚添加了一个新应用程序时),然后无法确定哪些权限属于哪个应用程序。它也是查找权限所属的应用程序的单一参考点。我想这是对的,但它也在数据库设计中绕了一圈。尝试将 ON_DELETE 或 ON_UPDATE 设置为级联时出现 MSSQL 错误。

任何建议,或者这是应该如何完成?顺便说一下,也欢迎任何有关命名约定等的建议(也许作为评论)。

谢谢,
卢克

编辑:更改了标题,希望能更清楚。前一个更全面,但可能过于复杂。

normalization database-design relational-theory

8
推荐指数
1
解决办法
1245
查看次数

重叠候选键究竟是什么?

有人可以简单地向我解释一下什么是overlapping candidate key?什么是overlapping顾名思义?

考虑以下关系

R(L,M,N,O,P) 
{
    M -> O
    NO -> P
    P -> L
    L -> MN
}
Run Code Online (Sandbox Code Playgroud)

上述哪个函数依赖在上述关系中引入了重叠的候选键?

让我们将讨论限制在依赖项上,我目前对 BCNF 不感兴趣

normalization database-design dependencies

8
推荐指数
1
解决办法
8327
查看次数

强制执行“至少一个”关系

许多一对多(数据模型)维基百科的文章使用作者和图书的例子:

例如,将 A 视为作者,将 B 视为书籍。一个作者可以写几本书,一本书可以由几个作者写。

在关系数据库管理系统中,这种关系通常是通过关联表(也称为交叉引用表)来实现的,例如,AB 具有两个一对多关系 A -> AB 和 B -> AB。在这种情况下,AB 的逻辑主键由两个外键(即 A 和 B 的主键的副本)形成。

有了约束,你会如何执行一本书必须至少一个作者?

笔记:

  • 对于此示例,本书没有“主要”作者这样的东西。
  • 以 SQL(任何 RDBMS)或一般术语回答。

normalization database-design constraint

8
推荐指数
1
解决办法
4447
查看次数

过多的表是否违反规范化规则?

这是我工作的数据库中存在的一些表的示例。数据实际上并不围绕学校,但结构是相同的。

有四张表:

** School **
School Id, School Name

** ClubType **
ClubType Id, ClubType Name

** Club **
Club Id, School Id, ClubType Id

** Student **
Student Id, Name, Club Id
Run Code Online (Sandbox Code Playgroud)

知道俱乐部表永远不会有额外的列(因为真实数据实际上不是关于学校俱乐部的),

我相信一个明显更好的设计,消除俱乐部表以避免连接,将是:

** School **
School Id, School Name

** ClubType **
ClubType Id, ClubType Name

** Student **
Student Id, Name, School Id, ClubType Id
Run Code Online (Sandbox Code Playgroud)

编辑:我们也知道每个俱乐部 ID 可能只有一种类型。Club 和 ClubType 的关系是 1 比 1。

我的问题是,第一个例子是否违反了一些已知的数据库规范化规则或其他一些数学原理?或者这只是一个糟糕的设计案例?

normalization database-design

8
推荐指数
1
解决办法
2039
查看次数

存储的金融交易是否应该包括一些数据冗余?

我目前在下表中存储金融交易(为简洁起见已缩短):

id INT
start DATETIME
end DATETIME
rate INT
usage INT
usage_fee INT
amount INT
commission_pct INT
payout INT
currency VARCHAR(5)
Run Code Online (Sandbox Code Playgroud)

向客户收取的总金额计算如下: amount = (end - start) * rate + usage * usage_fee

该平台收取以下费用/佣金: commission = amount * (commission_pct / 100)

服务提供商收到的付款是: payout = amount - commission

现在在上表中,存储支出在技术上是多余的,因为它可以按上图所示进行计算。我的问题是,存储这些类型的有关数据冗余的金融交易的常见方式/约定是什么?

例如,我正在考虑也存储的结果(end - start) * rateusage * usage_fee分别在该表中,除了它们的总和(量)。

我看到这样做的优点是:

  • 将相应金额发送到“支付提供商的 API”时没有(四舍五入)错误,即用户最终支付的金额与存储在数据库中的内容完全相同,而不是将计算值发送到所述 API
  • 易于查询和分析

这些专业人士是否有效,或者您会建议我完全规范化表格并在需要时计算值吗?

我知道根据“数据库设计原则”对表格进行规范化是正确的答案,但由于我正在处理财务数据,因此我不确定我是否 100% 愿意使用计算值。


佣金率不是每笔交易特定的,但收取的 Commission_pct 很可能在未来发生变化,因此它与每笔交易一起存储。当然,如果存储的是实际的“佣金金额”,则无需存储佣金百分比。

当时使用的 Commission_pct 和 rate 存储在表中,这就是为什么将来为后续交易更改这些不会有问题并且永远不会编辑现有交易的原因。此外,只有一个受控应用程序可以访问数据库。如果公式在未来发生变化,不计算和存储结果将是一个问题。我倾向于应用程序计算这些值并一举存储“原始”和计算值。

normalization database-design

8
推荐指数
1
解决办法
731
查看次数