2014-03-04 40 views
0

一些背景触发复杂的配置条件

我们有哪些可选集成到其他几个系统的系统。我们的系统将数据从MySQL数据库转移到其他系统。不同的客户需要传输不同的数据为了不触发这些外部系统不必要的传输(当没有相关数据发生变化时),我们有一个“导出”表,其中包含任何客户感兴趣的所有信息以及运行SQL文件中定义的SQL查询的服务导出表中的数据与其他表中的数据相匹配并更新导出表,我们并不满足以下几种原因的解决方案:

  • 没有客户使用超过这些列的一小部分,尽管每列至少有一个客户使用。
  • 随着数据库的增长,该服务正在对系统造成越来越大的压力。即使没有客户拥有特别大量的数据(所有相关表中大约15000行,最大值),某些服务器在该服务比较数据时会完全冻结,这可能需要2分钟(!)。我们担心如果我们得到一个拥有大量数据的客户会发生什么。通过创建一些索引和改进SQL查询可以提高性能,但我们觉得这是从错误的方向攻击问题。
  • 它不是很灵活,也不可扩展。每当客户有兴趣传送其他客户以前没有感兴趣的数据(这种情况很多)时,必须添加新的列,只是感觉... icky。我不知道它有多重要,但我们目前在这张表中最多有37列,而且还在不断增长。

我们想要做的

取而代之的是什么,我们希望有一个非常精简下来的“出口”表中仅包含最低限度的信息,即表和行的主键已更新,此行应该导出到的系统以及一些时间戳。然后,每当更新配置为保证更新的列时,每个相关表中的触发器都会更新此导出表。这种配置应该从另一个表(其中,在将来某个时候,可以从我们的网页图形用户界面来配置)来读取,看起来像这样:

+--------+--------+-----------+ 
| system | table | column | 
+--------+--------+-----------+ 
| 'sys1' | 'tbl1' | 'column1' | 
+--------+--------+-----------+ 
| 'sys2' | 'tbl1' | 'column2' | 
+--------+--------+-----------+ 

现在,TBL 1触发将从此表中读取时,行更新。上面的配置应该意味着如果tbl1中的column1发生了变化,那么应该更新sys1的导出行,如果column2也已更改,那么sys2的导出行也应该更新,等等。

到目前为止,它似乎都可行,但当你不是SQL天才时有点棘手。然而,我们希望能够定义一些更复杂的条件,至少像“column3 ='Apple'或column3 ='Banana'”,这是问题的核心......

所以,总结一下:

  • 什么是允许以这种方式配置触发器的最佳方式?
  • 我们疯了吗?触发器是否是正确的方式,或者我们应该坚持我们的服务,抨击某些索引并吸取它?还是有第三种选择?
  • 我们期望看到多少性能提升? (这是否值得?)
+0

嗯,我刚刚发现动态SQL不允许在触发器内......真是无赖。猜猜它已经回到了绘图板。 – moggizx

+0

我们得出的结论是,最好的方法是从PHP生成静态触发器,而实际上这可能是更好的解决方案。 – moggizx

回答

0

这实际上是不可能的,因为SQL中不支持动态SQL。因此我们想出了从PHP读取配置表并生成“静态”触发器。我们将尝试有2桌,一个为列和一个条件,像这样:

Columns 
+--------+--------+-----------+ 
| system | table | column | 
+--------+--------+-----------+ 
| 'sys1' | 'tbl1' | 'column1' | 
+--------+--------+-----------+ 
| 'sys2' | 'tbl1' | 'column2' | 
+--------+--------+-----------+ 

Conditions 
+--------+--------+-------------------------------------------+ 
| system | table |     condition    | 
+--------+--------+-------------------------------------------+ 
| 'sys1' | 'tbl1' | 'column3 = "Apple" OR column3 = "Banana"' | 
+--------+--------+-------------------------------------------+ 

然后,只需建立一个这样的语句在PHP(伪代码):

DROP TRIGGER IF EXISTS `tbl1_AUPD`; 

CREATE TRIGGER `tbl1_AUPD` AFTER UPDATE ON tbl1 FOR EACH ROW 
    BEGIN 
    IF (*sys1 columns changed*) AND (*sys1 condition1*) THEN 
     updateExportTable('sys1', 'tbl1', NEW.primary_key, NEW.timestamp); 
    END IF; 
    IF (*sys2 columns changed*) THEN 
     updateExportTable('sys2', 'tbl1', NEW.primary_key, NEW.timestamp); 
    END IF; 
END; 

这似乎对我们来说是最好的解决方案,甚至可能比我所要求的更好,但如果有人有更好的建议,我全都是耳朵!