在阅读了本网站关于索引的问答后,我想到了一个问题。
如果使用一个时间维度表,其粒度级别较低,那么会怎样呢?应该把索引放在哪里?
Randy Melder 在问题中:“索引”在 RDBMS 上意味着什么?说过 :
将索引视为“目录”......这是指向文件中位置的指针的有序列表,也就是偏移量
在时间维度的情况下,如果时间表存储特定年份的全天,则大多数数据研究可能针对特定日期、特定周、特定月或特定季度进行。
我的问题是:应该为所有这些字段设置索引吗?
Day 应该是独一无二的,所以对于这一天,我完全理解索引的使用。但是一周 id 将有7 次出现,一个月 id 将有30/31 次出现,一个季度 id 将有或多或少120 次出现。
我问你是因为在同一个问题中,大卫·斯皮莱特说:
添加太多索引当然可能是一个糟糕的优化,因为用于存储索引的额外空间(以及在您的数据库看到许多写操作时维护它们的 IO 负载)可能比稍微不太理想的读取查询更糟糕,所以不要过度。
那么对于时间维度的情况,最好的考虑是什么?
我是数据集市设计的新手,需要澄清一些概念。
我已经阅读了一些关于维度建模的内容,我看到事实表存储了对维度表的外键引用。
现在假设我有一个电话号码维度表和一个 phone_extension 维度表。(这些表格有不同的细节,因此我无法将它们组合起来)
据我了解,这两个维度表都将具有整数主键以获得更好的性能,事实表将具有自己的整数主键并存储对这些维度表的外键引用。
但是假设我遇到了一种情况,即并非所有电话号码都有与之相关的 phone_extension。(有些电话号码不需要分机)
对于具有扩展名的电话号码,事实表将有两个维度表的外键引用,但是我如何捕获只有电话号码而没有扩展名的情况(反之亦然,即没有电话号码的扩展名) ?
我是否应该使用事实表中的电话号码 FK 捕获此类信息,该电话号码具有值和 phone_extension 外键为空?或者这些不相关的对象没有记录在事实表中?
我还需要生成这个数据集市的报告。那么我是从查询事实表并检索维度键值开始还是直接从维度表中报告?
感谢您花时间阅读本文!!
感谢任何帮助!
我偶然发现了一个我不擅长的数据库设计问题,而我的首选 DBA 大师正在进行消防演习。
本质上,我有一个包含以下主键的表(为简洁起见,PK):
child_id integer
parent_id integer
date datetime
Run Code Online (Sandbox Code Playgroud)
child_id和parent_id是实体表的外键。“子”表本身也包含一个到“父”表的外键,而且,每个表child_id总是引用与parent_id上表预期相同的外键。事实上,事实证明有一些额外的代码使两者保持同步。
这使得这个过度热情的规范化新手说“我应该删除冗余!”
我分解为以下内容:
Table_1 PK:
child_id integer
date datetime
Table_2 PK:
parent_id integer
date datetime
Table_3: (already exists)
child_id integer PRIMARY KEY
parent_id integer FOREIGN KEY
Run Code Online (Sandbox Code Playgroud)
瞧,当我以自然的方式将这些人连接在一起时,我恢复了原始表。这是我的理解,使这个 5NF。
然而,现在我意识到有一个隐藏的商业规则。
通常,与给定关联的日期child_id必须是与相应parent_id. 您可以看到第一个表强制执行此规则。
我的分解不强制执行规则,因为您可以自由添加到表 1,直到日期变得太大。
这使我来到这里,有以下问题:
这是分解5NF吗?虽然我会说它允许插入异常,但它似乎也遵循 Wiki 示例,该示例本身遵循本指南。短语(强调我的)“我们可以从由三种不同记录类型组成的规范化形式重建所有真实事实”给了我特别的停顿,因为无论我注入多少垃圾Table_1,自然连接仍然会忽略它。
假设我不喜欢这种分解(我不喜欢)。我坦率地承认,实际的解决方案是让表格和代码保持原样。但是,从理论上讲,有没有办法分解和/或添加约束,以便我摆脱第一个表并保留我的业务规则?
schema normalization database-design best-practices relational-theory
我是一名学生,作为我的学术界的一部分,我正在开发几个项目。
在为其中一个项目开发数据库时,我们遇到了一种情况,我们考虑是否需要 ERD。目前,并不是我们每个人都同意先开发 ERD,然后从它开发数据库。
大多数人更喜欢直接根据纸上要求的系统口头开发数据库。
现在,我严格遵循数据库原则。我认为数据库应该只从 ERD 开发。所以,我只想知道以下几点:
我正在研究一个会计系统,对于每笔交易,如果这是借方或贷方,我需要保存。我可以想到两种方法(MySQL数据库):
方法一
方法二
在第一个设置中,我保存了交易类型,但在第二种方式中,我宁愿将金额保存在借方或贷方列中。这种方法的优点是与方法 1 相比,我可以更轻松地将借方和贷方总额相加。但我想知道是否有一种通用的方法可以做到这一点?
我有一个 PostgreSQL 9.1 数据库,其中的一部分处理代理佣金。每个代理都有他/她自己的计算佣金的公式。我有一个函数来生成每个代理应该获得的佣金数量,但是随着代理数量的增加,它变得无法使用。被迫做一些非常长的case语句和重复的代码,这让我的函数变得非常大。
所有公式都有常量变量:
d .. 那个月的工作天数 r .. 获得新节点 l .. 忠诚度得分 s .. 子代理佣金 b .. 基本利率 我 .. 收入增加
公式可以是这样的:
d*b+(l*4+r)+(i/d)+s
Run Code Online (Sandbox Code Playgroud)
每个代理与人力资源部协商支付公式。那么我可以将公式存储在代理表中,然后像一个小函数一样从表中获取公式并将其转换为值并计算数量吗?
postgresql database-design stored-procedures functions postgresql-9.1
我试图找出 SQL 或非 SQL 解决方案是否更适合创建事件数据库。我正在创建一个票务系统,类似于票务主。我知道对于任何一种数据库类型的存储都是简单的部分。决定因素是以下查询的性能:
事件基本上有 ID、NAME、LOCATION、VENUE、START DATE、END DATE
在关系模式中,我会有一个 EVENTS 表,一个用于单独存储日期的 DATES 表,因为事件可以发生在多个日期并且它们是可重复的,以及一个 VENUES 表,可以从中获取事件位置(国家、城市等)交叉引用。
我没有使用 no-SQL 数据库的经验,因此如果您投票支持 no-SQL,请建议您如何看待“架构”的组织方式以及哪个特定的数据库。
我希望这个问题足够具体。查询性能是决定性因素。
经过进一步考虑,我意识到这个问题更适合提炼出日期/时间函数的可用性,这些函数可以促进快速日期范围查询。我知道 MySQL 和 PostgreSQL 有这样的功能。在这一点上,PostgreSQL 在语法方面甚至看起来更好一些。我不知道 NoSQL 解决方案必须为此提供什么。
我知道系统当然可以在关系数据库中轻松建模。我也知道每个 no-sql 解决方案都是不同的。我想知道是否有人对特定的 no-sql 数据库有任何特定知识,可以引用为什么该特定数据库对解决方案有好处。
我们正在尝试优化数据仓库设计,该设计将支持针对多个时区的数据进行报告。例如,我们可能有一份一个月的活动(数百万行)的报告,需要显示按一天中的小时分组的活动。当然,一天中的那个小时必须是给定时区的“本地”小时。
当我们只支持 UTC 和一个本地时间时,我们的设计运行良好。UTC 和本地时间的日期和时间维度的标准设计,ID 在事实表上。但是,如果我们必须支持 100 多个时区的报告,那么这种方法似乎无法扩展。
我们的事实表会变得很宽。此外,我们必须解决 SQL 中的语法问题,即指定在任何给定的报告运行中使用哪个日期和时间 ID 进行分组。也许是一个非常大的 CASE 语句?
我已经看到一些建议,可以通过您所覆盖的 UTC 时间范围获取所有数据,然后将其返回到表示层以转换为本地并在那里聚合,但是使用 SSRS 进行的有限测试表明这将非常慢。
我也查阅了一些关于这个主题的书籍,他们似乎都说只有 UTC 和转换显示或有 UTC 和一个本地。将不胜感激任何想法和建议。
注意:此问题类似于:处理数据集市/仓库中的时区,但我无法评论该问题,因此觉得这值得自己提出问题。
更新:在Aaron 进行了一些重大更新并发布了示例代码和图表后,我选择了他的答案。我之前对他的回答的评论不再有意义,因为他们提到了答案的原始编辑。如果有必要,我会尝试回来并再次更新
data-warehouse database-design sql-server reporting timezone
我们以大约 5000 pr 的速率接收实时 GPS 数据。分钟(来自 4 个 TCP 服务器)。每个服务器使用单个连接来插入数据,并在插入之间缓冲数据。每隔 15 分钟左右,服务就会获取这些数据,并将其处理为行程。一旦生成了行程,实际的 GPS 数据通常就不那么重要了,只有当用户想在地图上查看路线时才会如此。
问题是数据库似乎正在努力跟上插入数据的速度。有时,当负载增加时,插入时间突然急剧增加(> 30 秒),这反过来又允许缓冲更多数据,从而导致更大的插入和更长的插入持续时间。
我希望得到一些关于当前设计的评论,一些我们必须提高性能的想法,以及我们一些问题的答案 - 以及人们可能有的任何其他提示!
当前设计
数据目前被分成代表一周的表格,并且超过一年的数据被存档到辅助数据库中。整个事情在一个可编辑的视图中连接在一起,用于插入和读取。
餐桌设计
指数
目前每周大约占用 10 GB 包括索引,目前主数据库中有大约 300 GB 数据。
主数据库中的数据表有自己的包含 1 个文件的文件组,但它与主数据库中的所有其他表在同一磁盘上。辅助数据库在不同的磁盘上,但在同一台机器上。
我认为我们也每周运行一次索引重建作业,当一个新的表分区(周)被使用时。不执行收缩。
该机器是具有 12 GB 内存的 8 核 HP,保存主数据库的磁盘运行 RAID 10。
想法
什么时候不想对数据库进行分区?(思维MySQL 分区)
就我而言
即使是最后一点,查找也不是并行运行的,所以在所有情况下,这是一个胜利吗?分区有什么缺点?为什么不是每个人都默认使用的东西,至少当您查看一百万条以上的记录时?
更新 - 我选择了 zgguy 的答案,但请注意,我在自己的研究结果中添加了自己的答案,包括指向对我非常有用的类似问题的非常好的答案的链接。
database-design ×10
mysql ×2
sql-server ×2
erd ×1
functions ×1
index ×1
mongodb ×1
nosql ×1
partitioning ×1
performance ×1
postgresql ×1
reporting ×1
schema ×1
timezone ×1
vldb ×1