标签: database-design

MySQL 能否合理地对数十亿行进行查询?

我计划将质谱仪的扫描结果存储在 MySQL 数据库中,并想知道存储和分析这一数量的数据是否远程可行。我知道性能因环境而异,但我正在寻找粗略的数量级:查询需要 5 天还是 5 毫秒?

输入格式

每个输入文件包含一次光谱仪运行;每次运行都由一组扫描组成,每个扫描都有一个有序的数据点数组。有一些元数据,但文件的大部分由 32 位或 64 位整数或浮点数数组组成。

主机系统

|----------------+---------------------------------------|
| 操作系统 | Windows 2008 64 位 |
| MySQL 版本 | 5.5.24 (x86_64) |
| 中央处理器 | 2x 至强 E5420(共 8 核)|
| 内存 | 8GB |
| SSD 文件系统 | 500 GiB |
| 硬盘RAID | 12 TiB |
|----------------+---------------------------------------|

服务器上还有一些其他服务在使用可忽略的处理器时间运行。

文件统计

|-----------+--------------|
| 文件数| ~16,000 |
| 总尺寸| 1.3 TiB |
| 最小尺寸 | 0 字节 |
| 最大尺寸 | 12 GiB …

mysql performance database-design

289
推荐指数
15
解决办法
17万
查看次数

二进制文件应该存储在数据库中吗?

存储与数据库中数据相关的二进制文件的最佳位置是什么?你应该:

  1. 使用 blob 存储在数据库中
  2. 使用数据库中的链接存储在文件系统上
  3. 存储在文件系统中但重命名为内容的散列并将散列存储在数据库中
  4. 我没有想到的东西

(1) 的优点是(除其他外)事务的原子性得以保留。代价是您可能会显着增加存储(和相关的流/备份)要求

(3) 的目标是在某种程度上保留原子性 - 如果您可以强制您正在写入的文件系统不允许更改或删除文件,并且始终具有正确的哈希作为文件名。这个想法是在允许引用哈希的插入/更新之前将文件写入文件系统 - 如果此事务在文件系统写入之后但在数据库 DML 之前失败,那很好,因为文件系统“假装”是所有的存储库可能的文件和哈希值 - 是否有一些文件没有被指向并不重要(如果你小心的话,你可以定期清理它们)

编辑:

看起来一些 RDBMS 以各自的方式涵盖了这一点 - 我很想知道其他人是如何做到的 - 特别是在 postgres 的解决方案中

database-design blob

147
推荐指数
10
解决办法
9万
查看次数

使用 ENUM 与 Integer 类型的优缺点?

假设在某个随机表中,您有一个名为status的列。它的实际值将是enableddisabled

此列的数据类型是 int/bool(1 或零)还是ENUM与值为enabledand一起使用更好disabled?有什么优点或缺点?

假设您有 4 个或 10 个甚至更多,而不仅仅是两个有效状态?随着所需值数量的增加,优势和劣势会向一侧倾斜还是向另一侧倾斜?

mysql database-design datatypes

136
推荐指数
3
解决办法
7万
查看次数

为什么我们不应该允许 NULL?

我记得读过这篇关于数据库设计的文章,我还记得它说你应该有 NOT NULL 的字段属性。我不记得为什么会这样。

我似乎只能想到,作为应用程序开发人员,您不必测试 NULL可能不存在的数据值(例如,字符串的空字符串)。

但是对于日期、日期时间和时间 (SQL Server 2008),您会怎么做?你必须使用一些历史或触底的日期。

对此有何想法?

null database-design

134
推荐指数
7
解决办法
6万
查看次数

如何在 PostgreSQL 中指定新列的位置?

如果我有一个包含列的表:

id | name | created_date
Run Code Online (Sandbox Code Playgroud)

并想添加一列,我使用:

alter table my_table add column email varchar(255)
Run Code Online (Sandbox Code Playgroud)

然后在列之后添加created_date列。

有什么办法可以指定新列的位置吗?例如,我可以在之后添加它name并得到一个表格,如:

id | name | email | created_date
Run Code Online (Sandbox Code Playgroud)

postgresql database-design

106
推荐指数
3
解决办法
12万
查看次数

存储与计算聚合值

是否有任何指导方针或经验法则来确定何时存储聚合值以及何时动态计算它们?

例如,假设我有用户可以评分的小部件(请参阅下面的架构)。每次我显示一个小部件时,我都可以从Ratings表格中计算出平均用户评分。或者,我可以将平均评分存储在Widget表格中。这将使我不必在每次显示小部件时计算评分,但是每次用户对小部件进行评分时我都必须重新计算平均评分。

Ratings       Widgets
---------     -------
widget_id     widget_id
user_id       name              
rating        avg_rating  <--- The column in question
Run Code Online (Sandbox Code Playgroud)

mysql database-design aggregate

104
推荐指数
2
解决办法
3万
查看次数

复合索引是否也适用于第一个字段的查询?

假设我有一个包含字段A和的表B。我在A+上进行常规查询B,所以我在 上创建了一个复合索引(A,B)A复合索引是否也会对查询进行全面优化?

此外,我在 上创建了一个索引A,但 Postgres 仍然只使用复合索引来查询A。如果前面的答案是肯定的,我想这并不重要,但是为什么它默认选择复合索引,如果单个A索引可用?

postgresql performance index database-design index-tuning

104
推荐指数
1
解决办法
4万
查看次数

数十亿行数据的最佳数据库和表设计

我正在编写一个需要存储和分析大量电气和温度数据的应用程序。

基本上,我需要存储过去几年和未来数万个地点的大量每小时用电量测量值,然后以不太复杂的方式分析数据。

