标签: database-design

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

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

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

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

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

我的选择是:

  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万
查看次数

在 PostgreSQL 中存储电子邮件地址的最佳方法是什么?

在 PostgreSQL 中存储电子邮件地址的正确数据类型是什么?

我可以使用varchar(甚至text),但我想知道电子​​邮件是否有更具体的数据类型。

postgresql database-design datatypes

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

如何在数据库和架构上管理用户的默认权限?

我想将一个相当简单的、内部的、数据库驱动的应用程序从 SQLite3 迁移到 PostgreSQL 9.3,并在执行过程中收紧数据库中的权限。

该应用程序当前包含一个用于更新数据的命令;和一个查询它。当然,我还需要以其他方式维护数据库(创建新表、视图、触发器等)。

虽然此应用程序一开始将是唯一托管在服务器上的应用程序,但我更愿意假设它将来可能会托管在具有其他数据库的服务器上,而不是在以后有必要时进行争夺未来。

我认为这些将是一组相当常见的要求,但我很难找到一个简单的教程来解释如何在 PostgreSQL 中设置一个新数据库,并使用这种用户/权限分离。参考资料详细介绍了组、用户、角色、数据库、模式和域;但我觉得他们很困惑。

这是我到目前为止尝试过的(从内部psql作为“postgres”):

CREATE DATABASE hostdb;
REVOKE ALL ON DATABASE hostdb FROM public;
\connect hostdb
CREATE SCHEMA hostdb;
CREATE USER hostdb_admin WITH PASSWORD 'youwish';
CREATE USER hostdb_mgr   WITH PASSWORD 'youwish2';
CREATE USER hostdb_usr WITH PASSWORD 'youwish3';

GRANT ALL PRIVILEGES ON DATABASE hostdb TO hostdb_admin;
GRANT CONNECT ON DATABASE hostdb TO hostdb_mgr, hostdb_usr;
ALTER DEFAULT PRIVILEGES IN SCHEMA hostdb GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO hostdb_mgr;
ALTER DEFAULT PRIVILEGES …
Run Code Online (Sandbox Code Playgroud)

postgresql database-design permissions

59
推荐指数
1
解决办法
6万
查看次数

是否应该在编写应用程序代码之前设计数据库?

设计数据库的最简单和最有效的方法是什么?从我的角度来看,应用程序的数据存储设计有几个选项:

  1. 在编写任何应用程序代码之前,尽可能最好地设计数据库。这为您提供了使用基本数据结构的优势。在我看来,这样做的缺点是您将有很多更改作为应用程序细节,这些更改会影响整个应用程序开发周期中数据更改的内容/位置/方式。
  2. 在应用程序实现时设计数据库。当您在编写应用程序时需要一些数据库对象时,您可以与应用程序并行(按时间顺序)开发数据库。在我看来,优点是对数据库结构的更改较少。缺点是应用程序代码和数据库开发之间的时间和开发工作的划分。

根据您的经验,您认为最有成效和最有效的方法是什么?

database-design

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

复数与单数表名

创建新数据库时应如何命名表?

单数:Client或复数:Clients

database-design naming-convention

57
推荐指数
5
解决办法
4万
查看次数

为每个客户创建数据库会遇到什么问题?

我从 stackoverflow 播客中记得Fog CreekFogbugz为每个客户使用一个数据库。我认为这意味着 Fogbugz On Demand 服务器拥有数以千计的数据库。

我们刚刚开始开发一个网络应用程序,并有一个类似的问题需要解决(许多客户拥有自己的独立数据)。

使用每个客户的数据库会出现什么问题?我该如何解决它们?

我的初步想法

每个客户数据库的优势

  • 更简单的数据库架构
  • 更简单的备份 - 您可以依次备份每个客户,而不会真正影响其他客户。
  • 可以轻松导出给定的客户数据。
  • 更好的缓存性能 - 写入一个更活跃的表只会影响执行写入的单个客户。
  • 更容易跨硬件扩展。例如,当我们需要从 1 台服务器增加到 2 台服务器时,我们只需将一半的客户转移到新服务器上。

缺点

  • MySQL能应付5000个数据库吗?性能会很差吗?
  • 对架构的更改可能难以复制到所有数据库中。我们真的必须为此制定一个自动化计划,例如对模式进行版本控制,以及一个了解如何将数据库从一个版本转换为另一个版本的脚本。
  • 做我们所有客户共同的事情可能会很尴尬或不可能
  • 与上述类似,但我们想要对所有客户执行的任何分析都可能是不可能的。例如,我们应该如何跟踪所有客户的使用情况?

mysql database-design database-recommendation

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

我应该在数据库中以什么数据类型存储电子邮件地址?

我知道 254 个字符的电子邮件地址是有效的,但我研究过的实现倾向于使用 varchar(60) 到 varchar(80) 或等效的。例如:此 SQL Server 推荐使用 varchar(80) 或此 Oracle 示例

是否有理由不使用最多 254 个字符?根据定义,varchar 不是只使用保存数据所需的存储空间吗?

是否存在显着的性能影响/权衡导致如此多的实现使用少于完整的 254 个可能字符?

database-design datatypes

51
推荐指数
3
解决办法
16万
查看次数

什么时候应该非规范化?

我想我们都熟悉数据库规范化

我的问题是:当您想对表进行非规范化时,您使用哪些准则?

database-design

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

拥有多个相互排斥的一对一关系是一种不好的做法吗?

比方说,一个表car有一个一对一关系的表electric_cargas_carhybrid_car。如果 acarelectric_car,则它不能再出现在gas_car或 ahybrid_car等中。

这样的设计有什么问题吗?路上可能会出现的一些问题?

database-design relations

48
推荐指数
2
解决办法
1万
查看次数

如何设计用于存储排序列表的数据库?

我希望在数据库中存储一个排序列表。我想有效地执行以下操作。

  1. Insert(x) - 将记录 x 插入表中
  2. Delete(x) - 从表中删除记录 x
  3. Before(x,n) - 返回排序列表中记录 x 之前的“n”条记录。
  4. After(x,n) - 返回排序列表中记录 x 之后的“n”条记录。
  5. First(n) - 从排序列表中返回前 'n' 条记录。
  6. Last(n) - 返回排序列表中的最后 'n' 条记录。
  7. Compare(x,y) - 给定表中的两条记录 x 和 y,查找是否 x > y。

我能想到的简单方法是在表中存储某种“等级”属性,并通过对该属性进行排序来进行查询。但是在这种方法中,插入/修改具有等级的记录成为一项代价高昂的操作。有没有更好的方法?

具体来说,我希望使用 Amazon 的 SimpleDB 来实现该表。但是关系数据库的一般答案也应该有帮助。

负载配置文件更新:

由于我正在为 Web 应用程序规划此功能,因此这取决于使用该应用程序的用户数量。

如果有 100k 活跃用户(超级乐观:P),那么我每天非常近似的估计是

500k 次选择,100k 次插入和删除,500k 次更新

我希望该表总共增长到 500k。

我希望优化更新、插入和比较操作。项目的排名会不断变化,我需要保持表格更新。

database-design

47
推荐指数
3
解决办法
5万
查看次数