我知道在Stack Overflow上已经广泛讨论了normalis(z)ation.我读过很多以前的讨论.我有一些额外的问题.
我正在研究一个至少有100个表的遗留系统.数据库具有一些非规范化结构,包含各种不同数据的表以及其他问题.我被赋予了改善它的任务.我不能再重新开始,但需要修改现有架构.
在过去,我一直试图设计规范化的数据库.现在的问题.一位高级开发人员建议在某些情况下我们无法规范化:
1)使用时态数据.例如,创建了一个链接到产品的发票.如果客户在一年后要求提供此发票的副本,我们必须能够生成原件的精确副本.如果产品价格,名称或描述已更新怎么办?资深人士建议将价格和其他产品信息复制到发票表中.我想也许我们应该有另一个表,例如productPrice,它有一个日期字段,所以我们可以跟踪价格随时间的变化.我想对产品描述和名称需要相同的东西吗?看似复杂.你怎么看?
2)数据库是一个会计系统.我对会计不是很熟悉.目前,一些摘要数据被导出并存储在数据库中.例如,当年的总销售额.我的高级助理表示,会计师喜欢通过将此值与实际根据发票等计算的数据进行比较来检查事情是否正确,以使他们相信应用程序正常工作.他说,目前我们可以判断是否有人错误地从去年删除了发票,因为总数不会相同.他还指出,在飞行中计算这些总数可能会非常缓慢.当然,我说数据不应该重复,应该在需要时进行计算.我建议我们可以使用SQL Reporting Services或其他一些解决方案来隔夜生成这些报告并缓存它们.无论如何,他不相信.对此有何评论?
非常感谢:)
干杯
马克
感谢您的出色回应.遗憾的是我只能将其中一个作为答案,因为这里有很多好的建议.
我目前正在开展的项目是一个大型非营利组织的公告板.公告板将用于允许组织内的办公室间通信.
我正在构建应用程序,并且无法从我的数据库中提取我需要的结果,因为我认为它没有正确规范化,并且由于我对关系数据库理论和mysql的了解有限.
我将非常感谢董事会设计的输入,特别是可以改进数据库结构以促进有效查询的方式,并帮助我更快地开发此应用程序和未来的应用程序
公告板将按以下方式使用
-- phpMyAdmin SQL Dump
-- version 3.2.4
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: Jan 16, 2011 at 06:44 PM
-- Server version: 5.1.41
-- PHP Version: 5.3.1
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
--
-- Database: `bulletinboard`
--
-- --------------------------------------------------------
--
-- Table structure for table `bbs`
--
CREATE TABLE IF NOT EXISTS `bbs` (
`id` int(11) NOT …Run Code Online (Sandbox Code Playgroud) 我最近问了几个关于数据库设计的问题,可能太多了;-)但是我相信我正在慢慢地用我的设计解决问题的核心并且慢慢地将它煮沸了.我仍在努力解决关于"警报"如何存储在数据库中的几个决定.
在该系统中,警报是必须被确认,采取行动等的实体.
最初我将读数与这样的警报相关联(非常简化): -
[Location]
LocationId
[Sensor]
SensorId
LocationId
UpperLimitValue
LowerLimitValue
[SensorReading]
SensorReadingId
Value
Status
Timestamp
[SensorAlert]
SensorAlertId
[SensorAlertReading]
SensorAlertId
SensorReadingId
Run Code Online (Sandbox Code Playgroud)
最后一个表是将读数与警报相关联,因为它是指示传感器处于警报状态的读数.
这种设计的问题在于它允许来自许多传感器的读数与单个警报相关联 - 而每个警报仅针对单个传感器,并且应该仅具有与其相关联的传感器的读数(我应该担心数据库允许这虽然?).
我想简化一些事情,为什么还要烦扰SensorAlertReading表呢?相反,我可以这样做:
[Location]
LocationId
[Sensor]
SensorId
LocationId
[SensorReading]
SensorReadingId
SensorId
Value
Status
Timestamp
[SensorAlert]
SensorAlertId
SensorId
Timestamp
[SensorAlertEnd]
SensorAlertId
Timestamp
Run Code Online (Sandbox Code Playgroud)
基本上我现在没有将读数与警报相关联 - 相反,我只知道特定传感器的开始和结束时间之间的警报是活动的,如果我想查找该警报的读数,我可以做.
显然缺点是我不再有任何约束阻止我删除警报期间发生的读数,但我不确定约束是否必要.
现在从外面看作为开发人员/ DBA,这会让你想生病还是看起来合情合理?
有没有其他方法可以让我失踪?
谢谢.
编辑: 这是另一个想法 - 它以不同的方式工作.它存储每个传感器状态变化,从表格中的正常变为警报,然后读数简单地与特定状态相关联.这似乎解决了所有问题 - 你怎么想?(我唯一不确定的是调用表"SensorState",我不禁认为有一个更好的名字(也许是SensorReadingGroup?): -
[Location]
LocationId
[Sensor]
SensorId
LocationId
[SensorState]
SensorStateId
SensorId
Timestamp
Status
IsInAlert
[SensorReading]
SensorReadingId
SensorStateId
Value
Timestamp
Run Code Online (Sandbox Code Playgroud)
必须有一个优雅的解决方案!
使用符合6NF原则标准化的数据库时,如何存储历史属性数据?
比方说,我们从@PerformanceDBA 获取此示例,但具有以下额外要求:
我们需要存储所有产品的历史数据,我们应该只需输入日期并获取该特定时间产品属性的快照.
更实际的示例:
假设上面示例中的磁盘和CPU是虚拟的,用户可以随意更改磁盘容量.我们如何改变数据库,以便我们可以在过去的任何时间(当然是在创建日期之后)检索给定磁盘的属性,同时保持5NF视图足够快.
我正在考虑的事情
任何帮助表示赞赏!
编辑:我知道时态数据库的概念,但问题是,对于我正在使用的数据库引擎(postgresql),时间扩展尚未完全实现.关于如何在没有时态数据库的情况下实现这一目
database database-design relational-database database-normalization
我正在创建一个应用程序,其核心功能随时间跟踪各种数据(血糖水平,胰岛素剂量,食物摄入量等),我正在尝试决定如何最好地在数据库中组织这些信息.
最基本的是这个特定伞中的所有内容都是一个事件,因此我想到了一个包含可能出现的所有属性的字段的事件表.然而,这可能是笨拙的,因为绝大多数领域最终将成为许多领域的空白; 但我不确定这是否真的是一个问题.这种方式的好处是可以更容易地调用和显示所有事件.但由于许多事件只有"时间戳"的共同点,我怀疑它们是否属于同一个表.
我不确定为每种事件都有一个表是有意义的,因为单独使用大多数事件只有一个属性而不是时间戳,并且它们通常必须混合在一起.(许多类型的数据通常但不总是出现在一个组中)
某些类型的事件有持续时间.有些是比较罕见的.一类事件通常是保持不变的比率,除非费率被改变为良好或临时覆盖(这些是我最担心的).有些是简单的二进制标记(我计划使用链接表,但为了简单起见,我需要/更喜欢整个event_id来链接它们.
我的倾向是,最好有一些表与密切相关的信息类型,而不是一张表,包含所有内容和大量空间......但我不太清楚如何继续.
在这样的情况下,我会喜欢一些关于确定最佳方法的策略建议.
编辑:这是我正在处理的数据类型的简要说明,以防它更清楚
events:
-blood glucose
timestamp
value
(tagged w/: from pump, manually entered
[pre-meal, post-meal (breakfast, lunch, dinner) before bed, fasting, hypo, high, hyper - which will be either manually entered or inferred based on settings or other user entries], before/after exercise etc i imagine would be better off dynamically generated with queries as necessary. though could apply same paradigm to the meals?
-sensor glucose (must be separate bc it is not as reliable …Run Code Online (Sandbox Code Playgroud) 在数据库世界中,我们进行了规范化.您可以从设计开始,转动步骤并最终使用正常形式的数据库.这是基于数据的语义完成的,可以被认为是一系列设计重构.
在面向对象的设计中,我们拥有SOLID原则和各种其他特殊设计指南.
您是否认为可以为OO定义等效的正规形式,这样一系列重构步骤可以将程序性的代码片段(或者设计不当的OO设计)转换为正确的(在一些定义明确的意义上)相同的功能?
(NB.很高兴制作这个社区wiki)
theory oop normalization relational-database solid-principles
我目前有2个返回的查询
PRODUCER FirstQueryColumn
------------------------------ ----------------------
aaaaaaaaaaaa 1
bbbbbbbbbbb 1
PRODUCER SecondQueryColumn
------------------------------ ----------------------
aaaaaaaaaaaa 2
bbbbbbbbbbb 1
Run Code Online (Sandbox Code Playgroud)
我想知道的是我应该如何制作它以便我可以在一个查询中获得相同的数据,也就是说,我想要的东西会产生(Producer, FirstQueryColumn, SecondQueryColumn).
我怎样才能做到这一点?
这是我目前的查询:
select Producers.name Prod, count(Animals.idanimal) AnimalsBought
from AnimalsBought, Animals, Producers
where (AnimalsBought.idanimal = Animals.idanimal) and (Animals.owner = Producers.nif) group by Producers.name;
select Producers.name Prod, count(Animals.idanimal) AnimalsExploration
from AnimalsExploration, Animals, Producers
where (AnimalsExploration.idanimal = Animals.idanimal) and (Animals.owner = Producers.nif) group by Producers.name;
Run Code Online (Sandbox Code Playgroud)
如您所见,对于这种情况,连接不会做太多:
select Producers.name Prod, count(AnimalsBought.idanimal) AnimalsBought, count(AnimalsExploration.idanimal) AnimalsExploration
from Producers, Animals, AnimalsBought, AnimalsExploration
where (AnimalsExploration.idanimal = …Run Code Online (Sandbox Code Playgroud)