2016-11-30 149 views
0

这可能是一个愚蠢的问题。SQL Server表设计建议

SQL Server 2008 R2的一些效率建议,尽管这些服务器将在未来几个月内升级到2014年。我正在创建3个表格。

  • t1有许多不同类型的列和一个身份数字ID是主键。我预计这张桌子可以进入1000个行的低位。

  • t2与t1具有一对多的关系。它的主键将是一个t2 ID和t1 ID的组合。 t2数字ID将由前端应用程序发送,并且每个t1 ID都是唯一的。我预计这张桌子可以达到50000多排。除了这两个ID之外,它将包含一些不同长度的varchar列。

  • t3与t2具有一对多的关系。它的主键可以是t3 ID,t1 ID和t2 ID的组合。 t3数字ID将再次由前端应用程序发送,并且对于每个t2 ID将是唯一的。我预计这张桌子会达到几百万行。除了这3个ID之外,它将包含少量的日期或数字列。

我的问题是T2内应该我建立标识列,其T3将指基本上意味着T3的主键将是2列而不是3,即T3 ID和从时刻t2的标识列。这会更有效率吗? t2中的这个标识列是否应该编入索引?帮助加入?

我应该做其他事吗?

+0

您最常执行哪种搜索?你会使用't1'还是't2'键搜索't3'还是会使用来自其他字段的数据?您的答案可能会使代理或自然键成为更好的选择。 – Tony

+0

在** t2 **和** t3 **中,不太可能会独立执行任何搜索,虽然这可能会在将来出现,尽管我怀疑它。对这些表的查询将由连接到** t1 **驱动。绝大多数日间搜索将用于1个t1记录,并且对于该t1个ID以及对于那些t1 | t2个ID在t3中的任何内容。 – Darybrain

回答

0

我首先想到的担忧的声明

...的[T2 | T3]数字ID将通过前端应用 发送...

如果生成唯一标识符为了在数据库中使用,我建议你让数据库生成数字。除非您可以绝对确定该应用程序不会生成重复的ID。

在回答您的意见,使用代理键时(如果我理解正确的表结构)

 
    +----+ +----+ +----+ 
    | | | | | | 
    | t1 +---+ t2 +---+ t3 | 
    | | | | | | 
    +----+ +----+ +----+ 

keys: t1.id t1.id t1.id 
       t2.id t2.id 
         t3.id 

到代理键的变化不会改变t1(不需要),这里的区别; t2也将保持不变,但您需要将t2.id从行号更改为唯一号码主键[pk]。麻烦的是,你必须将'行号'作为另一个字段存储在表中。

主要区别在于t3只需要t2.pk及其自己的行标识符,而不是全部三个表标识符。

 
     +----+ +----+ +----+ 
     | | | | | | 
     | t1 +---+ t2 +---+ t3 | 
     | | | | | | 
     +----+ +----+ +----+ 

keys: t1.id  t2.pk t2.pk 
       t1.id t3.pk 

这会更好吗?我不确定。它也将取决于您对表格运行的查询的类型和频率(请参阅我对您问题的评论)。

如果你主要是由id查询,则第一个布局将是最好的 - 在t3查找行,而不必加盟t2t1。但是,如果您需要从其他表中获取信息来进行搜索,则代理键结构可能会使您的联接更加冗长。

最终,这是所有不成熟的优化(在查询性能方面),因为直到实现它才会知道执行得最好。

+0

他们应该永远是独一无二的。在前端,t2 ID基本上是每个t1记录中屏幕上的行号。当数据在前端内更改时,应用程序应检查记录是否存在,以查看是否需要生成动态更新或插入SQL语句。你会建议什么结构?如果我使用单列身份作为主键,我仍然需要根据表格存储[t1 | t2]或[t1 | t2 | t3]的组合。在数据库中确保这些内容不重复的最好方法是什么? – Darybrain

+0

@Darybrain - 我已经更新了我的回答以回应您的评论。 – Tony

0

我通常为此创建标识int主键,并使其成为聚簇索引。

我不会有t2或t3有一个id是复合,而是一个单独的字段,并设置一个外键约束。

聚集索引和外键将成为您需要的所有索引(用于连接)。您可能需要基于您的查询的其他索引。

我已经在具有数亿行的表上设置了它,并在1秒内获得查询结果。

+0

以t2为例,如果我创建一个标识列作为集群主节点,我仍然需要从表中的前端应用程序获得t1标识和t2标识(基本上是每个t1记录的行号)。如何确保两者的组合不会重复?这两个领域会在你提到的限制之内吗? – Darybrain

+0

@Darybrain - 您可以在关键字段使用'UNIQUE'索引来防止重复,同时拥有一个数字键字段。 – Tony

+0

为什么前端生成密钥?除非应用程序正在控制多个数据存储,否则我不明白需要。 @Darybrain也是正确的,你可以添加一个唯一的约束来防止重复,但这会导致错误,你将不得不陷入和处理。关键问题是为什么前端对RDBMS有任何控制。 –