sql在mysql中设计父子关系

kjthegm6  于 2021-06-24  发布在  Mysql
关注(0)|答案(3)|浏览(530)

需要输入数据模型设计
我有一张表

id (PK)
current_version
latest_child_id

子表组件

id (PK)
parent_table_id (FK to parent)
version (running number . largest number implies latest child record)

父表与子表的关系为1:m。此外,父表还保留一个指向子表中记录的最新版本的指针。
系统将在子表中插入n个可变行,并更新父表以指向最新版本-以便更快地读取。
我的问题是:
让父表存储子表的最新版本是一种不好的做法吗?
我是否在寻找潜在的性能问题\锁定问题?既然子表中的任何插入也需要父表上的锁?
问题数据库:mysql

dba5bblo

dba5bblo1#

让父表存储子表的最新版本是一种不好的做法吗?
不,如果它符合你申请的要求,那就完全可以了。您需要添加额外的逻辑来正确更新表,但仅此而已。数据库为您提供了一系列存储数据和关系的可能性,这是一个非常好的选择。
我是否在寻找潜在的性能问题\锁定问题?既然子表中的任何插入也需要父表上的锁?
这取决于更新/插入/删除子项的频率。很可能这不会是一个问题,除非考虑到当前的数据库服务器,更改速率超过每秒200+。对于大量事务,独占锁定可能成为一个问题。
通常锁在行级别。因此,它们将只锁定您正在处理的行,因此具有不同父线程的多个线程不会造成瓶颈。
如果您的系统确实需要高级别的事务(1000+/秒),那么我看到的选项有:
投入更多的硬件:最简单的方法。只要买一台更大的机器,问题就解决了。。。至少有一段时间,直到你的系统再次增长。
使用乐观锁定:这个策略根本不需要执行任何实际的锁定。但是,您需要添加一个额外的数字列来存储行的版本号。
切换到另一个数据库:mysql可能无法很好地处理非常大的容量。如果是这样的话,你可以考虑postgresql,甚至oracle数据库,它当然有更好的缓存技术,但也非常昂贵。

m4pnthwp

m4pnthwp2#

让父表存储子表的最新版本是一种不好的做法吗?
像“坏习惯”这样的短语充满了上下文。我更愿意考虑权衡,并理解这一级别的决定。通过存储一个您可以计算的属性,您正在进行非规范化。这是处理性能挑战的一种既定方法,但它只是其中之一。权衡大致如下。
负面:占用更多存储空间。假设这不重要
否定:需要更多的代码。更多的代码意味着更多的错误机会。考虑将数据访问代码 Package 到测试套件中。
否定:非规范化模式可能需要额外的“大脑空间”——您必须记住,您计算(例如)父级拥有的子级的数量,但通过查看父表中的属性来查找最新的子级。在理想情况下,规范化模式描述业务上下文而不必记住实现细节。
负面:可能会使您的数据模型在将来更难扩展。随着您添加更多的实体和属性,这个非规范化的表可能越来越难以保持同步。一个非规范化的列通常很容易处理,但是如果您有很多非规范化的列,那么保持它们都是最新的可能非常困难。
负面:对于不经常访问的数据,非规范化设计可能比动态计算对性能的影响更大。你的问题2就是一个例子。在复杂的场景中,多个线程可能会在非规范化数据中创建不一致性。
正面:对于经常读取的数据,如果计算很昂贵,非规范化模式将允许更快的读取访问。
在您的情况下,我怀疑您是否需要将此数据存储为非规范化属性。通过在上创建索引 parent_table_id, version DESC ,动态检索这些数据的速度太快,无法测量(假设您的数据库中有100万条记录,而不是100亿条)。
通常,我建议仅在以下情况下进行非规范化:
你可以证明你有一个性能问题(即你已经测量过)
不能通过创建更好的索引来提高性能
您无法通过更好的硬件来提高性能
我是否在寻找潜在的性能问题\锁定问题?既然子表中的任何插入也需要父表上的锁?
正如@theimpaler所写,可能不是。但是,这取决于插入逻辑的复杂性(它是否执行任何可能会减慢速度的复杂计算?),以及多个并发线程尝试更新父记录的可能性。在这些场景中,您也可能最终得到不一致的数据。

6kkfgxo0

6kkfgxo03#

ORDER BY child_id DESC LIMIT 1

是获得“最新”孩子的一种非常有效的方法(假设你有 INDEX(child_id) ).
这样就不需要你提议的那些调皮的“多余”信息了。

相关问题