(这被建议从StackOverflow重新发布)
@H_502_2@目前有一个表..并需要开始向其添加新的数据列.
并非每条记录(甚至在添加新数据列后继续使用新数据)都会有数据.所以我想知道这是否更适合新表,因为它实际上是某些数据行的扩展,并不适用于每一行. @H_502_2@换句话说,由于这些新数据元素会有很多未使用的列,所以它似乎更适合新表? @H_502_2@第一个表是页面浏览量记录(目前有200万条记录)
我会假设大约10%的行将拥有数据(因为它通常仅归因于第一次访问) @H_502_2@数据的主要用途是归因于人们来自哪里.这可能会更频繁地使用(这似乎适用于单个表) @H_502_2@感谢反馈 – 如果需要可以添加更多
并非每条记录(甚至在添加新数据列后继续使用新数据)都会有数据.所以我想知道这是否更适合新表,因为它实际上是某些数据行的扩展,并不适用于每一行. @H_502_2@换句话说,由于这些新数据元素会有很多未使用的列,所以它似乎更适合新表? @H_502_2@第一个表是页面浏览量记录(目前有200万条记录)
- id - IP address - times viewed - created_at timestamp - date@H_502_2@对于每个IP地址,每天都会记录一次 – 并且连续的综合浏览量会添加到每天的时间视图中 @H_502_2@其他字段将用于原点跟踪(即谷歌分析源/媒体/活动) @H_502_2@并非每次访问都会有这些信息.
我会假设大约10%的行将拥有数据(因为它通常仅归因于第一次访问) @H_502_2@数据的主要用途是归因于人们来自哪里.这可能会更频繁地使用(这似乎适用于单个表) @H_502_2@感谢反馈 – 如果需要可以添加更多
解决方法
你正在挣扎的是垂直分区.这是一种提高性能的物理数据库设计技术.与任何物理数据库设计技术一样,它的适用性取决于您尝试优化的特定查询以及此技术是否会优化它们.从逻辑的角度来看,如果这些新字段依赖于您实体的候选键,那么它们就是属于它的事实.首先,您应该确保完全理解这些新字段对候选键的功能依赖性,以验证它们是否真的是关于每日页面浏览量的事实.如果是这样,决定将它们分成另一个表是性能优化,只有在达到性能目标时才能进行.
@H_502_2@通常,如果您不经常地从原始表中的其他列查询这些新列,则垂直分区很有用.通过将这些列放在与现有表共享相同PK的另一个表中,您可以在需要这些新列时直接查询它并获得更大的吞吐量,因为此新表上的每页磁盘上将有更多行因为原始表中的所有列都不会坐在那些行上.但是,如果您始终将这些列与原始表中的列一起查询,那么垂直分区将没有多大意义,因为您将始终必须使用外部联接来获取它们.来自磁盘上的表的页面独立地进入DBMS的缓冲池,从未预加入,因此即使数据固定在缓冲池中,也必须在每次查询执行时进行连接.在这种情况下,在原始表上使它们成为NULLABLE列将使DBMS存储引擎能够在NULL时有效地存储它们,并且无需加入检索.
@H_502_2@听起来像你的用例是后者,并将它们添加为原始表的NULLABLE是可行的方法.但与数据库设计中的其他所有内容一样,这取决于您做出正确决策,您需要知道您的预期工作量以及做出正确选择的依赖程度.垂直分区的正确用例的一个很好的例子是人员搜索面板,其中您的应用程序有一些很少填充的关于某人可能想要搜索但很少搜索的人的信息.如果您将这些信息放入另一个表中,那么您可以获得一些很好的性能选择.您可以编写搜索,以便您有2个查询 – 一个使用主要的,始终填充的信息仅用于搜索(如姓氏或ssn),另一个只在请求搜索时才加入非常不常填充的信息.要么
你可以利用DBMS优化器,如果它足够聪明,可以识别一组给定的主机变量,不需要外连接,也不会执行它,因此你只需要创建1个查询. @H_502_2@您使用的DBMS平台是什么?平台处理NULL列存储的方式,优化查询以及稀疏列支持的可用性(sql Server具有此功能)将影响决策.最后,我建议在测试环境中尝试使用生产规模的数据和工作负载,并查看哪些更好地实现了您的性能目标.
你可以利用DBMS优化器,如果它足够聪明,可以识别一组给定的主机变量,不需要外连接,也不会执行它,因此你只需要创建1个查询. @H_502_2@您使用的DBMS平台是什么?平台处理NULL列存储的方式,优化查询以及稀疏列支持的可用性(sql Server具有此功能)将影响决策.最后,我建议在测试环境中尝试使用生产规模的数据和工作负载,并查看哪些更好地实现了您的性能目标.