代码之家  ›  专栏  ›  技术社区  ›  Matt Lacey

如何设置新的SQL Server数据库以允许将来进行可能的复制?

  •  6
  • Matt Lacey  · 技术社区  · 16 年前

    我正在构建一个系统,它有可能需要500多个并发用户的支持,每一个用户每分钟都要进行几十次查询(选择、插入和更新)。基于这些要求和具有数百万行的表,我怀疑将来需要使用数据库复制来减少一些查询负载。

    在过去没有使用复制,我想知道在模式设计中是否需要考虑什么?

    例如,有人告诉我,有必要为主键使用guid来启用复制。这是真的吗?
    对于将要复制的数据库,在数据库设计方面有哪些特殊考虑或最佳实践?

    由于项目的时间限制,我不想在不需要复制时通过实现复制来浪费任何时间。(我现在有足够的明确问题要解决,而不必担心可能的问题。)但是,我不想在将来需要复制时进行可能可以避免的模式更改。

    关于这个主题的任何其他建议,包括学习实现复制的好地方,也将受到赞赏。

    3 回复  |  直到 16 年前
        1
  •  3
  •   Adam Robinson    16 年前

    而每一行都必须有一个 rowguid 列,你是 需要使用主键的GUID。实际上,你甚至不需要 一个主键(尽管你会因为没有创建一个而被石头砸死)。即使您将主键定义为guid,而不是 罗吉德 列将导致复制服务为您创建一个附加列。你肯定 可以 做这件事,这不是一个坏主意,但这不是必要的,也不是特别有利的。

    以下是一些提示:

    1. 保留桌子(或者,更确切地说, )大小很小;除非使用列级复制,否则将下载/上载一行的全部内容,即使只有一列发生更改。此外,较小的表使冲突解决更容易,也更不频繁。
    2. 不要使用顺序或确定性算法驱动的主键。 这包括标识列 . 是的,复制服务将自己处理标识列和分配密钥分配,但是您很头疼 不要 想要处理。这是一个很好的理由为您的主键使用一个guid。
    3. 不要让应用程序执行不必要的更新。这显然是一个坏主意,但从带宽使用和冲突解决的角度来看,这个问题在复制场景中呈指数级恶化。
        2
  •  1
  •   flesh    16 年前

    您可能希望对主键使用guid—在复制的系统中,在整个拓扑中,行必须是唯一的,guid pks是实现这一点的一种方法。

    这是一个短 article about use of GUIDs in SQL Server

        3
  •  1
  •   Remus Rusanu    16 年前

    我要说的是,您真正的问题不是如何处理复制,而是如何处理向外扩展,或者至少扩展为可查询性。虽然这个难题有各种各样的答案,但有一个答案是显而易见的: 使用复制。

    复制的问题,特别是合并复制的问题是 写入次数增加 在复制中。假设您有一个每秒处理100个查询(90个读取和10个写入)的系统。您希望向外扩展,然后选择复制。现在您有两个系统,每个系统处理50个查询、45个读取和5个写入 每个 . 现在,这些写操作必须被复制,因此实际的写操作数不是5+5,而是5+5(原始写操作),然后是另一个5+5(副本写操作),所以您有90次读操作和20次写操作。因此,当每个系统上的负载减少时,写入和读取的比率也增加了。这不仅改变了IO模式,而且最重要的是它改变了负载的并发模式。添加第三个系统,您将有90次读取和30次写入等等。很快,您将拥有比读取更多的写操作,复制更新延迟以及并发问题和合并冲突将使您的项目脱轨。其要点是,“快”比你预期的要快得多。很快就有足够的理由考虑扩大规模,因为无论如何,你所说的扩大规模最多是6-8家同行的6-8倍,而使用扩大规模增加6-8倍的容量将更快、更简单,甚至可能更便宜。

    记住这些都是 纯粹的理论 数字。实际上,复制基础结构不是免费的,它在系统上添加了自己的负载。需要跟踪写入,必须读取更改,必须存在分发服务器才能存储更改,直到分发到订阅服务器,然后必须写入更改并 调解可能的冲突 .这就是为什么我看到很少有部署能够声称通过基于复制的扩展策略获得成功。

    另一种选择是只扩展读操作,在这里复制 工作,通常使用事务复制,但日志传送或数据库快照镜像也可以。

    真正的选择是分区(即切分)。请求在应用程序中路由到适当的分区,并在包含适当数据的服务器上着陆。一个分区上需要反映在另一个分区上的更改通过异步(通常是基于消息传递的)方式发送。数据只能在分区内联接。要更详细地讨论我所说的内容,请阅读 how MySpace does it . 不用说,这样的策略对应用程序设计有很大的影响,不能简单地在v1之后进行粘合。