php – 智能(?)数据库缓存

我见过几个数据库缓存引擎,它们都非常愚蠢(即:保持此查询缓存X分钟)并要求在执行INSERT / UPDATE / DELETE查询后手动删除整个缓存存储库.

大约2或3年前,我为我正在开发的项目开发了一个替代数据库缓存系统,这个想法基本上是使用正则表达式来查找特定SQL查询中涉及的表:

$query_patterns = array
(
    'INSERT' => '/INTO\s+(\w+)\s+/i',
    'SELECT' => '/FROM\s+((?:[\w]|,\s*)+)(?:\s+(?:[LEFT|RIGHT|OUTER|INNER|NATURAL|CROSS]\s*)*JOIN\s+((?:[\w]|,\s*)+)\s*)*/i',
    'UPDATE' => '/UPDATE\s+(\w+)\s+SET/i',
    'DELETE' => '/FROM\s+((?:[\w]|,\s*)+)/i',
    'REPLACE' => '/INTO\s+(\w+)\s+/i',
    'TRUNCATE' => '/TRUNCATE\s+(\w+)/i',
    'LOAD' => '/INTO\s+TABLE\s+(\w+)/i',
);

我知道这些正则表达式可能有一些缺陷(当时我的正则表达式技术非常漂亮)并且显然与嵌套查询不匹配,但是因为我从不使用它们对我来说不是问题.

无论如何,在找到所涉及的表之后,我将按字母顺序对它们进行排序,并使用以下命名约定在缓存存储库中创建一个新文件夹:

+table_a+table_b+table_c+table_...+

在SELECT查询的情况下,我将从数据库中获取结果,serialize()它们并将它们存储在相应的缓存文件夹中,因此例如以下查询的结果:

SELECT `table_a`.`title`, `table_b`.`description` FROM `table_a`, `table_b` WHERE `table_a`.`id` <= 10 ORDER BY `table_a`.`id` ASC;

将存储在:

/cache/+table_a+table_b+/079138e64d88039ab9cb2eab3b6bdb7b.md5

MD5是查询本身.在随后的SELECT查询中,结果对于获取来说是微不足道的.

在任何其他类型的写查询(INSERT,REPLACE,UPDATE,DELETE等)的情况下,我将glob()所有在其名称中具有matched_table的文件夹都删除所有文件内容.这样就没有必要删除整个缓存,只删除受影响和相关表使用的缓存.

系统工作得很好,性能差异很明显 – 虽然项目的读取查询比写入查询多得多.从那时起,我开始使用事务,FK CASCADE UPDATES / DELETES,从未有时间完善系统,使其能够使用这些功能.

我过去使用过MySQL Query Cache,但我必须说性能甚至没有比较.

我想知道:我是唯一一个在这个系统中看到美女的人吗?有没有我可能不知道的瓶颈?为什么流行的框架如CodeIgniterKohana(我不知道Zend Framework)有这样的基本数据库缓存系统?

更重要的是,您认为这是值得追求的功能吗?如果是的话,有什么我可以做/用来使它更快(我的主要关注点是磁盘I / O和(de)查询结果的序列化)?

我感谢所有的投入,谢谢.

解决方法:

我可以看到这个解决方案的美感,但是,我相信它只适用于一组非常具体的应用程序.不适用的场景包括:

>使用级联删除/更新或任何类型的触发器的数据库.例如,您对表A的DELETE可能会导致表B中的DELETE.正则表达式永远不会捕获这个.
>从不通过您的缓存无效方案的点访问数据库,例如, crontab脚本等.如果您决定跨机器实现复制(引入只读从属),它也可能会干扰缓存(因为它不会通过缓存失效等)

即使这些场景对您的情况不太现实,它仍然回答了为什么框架不实现这种缓存的问题.

关于这是否值得追求,这一切都取决于您的申请.也许您愿意提供更多信息?

上一篇:Docker环境下编译android源码|编译可运行xposed


下一篇:http basic authorization