2012-02-19 36 views
9

我正在构建一个系统,它是用于存储来自许多其他系统的数据的中央存储库。当更新其他系统数据时,需要同步过程来更新中央存储库。将会有一个sync_action表来标识中央仓库需要同步的系统以及所需的同步类型。有一组定义好的行为是不太可能改变的。下面是一个瘦身系统。外键与检查约束的完整性

当我看到它,我可以以两种方式接近这一点:

选项1)有一个具有可用的3个行动的Action表。有一个sync_action表,它使用外键来引用所需的操作。

表:系统

ID Description 
1 Slave System 1 
2 Slave System 2 

表:行动

ID Description 
1 Insert 
2 Update 
3 Delete 

表:Sync_action

ID Action System 
1  1  1 
2  2  1 

选项2)而不是外键在sync_action.action列上使用检查约束,因此只能插入操作Insert/Update/Delete

表:Sync_action

ID Action System 
1 Insert 1 
2 Update 1 

我想知道进入确定完整性约束,外键VS检查约束之间进行选择时,这是一个更好的方法是什么因素。有类似的线程,但我没有发现它们足够明确。这可能是因为它的解释,但任何想法,将不胜感激。

干杯

+3

我通常更喜欢FK和表格关系,因为:它们更“可见”(例如,显示在关系图中)并且它们“更具可扩展性”(取决于数据,而不是条件,并且可以具有附加的“额外”信息),并且它们通常是“更可映射的”(对于您选择的任何ORM)。在这样的情况下,我*也考虑使用非代理PK(它确实是一个“静态数据”表),也许只是一个“单一有意义的字符”,如“我”,“U”,“D”。如果在另一个表中,那么也可以具有“自我记录”标签列。 – 2012-02-19 08:35:15

+0

欢迎使用StackOverflow:如果您发布代码,XML或数据样本,**请**在文本编辑器中突出显示这些行,然后单击编辑器工具栏上的“代码样本”按钮(“{}”)语法突出它! – 2012-02-19 10:29:56

+2

我同意'pst' - 如果你需要添加第四个,第五个动作怎么办?如果你有一个单独的“Action”表,就像添加一行一样简单。如果你有检查限制,你需要放弃并重新创建这些 - 这是更多的工作,更麻烦。我没有看到任何好的论点,**针对具有单独的“操作”表并使用FK约束强制执行参照完整性 - 数据库擅长这一点! (这是他们的核心业务!) – 2012-02-19 10:31:24

回答

6

评论员似乎umanimously同意:

一般来说,最好有一个FOREIGN KEY约束至(或多或少是静态的)参考表。理由:

  • 该约束很容易“扩展”。要添加或删除选项,您只需添加或删除参考表中的一行。您不必删除约束并重新创建它。更甚者,如果您在其他表格中的相似列中也有相同的约束。

  • 您可以附加额外的信息(更多列),如果需要可以由应用程序读取。

  • ORM可以更好地处理这些约束(阅读:意识到)。他们只需要读取一张表格,而不是元数据。

  • 如果要更改操作代码,级联效果将处理其他(可能很多)表中的更改。无需编写UPDATE查询。

  • 一个特定的DBMS尚未实现CHECK约束(羞耻),虽然它确实有FK。

正如@pst提到的(我更喜欢这种方法),您可以使用合理的代码而不是代理整数ID。所以,你的表可能是:

表:系统

SystemID Description 
1  Slave System 1 
2  Slave System 2 

表:行动

ActionCode Description 
I   Insert 
U   Update 
D   Delete 

表:SyncAction

ID ActionCode SystemID 
1  I   1 
2  U   1 
+0

在我现在的工作场所,我们已经发展出这样一个系统,而且工作得很好。主键的类型指示该表是“参考数据”(非整数pk,由tech手动更新)还是普通数据(整数代理pk,可由应用程序管理)。 – araqnid 2012-02-19 13:45:50

3

我认为你混淆了外键约束检查约束之间的差异。

一个外键约束有强制参照完整性和检查约束约束列只包含有效数据。在你的情况下,这可能看起来像一个微小的差异,但如果我们稍微抽象它,我希望更清楚。

如果我们考虑一个表users与列user_id, user_name, address_id, join_date, active, last_active_month;我认识到,这不一定是做事的最佳方式,但它可以满足我试图提出的观点。

在这种情况下,将address_id作为约束是非常荒谬的。此列可以具有任意数量的值。但是,active,假设我们想要一个布尔型y/n只能有两个可能的值并且last_active_month只能有12个可能的值。在这两种情况下,拥有外键是完全荒谬的。只有一定数量的值,并且根据数据的定义,您将包含这些值不能更改。

在你的情况,而你可以走了检查约束,除非你可以绝对肯定说的actions数量将永远不会改变外键是要走的正确途径。


在一个稍微分开的问题上,正如@pst提到的,我看到你被代理键怪物吃掉了。虽然这可以导致性能改进,但在您设想的大小(3个值,insert/update/delete)或更大的表中,它所要做的只是掩盖您想要实现的功能。

这并不容易看

ID Action System 
1  1  1 
2  2  1 

,看看发生了什么事情,但:

ID Action System 
1 insert  1 
2 update  1 

是更容易阅读;你可能也想考虑为system列做同样的事情 - 我可能会这么做,尽管可能值的数量在这方面略有增加。只是我个人对此事的想法......