数据库设计问题 - 哪个是最佳解决方案?

时间:2010-11-19 12:09:14

标签: database database-design firebird firebird2.1 database-indexes

我正在使用Firebird 2.1,我正在寻找解决此问题的最佳方法。

我正在写一个日历应用程序。不同用户的日历条目存储在一个大的Calendar表中。每个日历条目都可以设置一个提醒集 - 只有一个提醒/条目。

据统计,随着时间的推移,日历表可能会增长到数十万条记录,而提醒则会少得多。

我需要不断查询提醒。

哪个是最佳选择?

A)将提醒信息存储在日历表中(在这种情况下,我将查询数十万条IsReminder = 1的记录)

B)创建一个单独的Reminders表,其中只包含设置了提醒的日历条目的ID,然后使用JOIN操作查询这两个表(或者可以在它们上创建一个视图)

C)我可以在Reminders表中存储有关提醒的所有信息,然后只查询该表。缺点是需要在两个表中复制一些信息,比如为了显示提醒,我需要知道并将事件的启动时间存储在Reminders表中 - 因此我维护两个具有相同值的表。

您怎么看?

还有一个问题:Calendar表将包含多个用户的日历,仅由UserID字段分隔。由于只有4-5个用户,即使我在这个字段上放了一个索引,它的选择性也会非常糟糕 - 这对于拥有数十万条记录的表来说并不好。这里有解决方法吗?

谢谢!

3 个答案:

答案 0 :(得分:2)

这三种选择都有优点和缺点。这个最好取决于你没有提供的细节。一般情况下,如果您设置的索引允许正确的检索策略,请不要过于担心选择十万个中的三个或四个条目。如果不理解索引,无论你做出哪三个选择,你都可能遇到麻烦。

如果是我,我会选择B.我还会在表格中存储提醒的任何属性以便提醒。

要特别注意您是单独使用EventId还是通过(UserId,EventId)识别事件。如果选择后者,则可以使用复合主键作为Event表。不要太担心复合主键,尤其是Firebird 如果声明复合主键,请注意声明(UserId,EventId)与声明(EventId,UserId)不会产生相同的后果。它们在逻辑上是等价的,但自动生成的索引的结构在两种情况下会有所不同。

这反过来会影响查询的速度,例如“查找给定用户的所有提醒”。

同样,如果是我,我会避免选择C.将有害冗余引入模式时,在进行更新数据时需要对其进行一些非常仔细的编程。否则,您最终可能会在数据库的不同位置存储相同事实的矛盾版本的数据库。

而且,如果您真的想知道对性能的影响,请尝试所有三种方法,加载测试数据,并自己做基准测试。

答案 1 :(得分:0)

我认为您需要创建逼真的虚假用户数据,并衡量您希望运行的一些典型查询的差异。

索引,查询优化和您需要的查询结果类型可以产生很大的不同, 所以如果不了解更多内容就不容易说出什么是最好的。

答案 2 :(得分:0)

选择选项(A)时,您应该

  • 提供“IsReminder”的索引(或IsReminder的综合索引,UserId,最适合您的预期查询)
  • 确保您的查询使用此索引

如果您要存储的每个提醒都有多个布尔标志(例如,用户在事件发生前应通知的分钟数),则选项B优于A。但是,您应该猜测在程序中经常需要加入两个表。

如果可以,请避免使用选项C.如果您不想对所有三种情况进行基准测试,我建议根据所描述的情况从A或B开始,并且您选择的解决方案可能足够快,所以你不必为其他案件而烦恼。