mysql cookbook0009
9.0 引言
元数据类型:
1. 关于语句结果的信息(对于删除或者更新数据行的语句,select语句等)
2. 关于表和数据库的信息(关于表和数据库的结构信息)
3. 关于mysql服务器的信息(关于数据库服务器或你当前与服务器连接状态的信息)
注意:由于元数据信息用于数据库系统的实现,所以它倾向于数据库部分相关。这意味着如果应用程序使用了本节介绍的技术,那么在其他数据库使用时要做些修改。
一个更方便的元数据的来源是information_schema数据库,这个元数据数据库包括的信息:数据库,表,列,字符集等。information_schema拥有比show更好的特征:
1. 其他数据库系统也支持information_schema所以使用它的应用程序可能比那些使用show语句的更方便。
2. information_schema是使用标准的select语法,所以与show相比,他与其他数据获取更类似。
information_schema的一个劣势就是访问它的语句相对于show语句更冗长。
show语句:show databases,show tables; show columns;
9.1 获取受影响的数据行数目
对于影响数据行的语句(增删改,replace),对于mysql而言,'被影响'默认的含义是被'改变'而非'匹配'.
也就是说,没有被语句改变的数据行是不被计数的,尽管他们符合指明的条件,当连接指明他希望数据行匹配计数而非数据行改变计数时,
mysql服务器允许客户端设置标志位。但也不是所有的API都可以选择你想要的技术类型。
java就可以:
java的jdbc接口有两种不同的方法提供数据行计数:
1. 使用executeUpdate函数:
Statement s = conn.createStatement();
int count = s.executeUpdate();
2. 使用execute函数:如果使用该函数,那么它返回true或false来指明调用语句是否返回了结果集。对于delete,update不返回结果集的语句,execute函数
将返回false,同时数据行技术将通过调用getUpdateCount函数得到
Statement s = conn.createStatement();
if(!s.execute){
int count = s.getUpdateCount();
}
9.2 获取设置元数据的结果
jdbc通过ResultSetMetaData对象使结果集元数据可用,可以调用ResultSet.getMetaData()得到ResultSetMetaData,
他的getColumnCount方法返回结果集中数据列的计数。对于数据列的索引是从1开始。
class TestMetaDate{
public void connMysql(){
String stmt = "select name,foods from profile";
Statement s= conn.createStatement();
s.executeQuery(stmt);
ResultSet rs = s.getResultSet();
ResultSetMetaData md = rs.getMetaData();
//元数据从 这里开始使用
int ncols = md.getColumnCount();
if(ncols >0){
for(int i = 0; i < ncols; i ++){
String columnName = md.getColumnName(i);
String columnDisplaySize = md.getColumnDisplaySize();
String columnLabei = md.getColumnLabel();
String columnTypeName = md.getColumnTypeName();
........
}
}
}
}
9.3 确定一条语句是否生成了结果集
注意:对于是否产生结果集的语句必须知道这个很关键,因为结果集产生与否关系到了你处理的方式,前一节中介绍了java怎样处理结果集针对不同情况。
9.4 使用元数据来格式化查询输出
使用结果集元数据来协助格式化输出,你甚至在不知道查询的是什么但是通过元数据来格式化输出,
注意两点:
1. 数据列名称的长度需要考虑
2. 对于NULL值我们将打印'NULL',所以如果数据列包括NULL值,显示宽度至少为4
9.5 列举或检查数据库或表的扩展
使用information_schema来得到相应信息,schemata表中的每一行数据对应一个数据库,tables表中的每一行数据对应数据库中的一张表
mysql> select * from schemata limit 1\G
*************************** 1. row ***************************
CATALOG_NAME: def
SCHEMA_NAME: information_schema//库名
DEFAULT_CHARACTER_SET_NAME: utf8
DEFAULT_COLLATION_NAME: utf8_general_ci
SQL_PATH: NULL
1 row in set (0.00 sec)
mysql>
在java中提供了方法得到数据库信息和表信息
DataBaseMetaData md = conn.getMetaData()
//获取数据库列表
ResultSet rs = md.getCatalogs();
ResultSet rs = md.getTables(dbName,'','',null)
9.6 访问表数据列定义
可以使用show语句或者mysqldump得到信息
表结构信息:
mysql> select * from tables limit 1\G
*************************** 1. row ***************************
TABLE_CATALOG: def
TABLE_SCHEMA: information_schema//表所属的数据库
TABLE_NAME: CHARACTER_SETS//表名
TABLE_TYPE: SYSTEM VIEW//
ENGINE: MEMORY//数据库引擎
VERSION: 10
ROW_FORMAT: Fixed
TABLE_ROWS: NULL
AVG_ROW_LENGTH: 384
DATA_LENGTH: 0
MAX_DATA_LENGTH: 16604160
INDEX_LENGTH: 0
DATA_FREE: 0
AUTO_INCREMENT: NULL
CREATE_TIME: 2014-12-02 21:18:26//之所以创表时间在最进打开连接是因为该表的引擎是memory。
UPDATE_TIME: NULL
CHECK_TIME: NULL
TABLE_COLLATION: utf8_general_ci//字符集序列
CHECKSUM: NULL
CREATE_OPTIONS: max_rows=43690
TABLE_COMMENT:
1 row in set (0.05 sec)
表的列的信息:
mysql> select * from columns limit 1\G
*************************** 1. row ***************************
TABLE_CATALOG: def
TABLE_SCHEMA: information_schema//表所属的数据库
TABLE_NAME: CHARACTER_SETS//列所属的表
COLUMN_NAME: CHARACTER_SET_NAME//列名
ORDINAL_POSITION: 1//表中定义的数据列位置
COLUMN_DEFAULT:
IS_NULLABLE: NO//是否能为空
DATA_TYPE: varchar//数据类型
CHARACTER_MAXIMUM_LENGTH: 32
CHARACTER_OCTET_LENGTH: 96
NUMERIC_PRECISION: NULL
NUMERIC_SCALE: NULL
CHARACTER_SET_NAME: utf8
COLLATION_NAME: utf8_general_ci
COLUMN_TYPE: varchar(32)//包含数据类型的附加信息
COLUMN_KEY://索引信息
EXTRA:
PRIVILEGES: select
COLUMN_COMMENT:
1 row in set (0.11 sec)
使用show [full] columns来获取表结构(等价于:show field from tab1 ,desc
ribletab1)
show columns from tab1 like 'pattern'
show create table tab1;
9.7 取得Enum 和set数据列信息(mysqldump --no-data 数据库 表名)
mysql> show create table set_enum\G
*************************** 1. row ***************************
Table: set_enum
Create Table: CREATE TABLE `set_enum` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`weekday` enum('MON','TUE','WEN','THU','FRI','SAR','SUM') DEFAULT NULL,
`color` set('chartreuse','mauve','lime green','puce') DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
使用enum或者set的好处在于:例如你想为页面的弹出菜单添加条目,那么为了维护添加数据的正确性,定义在枚举中就有很大的保证
9.9 获取服务器元数据
1. select version()//查询版本信息
2. select database();//查询默认的数据库名称,其实他查询的是:
mysql> select * from schemata;
+--------------+--------------------+----------------------------+------------------------+----------+
| CATALOG_NAME | SCHEMA_NAME | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME | SQL_PATH |
+--------------+--------------------+----------------------------+------------------------+----------+
| def | information_schema | utf8 | utf8_general_ci | NULL |
| def | mysql | utf8 | utf8_general_ci | NULL |
| def | performance_schema | utf8 | utf8_general_ci | NULL |
| def | sjxy_ess | utf8 | utf8_general_ci | NULL |
| def | temp | utf8 | utf8_general_ci | NULL |
+--------------+--------------------+----------------------------+------------------------+----------+
3. select user()//客户端连接时给出的当前用户,其实查询的就是:
*************************** 2. row ***************************
TABLE_CATALOG: def
TABLE_SCHEMA: mysql
TABLE_NAME: user
TABLE_TYPE: BASE TABLE
ENGINE: MyISAM
VERSION: 10
ROW_FORMAT: Dynamic
TABLE_ROWS: 3
AVG_ROW_LENGTH: 122
DATA_LENGTH: 368
MAX_DATA_LENGTH: 281474976710655
INDEX_LENGTH: 2048
DATA_FREE: 0
AUTO_INCREMENT: NULL
CREATE_TIME: 2012-07-21 02:29:31
UPDATE_TIME: 2014-11-27 19:13:37
CHECK_TIME: NULL
TABLE_COLLATION: utf8_bin
CHECKSUM: NULL
CREATE_OPTIONS:
TABLE_COMMENT: Users and global privileges
2 rows in set (0.00 sec)
4. select_current_user();
5. show global status();//查询服务器的全局状态指示器,也有连接的状态:session_status
mysql> show create table global_status\G
*************************** 1. row ***************************
Table: GLOBAL_STATUS
Create Table: CREATE TEMPORARY TABLE `
GLOBAL_STATUS` (
`VARIABLE_NAME` varchar(64) NOT NULL DEFAULT '',
`VARIABLE_VALUE` varchar(1024) DEFAULT NULL
) ENGINE=MEMORY DEFAULT CHARSET=utf8
1 row in set (0.05 sec)
6. show variables//服务器配置变量 ,也有连接的变量:session_variables
mysql> show create table global_variables\G
*************************** 1. row ***************************
Table: GLOBAL_VARIABLES
Create Table: CREATE TEMPORARY TABLE `
GLOBAL_VARIABLES` (
`VARIABLE_NAME` varchar(64) NOT NULL DEFAULT '',
`VARIABLE_VALUE` varchar(1024) DEFAULT NULL
) ENGINE=MEMORY DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
9.10 编写适合mysql服务器版本的应用程序
对于不同的版本号,进行应用程序的调整
9.11 检测mysql服务器
SHOW STATUS()/SHOW VARIABLES()
SHOW STATUS LIKE 'CONNECTIONS'
SHOW STATUS LIKE 'UPTIME'
SHOW VARIABLES LIKE 'WAIT_TIMEOUT' -> SELECT
@@WAIT_TIME_OUT//全局变量的意思
注意:mysql不确定规则
某些指示器,在你每次测量时你都改变了你正在测量的数值,例如:show status like 'questions';
然而该句本身也是一套服务器接收语句,所以每次提交它,就引起了请求数值的上升,从效果上说你的性能评估影响了测量的本身
9.12 确定服务器支持哪个存储引擎
mysql> select * from engines limit 1\G
*************************** 1. row ***************************
ENGINE: FEDERATED//引擎的名称
SUPPORT: NO//如果为NO标识不可用,假如是YES/DEFAULT 标识可用状态
COMMENT: Federated MySQL storage engine
TRANSACTIONS: NULL
XA: NULL
SAVEPOINTS: NULL
1 row in set (0.00 sec)