【问题标题】:Add additional address type to existing table向现有表添加其他地址类型
【发布时间】:2018-07-09 05:23:16
【问题描述】:

假设我有这张表在现场生产多年:

[UserContactInfo]
[UserContactInfoId] uniqueidentifier not null
[UserId] uniqueidentifier not null PK to [User] table
[FirstName] varchar(50) null
[LastName] varchar(50) null
[Street] varchar(200) null
[City] varchar(50) null
[State] varchar(2) null
[Zip] varchar(10) null
many other fields

目前总的最大行字节数目前只有 1K - 远低于每行 8K 的限制。

目前大约有 1000 万行或大约 9GB。

假设数据迁移非常痛苦,因为表很大,需要在事务中运行所有操作,以及扩展数据库维护窗口的业务负面影响。

现在我想添加邮寄地址。

选项 1:我可以添加其他列:

[MailingStreet] varchar(200) null
[MailingCity] varchar(50) null
[MailingState] varchar(2) null
[MailingZip] varchar(10) null

选项 2:我可以输入地址:

[AddressType] byte not null

对应于写入时强制执行的 C# 枚举

enum AddressType {
Physical=1,
Mailing=2}

并在数据库维护作业期间运行脚本以将所有现有行更新为 [AddressType]=1

我的问题是哪个选项会更好?

选项 1 否定:

(a) 最初,所有行都将有 4 个未使用的列,即使在多年后,实际数据的行数也可能很低。但我相信 SQL Server 只需要一个位来记录 col 是否为空。 (b) 它将行稍微靠近 8K 边界(尽管还有很长的路要走) (c) 如果我们需要其他地址类型,则意味着更多列

选项 2 否定:

(a) 未来某个时候,该表的行数可能会增加一倍。我可以在[UserId],[AddressType] 上添加一个复合索引,并且我确信 SQL Server 有各种技巧来优化性能,但我是否可以怀疑它是否会接近一半大小的表的性能?

是否有人对选项 1 与选项 2 的权衡有更深入的了解?

【问题讨论】:

  • 您的 1a 和 2a 点相互矛盾。 1a 表示您不可能有很多邮寄地址。 2a 表示几乎每个人都会拥有两个地址。是哪个?

标签: sql-server database-design database-schema database-performance sqlperformance


【解决方案1】:

选项 2 将是更标准的方法。这意味着您不会重复列定义(考虑如果您决定 city 需要扩展到 60 个字符会发生什么),并且更适合以后添加(更多地址类型)。

它还为您提供了更大的查询灵活性。如果您有任何查询出于查询的目的将所有地址视为“相等”(地址的用途无关紧要),那么编写起来很简单,如果您需要限制特定的地址类型,您可以在WHERE 子句中应用一个简单的过滤器。

与选项 1 相比 - 如果您想平等地查询所有地址,那么您需要在 WHERE 子句中单独命名所有地址列,并且需要注意避免混合单个元素(例如,如果您尝试找到Tampa, CO 的所有用途,您需要确保不要将邮寄地址中的城市与实际地址的状态混淆)。如果你想让人们过滤到个别地址类型,你必须翻译例如UI 选择到单独的列名中,通常会导致需要动态 SQL。


(根据用例,您可能需要单独决定名字和姓氏以及它们是否与地址或用户相关联,以决定它们是否仍属于此表,因为它正在建模多个地址)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-24
    • 2018-09-28
    • 1970-01-01
    • 2013-08-24
    • 2014-07-06
    • 2010-12-18
    • 2019-10-28
    相关资源
    最近更新 更多