首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >规范或不规范user_ids

规范或不规范user_ids
EN

Stack Overflow用户
提问于 2009-12-24 10:20:07
回答 3查看 420关注 0票数 1

在我的Rails应用程序中,我有各种包含用户数据的数据库表。其中一些表有很多行(在某些情况下,每个用户最多有50万行),并且经常被查询。每当我查询任何表时,当前用户的user_id都在查询的某个位置--如果该表与用户有直接关系,或者通过连接(如果它们通过其他表关联),则直接查询该表。

为了更快的性能,我应该取消user_id并将它包含在每个表中吗?

以下是一个例子:

user_id

  • Envelope地址属于用户,
  • 地址属于用户,
    • 地址连接地址和信封,因此它有envelope_id和address_id --它没有user_id,但可以通过信封或地址(必须属于同一个用户)到达它。

一个常见的昂贵查询是为特定用户选择所有的AddressesEnvelopes,即使我不需要这些表中的任何内容,我也可以通过连接地址或信封来完成这些任务。或者我可以复制这个表中的用户id。

这里有一个不同的场景:

信属于用户,user_id

  • Recepient属于字母,letter_id

  • RecepientOption属于接收者,recepient_id

属于recepient_id。

在接受者和RecepientOption中复制user_id是否有意义,即使我总是可以通过联系,通过信函获得它?

一些注意事项:

  • 用户之间从来没有共享的对象。相关对象的整个层次结构始终属于同一个用户,对象的用户所有者changes.
  • Database性能非常重要,因为它是一个数据密集型的应用程序。有许多查询和表。

因此,我应该在每个表中包括user_id,以便在创建索引时使用它?那会不会是个糟糕的设计?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-12-24 10:39:40

我想指出的是,如果您愿意使用复合主键,则没有必要进行反错。AddressEnvelop案例的样本:

代码语言:javascript
复制
user(
    #user_id
)
address(
    #user_id
,   #addres_num
)
envelope(
    #user_id
,   #envelope_num
)
address_envelope(
    #user_id
,   #addres_num
,   #envelope_num
)

(#表示主键列)

如果我能避免的话,我不是这个设计的粉丝,但是考虑到您说所有这些对象都绑定到一个用户的事实,这种类型的设计将使它相对简单地划分您的数据(逻辑上,将用户范围放在单独的表中,或者物理上使用多个数据库,甚至是机器)。

在这种设计中,另一件有意义的事情是使用聚集索引(在MySQL中,InnoDB表的主键是从聚集索引构建的)。如果确保user_id始终是索引中的第一列,则将确保每个表的所有数据都存储在磁盘上。当您总是使用user_id进行查询时,这是很好的,但是如果您使用另一个对象进行查询,则会影响性能(在这种情况下,复制就像您建议的那样可能是一个更好的解决方案)。

无论如何,在更改设计之前,首先要确保模式已经优化,并且外键列有适当的索引。如果性能确实是最重要的,那么您只需尝试几种解决方案并进行基准测试。

票数 2
EN

Stack Overflow用户

发布于 2009-12-24 10:28:29

只要你

( a)取得可衡量的性能改进

b)知道数据库的哪些部分是真正的规范化数据,哪些是冗余的改进

没有理由不这样做!

票数 1
EN

Stack Overflow用户

发布于 2009-12-24 10:37:41

实际上,您有衡量性能的问题吗? 500,000行不是很大的表。如果选择不是很复杂,而且列上有适当的索引,那么选择应该是合理的、快速的。

首先,我将查看是否存在慢速查询,并尝试使用索引优化查询。如果这还不够的话,只有这样我才会研究去正规化。

如果您不能通过其他方法实现所需的性能,那么您建议的反错操作似乎是合理的。只需确保您保持非规范化字段的最新。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1957734

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档