我有一个表,在许多其他表上由外键引用。在我的程序中,如果我想删除其中一行,我需要首先搜索依赖项并将它们呈现给用户 - “此对象依赖于表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是不是一个坏主意。如果没有,我如何从查询中提取更好的性能。我使用的查询是否可靠或有更好的方法吗?如果是这样,我应该如何从可维护性角度解决这个问题。
答案 0 :(得分:4)
Dvorak是对的,INFORMATION_SCHEMA就是为了这个目的。
关于您的性能问题,有几种方法可以改善性能
简单的方法,但不会有太大的改进: 将信息存储在静态变量中。至少查询每页只会发生一次
使用持久性缓存:替代PHP缓存可以帮助您(请参阅http://fr3.php.net/manual/en/book.apc.php)。 您将从信息模式中获取的信息是存储在持久缓存中的理想选择。
使用ORM库,例如doctrine(http://www.doctrine-project.org/) 查看文件lib / Doctrine / Import / Mysql.php将显示它完全符合您的需求,等等。
答案 1 :(得分:3)
我认为这正是INFORMATION_SCHEMA的目的。
答案 2 :(得分:3)
我也在研究这个问题。我想将KEY_COLUMN_USAGE用于某些CRUD。我注意到这些表上没有任何键或索引。这可能是表现不佳的原因。
答案 3 :(得分:2)
在静态或管理系统上使用INFORMATION_SCHEMA是可以的,但不建议用于事务应用程序功能,因为INFORMATION_SCHEMA可能在本机系统数据字典之上实现为视图。
这对于为CRUD库执行通用“D”操作是一种相当低效的方法。此外,在许多系统上(Oracle会想到),系统数据字典实际上是作为较低级别数据结构的视图实现的。这意味着本机系统数据字典也可能不适用于此。系统数据字典也可能随版本而变化。
应该有相对较少的情况,直接'删除'记录及其所有孩子是正确的方法。将此作为通用功能可能会让您获得实用性。此外,如果数据库中没有外键,您将看到孤儿正在撒谎,因为这种方法依赖于FK的存在来知道要删除哪些孩子。
答案 4 :(得分:1)
减慢我的应用程序爬行速度,但我需要外键约束数据才能正确连接所有内容。
查询信息架构时,延迟很大,并且制作一个过去即时加载的页面,在3-4秒内加载。
嗯,至少在MySQL 5中可以使用外键约束,这样可以实现更强大的应用程序开发,但显然需要付出代价。
自2006年以来,基于我的Google搜索,人们一直在抱怨这个问题,问题仍然存在 - 一定不能轻易解决; - (
答案 5 :(得分:1)
如果在谷歌上找到这个,那么值得注意的是,information_schema偶尔会与show create table
返回的内容不同。
在DBA Stack Exchange thread中有一个很好的例子。执行此命令后:
create table rolando (num int not null, primary key (num) using hash);
检查结果:
mysql> show create table rolando\G
(...)
PRIMARY KEY (`num`) USING HASH
mysql> show indexes from rolando;
(...) | Index_type | (...)
(...) | BTREE | (...)