从理论上讲,INFORMATION_SCHEMA是SQL标准中指定的一组视图,允许用户检查系统的元数据。如何在MySQL中实现?
连接到全新安装时,我会看到两个数据库:mysql
和information_schema
。在数据库SHOW CREATE TABLE
上使用语句后information_schema
,看起来它并未实现为一组视图,而是使用了基本表。这个假设正确吗?还是有其他对用户隐藏的系统表?
从理论上讲,INFORMATION_SCHEMA是SQL标准中指定的一组视图,允许用户检查系统的元数据。如何在MySQL中实现?
连接到全新安装时,我会看到两个数据库:mysql
和information_schema
。在数据库SHOW CREATE TABLE
上使用语句后information_schema
,看起来它并未实现为一组视图,而是使用了基本表。这个假设正确吗?还是有其他对用户隐藏的系统表?
Answers:
该INFORMATION_SCHEMA数据库由使用MEMORY存储引擎临时表了。
示例:这是MySQL 5.5.12(Windows版)中的表INFORMATION_SCHEMA.TABLES
mysql> show create table information_schema.tables\G
*************************** 1. row ***************************
Table: TABLES
Create Table: CREATE TEMPORARY TABLE `TABLES` (
`TABLE_CATALOG` varchar(512) NOT NULL DEFAULT '',
`TABLE_SCHEMA` varchar(64) NOT NULL DEFAULT '',
`TABLE_NAME` varchar(64) NOT NULL DEFAULT '',
`TABLE_TYPE` varchar(64) NOT NULL DEFAULT '',
`ENGINE` varchar(64) DEFAULT NULL,
`VERSION` bigint(21) unsigned DEFAULT NULL,
`ROW_FORMAT` varchar(10) DEFAULT NULL,
`TABLE_ROWS` bigint(21) unsigned DEFAULT NULL,
`AVG_ROW_LENGTH` bigint(21) unsigned DEFAULT NULL,
`DATA_LENGTH` bigint(21) unsigned DEFAULT NULL,
`MAX_DATA_LENGTH` bigint(21) unsigned DEFAULT NULL,
`INDEX_LENGTH` bigint(21) unsigned DEFAULT NULL,
`DATA_FREE` bigint(21) unsigned DEFAULT NULL,
`AUTO_INCREMENT` bigint(21) unsigned DEFAULT NULL,
`CREATE_TIME` datetime DEFAULT NULL,
`UPDATE_TIME` datetime DEFAULT NULL,
`CHECK_TIME` datetime DEFAULT NULL,
`TABLE_COLLATION` varchar(32) DEFAULT NULL,
`CHECKSUM` bigint(21) unsigned DEFAULT NULL,
`CREATE_OPTIONS` varchar(255) DEFAULT NULL,
`TABLE_COMMENT` varchar(2048) NOT NULL DEFAULT ''
) ENGINE=MEMORY DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
这些表没有物理文件夹,甚至没有.frm文件。您不能mysqldump它。您不能删除它。您不能向其中添加表。您不能从中删除表。那么,表在哪里?
INFORMATION_SCHEMA数据库中的所有表都作为MEMORY存储引擎表直接存储在内存中。它们完全在MySQL内部,因此.frm机制在mysqld中处理。在我的回答中,我首先显示了INFORMATION_SCHEMA.TABLES的表布局。它是内存中的临时表。使用存储引擎协议对其进行操作。因此,当mysqld关闭时,所有的information_schema表都被删除。启动mysqld时,所有information_schema表都将创建为TEMPORARY表,并为mysql实例中的每个表重新填充元数据。
在INFORMATION_SCHEMA数据库首先在MySQL 5.0中引入要给大家介绍的其他存储引擎的表获得的元数据。例如,您可以执行SHOW DATABASES来获取数据库列表。您也可以像这样查询它们:
SELECT schema_name database FROM information_schema.schemata;
您可以通过两种方式检索数据库中的表名:
use mydb
show tables;
要么
SELECT table_name from information_schema.tables WHERE table_schema = 'mydb';
自成立以来,MySQL已将INFORMATION_SCHEMA数据库扩展为具有进程列表(自MySQL 5.1起)。您实际上可以查询流程列表,以查找仍在运行至少10分钟的长时间运行的查询:
SELECT * FROM information_schema.processlist WHERE time >= 600\G
您可以使用INFORMATION_SCHEMA来做每件事:
使用特定的存储引擎获取所有表的计数:
SELECT COUNT(1) TableCount,IFNULL(engine,'Total') StorageEngine
FROM information_schema.tables
WHERE table_schema NOT IN ('information_schema','mysql')
AND engine IS NOT NULL
GROUP BY engine WITH ROLLUP;
获取推荐的MyISAM密钥缓冲区大小(以MB为单位)
SELECT CONCAT(ROUND(KBS/POWER(1024,IF(pw<0,0,IF(pw>3,0,pw)))+0.49999),
SUBSTR(' KMG',IF(pw<0,0,IF(pw>3,0,pw))+1,1)) recommended_key_buffer_size
FROM (SELECT SUM(index_length) KBS FROM information_schema.tables WHERE
engine='MyISAM' AND table_schema NOT IN ('information_schema','mysql')) A,
(SELECT 2 pw) B;
获取建议的InnoDB缓冲池大小(以GB为单位)
SELECT CONCAT(ROUND(KBS/POWER(1024,IF(pw<0,0,IF(pw>3,0,pw)))+0.49999),
SUBSTR(' KMG',IF(pw<0,0,IF(pw>3,0,pw))+1,1)) recommended_innodb_buffer_pool_size
FROM (SELECT SUM(data_length+index_length) KBS FROM information_schema.tables
WHERE engine='InnoDB') A,(SELECT 3 pw) B;
按存储引擎获取所有数据库的磁盘使用情况,以MB为单位
SELECT Statistic,DataSize "Data Size",IndexSize "Index Size",TableSize "Table Size"
FROM (SELECT IF(ISNULL(table_schema)=1,10,0) schema_score,
IF(ISNULL(engine)=1,10,0) engine_score,
IF(ISNULL(table_schema)=1,'ZZZZZZZZZZZZZZZZ',table_schema) schemaname,
IF(ISNULL(B.table_schema)+ISNULL(B.engine)=2,"Storage for All Databases",
IF(ISNULL(B.table_schema)+ISNULL(B.engine)=1,CONCAT("Storage for ",B.table_schema),
CONCAT(B.engine," Tables for ",B.table_schema))) Statistic,
CONCAT(LPAD(REPLACE(FORMAT(B.DSize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') DataSize,
CONCAT(LPAD(REPLACE(FORMAT(B.ISize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') IndexSize,
CONCAT(LPAD(REPLACE(FORMAT(B.TSize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') TableSize
FROM (SELECT table_schema,engine,SUM(data_length) DSize,SUM(index_length) ISize,
SUM(data_length+index_length) TSize FROM information_schema.tables
WHERE table_schema NOT IN ('mysql','information_schema','performance_schema')
AND engine IS NOT NULL GROUP BY table_schema,engine WITH ROLLUP) B,
(SELECT 2 pw) A) AA ORDER BY schemaname,schema_score,engine_score;
相信我,INFORMATION_SCHEMA还有更多精彩的用法,因为时间不允许我进一步讨论。
请记住,INFORMATION_SCHEMA非常敏感,以至于如果mysql正在运行,您可以执行以下操作:
cd /var/lib/mysql
mkdir junkfolder
然后进入mysql运行
mysql> SHOW DATABASES;
您将看到垃圾文件夹是数据库之一。
知道这一点对于DBA和开发人员至关重要。《MySQL 5.0认证研究指南》一书的第20章(开发人员)和第31章(DBA)
为开发人员和DBA认证考试做准备。拿起这本书,好好学习这些章节,您可以使用MySQL的INFORMATION_SCHEMA来做大事。
从MySQL 5.5开始,INFORMATION_SCHEMA数据库现在具有插件,全局变量(状态和静态),会话变量(状态和静态),存储引擎状态,性能指标检测,触发器映射,事件(可编程)等。
抱歉,这看起来像WTMI,但我强烈支持使用INFORMATION_SCHEMA数据库。