查询MySQL information_schema数据库是查找相关表的好方法吗?
我有一个被许多其他表上的外键引用的表。在我的程序中,如果要删除这些行之一,我需要首先搜索依赖项并将其呈现给用户"此对象取决于表y中的x,表q中的z等"。我还希望具有该表的外键的表的数量会随着时间的推移而显着增加。
information_schema数据库是搜索所有依赖项的好方法吗?我试图查询它以检索所有包含对我的表有外键的表的列表,然后遍历结果并从每个表中选择所有表,其中外键值与用户尝试删除的值相匹配。我的查询如下:
SELECT * FROM `KEY_COLUMN_USAGE` kcu LEFT JOIN TABLE_CONSTRAINTS tc ON tc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME WHERE tc.CONSTRAINT_TYPE='FOREIGN KEY' AND (kcu.REFERENCED_TABLE_SCHEMA='db') AND (kcu.REFERENCED_TABLE_NAME = 'testtable')
它非常适合确定我需要搜索的表,但是它非常慢。在开发计算机上执行查询最多需要大约1到2秒的时间,在生产服务器上运行查询时,查询会减少很多,但仍然很慢。
我需要知道以这种方式使用information_schema是否不是一个好主意。如果没有,如何从查询中提取更好的性能。我使用的是固态查询还是有更好的方法呢?如果是这样,我应该如何从可维护性的角度来解决这个问题。
解决方案
我认为这正是INFORMATION_SCHEMA所针对的。
德沃夏克(Dvorak)是正确的,INFORMATION_SCHEMA是为此目的而设计的。
关于性能问题,有几种方法可以改善性能
- 简单的方法,但并不会带来很多改进:将信息存储在静态变量中。至少每页查询一次
- 使用持久性缓存:备用的PHP缓存可以为我们提供帮助(请参阅http://fr3.php.net/manual/zh/book.apc.php)。我们将从信息架构中获得的信息很适合存储在持久性缓存中。
- 使用ORM库,例如doctrine(http://www.doctrine-project.org/)。查看文件lib / Doctrine / Import / Mysql.php会发现它确实可以满足需求,甚至还有更多。
为此,在静态或者管理系统上可以使用INFORMATION_SCHEMA,但不建议将其用于事务性应用程序功能,因为INFORMATION_SCHEMA可能已实现为本机系统数据字典上的视图。
这对于CRUD库执行通用的" D"操作将是一种效率很低的方法。同样,在许多系统上(想到Oracle),系统数据字典实际上是作为较低级别数据结构上的视图实现的。这意味着本机系统数据字典也可能不适合于此。系统数据字典也可能因版本而异。
应该很少有直接删除记录及其所有子级的正确方法。作为通用函数执行此操作可能不会给我们带来什么实际的好处。另外,如果数据库中不存在外键,我们将得到孤立的孩子,因为这种方法依赖于FK的存在来知道要删除哪些孩子。
使我的应用程序慢下来,但是我需要外键约束数据才能使所有内容正确地结合在一起。
查询信息架构时,延迟是巨大的,并且要使一个用于立即加载的页面在3-4秒内加载。
好吧,至少在MySQL 5中可以使用外键约束,这可以使应用程序开发更可靠,但显然要付出一定的代价。
自2006年以来,根据我的Google搜索,人们一直在抱怨这个问题,并且问题仍然存在-绝非易事;-(
我也在研究这个。我想对某些CRUD使用KEY_COLUMN_USAGE。而且我注意到这些表上没有可用的键或者索引。这可能是性能不佳的原因。