我需要(目前)存储的信息是位置 ID、时间戳(日期和时间)、温度和电力使用情况。

关于需要存储的数据量,这是一个近似值,但大致如下:
20 000 多个位置,每月 720 条记录(每小时测量,每月大约 720 小时),120 个月(10 年前) ) 和未来许多年。简单的计算得出以下结果:

20 000 个位置 x 720 条记录 x 120 个月(10 年前)= 1 728 000 000 条记录

这些是过去的记录,新记录将每月导入,因此每月大约有 20 000 x 720 = 14 400 000 条新记录

总位置也将稳步增长。

对于所有这些数据,需要执行以下操作:

  1. 检索特定日期和时间段的数据:某个位置 ID 在 01.01.2013 和 01.01.2017 之间以及 07:00 和 13:00 之间的所有记录。
  2. 特定日期和时间范围的简单数学运算,例如 MIN、MAX 和 AVG 温度以及特定位置 ID 5 年 07:00 至 13:00 之间的用电量。

数据将每月写入一次,但会被数百名用户(至少)不断读取,因此读取速度更为重要。

我没有使用 NoSQL 数据库的经验,但从我收集到的信息来看,它们是此处使用的最佳解决方案。我已经阅读了最流行的 NoSQL 数据库,但由于它们完全不同,并且还允许非常不同的表架构,我一直无法决定使用什么是最好的数据库。

我的主要选择是 Cassandra 和 MongoDB,但由于我的知识非常有限,而且在大数据和 NoSQL 方面没有实际经验,我不太确定。我还读到 …

nosql database-design database-recommendation

104
推荐指数
5
解决办法
16万
查看次数

反对或支持将应用程序逻辑置于数据库层的论据是什么?

NOTE程序员.se和dba.se的受众不同,会有不同的观点,所以在这个例子中我认为复制什么是反对或支持将应用程序逻辑放在数据库层的论据是什么?在程序员.se上。

我已经找不到关于 dba 的讨论了,原帖已经说明了一切,所以:

大多数软件开发人员都希望将应用程序逻辑保留在应用程序层中,我们将它保留在这里可能感觉很自然。数据库开发人员似乎希望将应用程序逻辑放在数据库层,作为触发器和存储过程。

就我个人而言,我更愿意在应用层中保留尽可能多的内容,以便更容易调试并保持各层的职责分离。

您对此有何看法,在数据库层中应该或不应该实现什么?

注意,我不是该问题的 OP,但保留了原始措辞。

database-design

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

编写一个简单的银行模式:我应该如何保持我的余额与他们的交易历史同步?

我正在为一个简单的银行数据库编写架构。以下是基本规格:

  • 数据库将存储针对用户和货币的交易。
  • 每个用户每种货币都有一个余额,因此每个余额只是针对给定用户和货币的所有交易的总和。
  • 余额不能为负。

银行应用程序将专门通过存储过程与其数据库通信。

我希望这个数据库每天接受数十万个新事务,以及更高数量级的平衡查询。为了非常快速地提供余额,我需要预先汇总它们。同时,我需要保证余额永远不会与其交易历史相矛盾。

我的选择是:

  1. 有一个单独的balances并执行以下操作之一:

    1. 将事务应用于transactionsbalances表。TRANSACTION在我的存储过程层使用逻辑来确保余额和交易始终同步。(由杰克支持。)

    2. 将交易应用到transactions表并有一个触发器,balances用交易金额为我更新表。

    3. 将交易应用到balances表中,并有一个触发器transactions为我在表中添加一个新条目,其中包含交易金额。

    我必须依靠基于安全的方法来确保在存储过程之外不能进行任何更改。否则,例如,某些进程可以直接将事务插入transactions表中,并且在该方案1.3下相关余额将不同步。

  2. 有一个balances索引视图,可以适当地聚合事务。存储引擎保证余额与其交易保持同步,因此我不需要依赖基于安全的方法来保证这一点。另一方面,我不能再强制余额为非负数,因为视图——甚至索引视图——不能有CHECK约束。(由丹尼支持。)

  3. 只有一个transactions表,但有一个额外的列来存储该交易执行后立即生效的余额。因此,用户和货币的最新交易记录也包含其当前余额。(下面由Andrew建议;由garik提出的变体。)

当我第一次解决这个问题时,我阅读了 两个讨论并决定了 option 2。作为参考,您可以在此处查看它的基本实现。

  • 您是否设计或管理过这样的具有高负载配置文件的数据库?你对这个问题的解决方案是什么?

  • 你认为我做出了正确的设计选择吗?有什么我应该记住的吗?

    例如,我知道对transactions表的架构更改需要我重建balances视图。即使我正在归档事务以保持数据库较小(例如,将它们移到其他地方并用摘要事务替换它们),每次架构更新时都必须重建数千万个事务的视图,这可能意味着每次部署的停机时间会显着增加。

  • 如果索引视图是要走的路,我如何保证没有余额为负?


归档交易:

让我详细说明一下存档交易和我上面提到的“摘要交易”。首先,在像这样的高负载系统中,定期存档将是必要的。我想保持余额与其交易历史之间的一致性,同时允许将旧交易转移到其他地方。为此,我将用每个用户和货币的金额摘要替换每批存档交易。

因此,例如,此交易列表:

user_id    currency_id      amount    is_summary
------------------------------------------------
      3              1       10.60 …
Run Code Online (Sandbox Code Playgroud)

sql-server-2008 database-design sql-server aggregate materialized-view

70
推荐指数
5
解决办法
7万
查看次数