如何在SQL Server 2008中以最佳方式存储以下SQL数据

Pat*_*ick 2 database optimization performance sql-server-2008

我正在创建一个人们可以发表文章的页面.当用户发布文章时,它会显示在列表中,例如Stack Overflow上的相关问题(当您添加新问题时).这很简单.

我的问题是我有两种类型的用户.1)未注册的私人用户.2)一家公司.

未注册的用户需要输入他们的姓名,电子邮件和电话.公司用户只需输入公司名称/密码即可.相当简单.

我需要减少过多的数据库使用量,并尝试优化数据库并有效地构建表.

现在我手头的问题:

所以我有一张表格,里面有关于公司ID (guid), Name, email, phone等的信息.

我正在考虑制作一个名为文章的表,其中包含ArticleID,标题,内容和发布日期.

一个表格,其中包含有关未注册用户,ID,姓名,电子邮件和电话的信息.

如何将articles表绑定到company/unregistered users表.是否可以创建一个包含2个值的整数,1 =未注册的用户和2 =公司,然后是一个具有指定用户/公司ID号的字段.看起来您需要大量额外的代码来查询数据库.性能?我怎么能把这篇文章和联系信息一起归还?您还应该能够返回特定公司的所有文章.

表公司将是:

ID (guid), company name, phone, email, password, street, zip, country, state, www, description, contact person and a few more that i don't have here right now.
Run Code Online (Sandbox Code Playgroud)

表未注册用户:

ID (guid), name, phone, email
Run Code Online (Sandbox Code Playgroud)

表文章:

ID (int/guid/short guid), headline, content, published date, is_company, id_to_user
Run Code Online (Sandbox Code Playgroud)

有更好的方法吗?

我正在寻找的品质是:性能,易于查询和易于维护(添加新字段,索引等)

Rem*_*anu 11

理论

您描述的问题在数据建模理论中称为表继承.在Martin Fowler的书中,解决方案是:

因此,从理论和行业实践的角度来看,所有三种解决方案都是可以接受的:一个表海报带有列NULLable列(即单个表),三个表海报,公司和人员(即类继承)和两个表公司和人员(即具体的继承).

现在,为了利弊.

NULL列的成本

记录结构在内部存储引擎:记录剖析中讨论:

NULL位图

  • 记录中列数的两个字节
  • 记录中每列存储一位的可变字节数,无论该列是否可为空(这与SQL Server 2000不同且简单,只有每个可空列一位)

因此,如果您至少有一个NULLable列,则需要支付每个记录中NULL位图的开销,至少为3个字节.但如果您有1列或8列,则成本相同!第9个NULLable列将向每个记录中的NULL位图添加一个字节.在估算聚集指数的大小中描述了公式:2 +((Num_Cols + 7)/ 8)

性能驱动因素

在数据库系统中,实际上只有一个因素可以提高性能:扫描的数据量.查询计划扫描的记录有多大,以及它必须扫描多少条记录.因此,要提高性能,您需要:

  • 缩小记录:减少数据大小,覆盖包括索引,垂直分区
  • 减少扫描的记录数:索引
  • 减少扫描次数:消除连接

现在,为了分析这些标准,您的帖子中缺少一些内容:流行的数据访问模式,即.数据库将被击中的最常见查询.这取决于您在网站上显示帖子的方式.考虑以下可能的方法:

  • 帖子首页:喜欢SO,最近的帖子页面有标题,摘录,发布时间和作者基本信息(名称,gravatar).要显示此页面,您需要将作者与帖子一起加入,但您只需要作者姓名和gravatar.单表继承和类表继承都可以工作,但具体的表继承会失败.这是因为您无法承担这样的查询来进行条件连接(即加入发布到公司人员的文章),这样的查询将不是最佳的.

  • 每位作者的帖子:用户必须先登录,然后他们才能看到自己的帖子(这对于非公开的面向帖子的网站很常见,例如考虑事件跟踪).对于这样的设计,所有三个表继承方案都可以工作.

结论

有一些一般的性能考虑(即缩小数据)要考虑,但缺少关键信息:您将如何查询数据,您的访问模式.必须针对访问模式优化数据模型:

  • 公司和人员中的哪些字段将显示在站点的登录页面上(即最常见和性能关键的查询)?您不想加入5个表来显示这些字段.
  • 用户信息页面上是否只需要一些公司/个人信息字段?也许可以将表垂直划分为CompaniesExtra和PersonsExtra表.或者使用一个覆盖常用字段的索引(这种方法简化了代码,更容易保持一致,代价是数据重复)

PS

不用说,不要使用guid作为id.除非您正在构建分布式系统,否则由于宽度过大,它们是一个可怕的选择.碎片也是一个潜在的问题,但可以通过使用顺序guid来缓解.