mysql basic operation,mysql總結,對mysql常用語句的詳細總結,MySQL學習筆記

mysql> select * from wifi_data where dev_id like "0023-AABBCCCCBBAA" ;

一、顯示數據庫列表。
show databases;
剛開始時才兩個數據庫:mysql和test。mysql庫很重要它裏面有MYSQL的系統信息,咱們改密碼和新增用戶,實際上就是用這個庫進行操做。

二、顯示庫中的數據表:
use mysql; //打開庫,學過FOXBASE的必定不會陌生吧
show tables;

三、顯示數據表的結構:
describe 表名;

四、建庫:
create database 庫名;

五、建表:
use 庫名;
create table 表名 (字段設定列表);
以下:
CREATE TABLE `wifi_test` (
 `dev_id` varchar(30) NOT NULL default '' COMMENT '設備ID',
 `timestamp` varchar(50) NOT NULL default '' COMMENT '時間',
 `interval` tinyint(1) NOT NULL default '1' COMMENT '上傳間隔',
 PRIMARY KEY  (`dev_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;


六、刪庫和刪表:
drop database 庫名;
drop table 表名;

七、將表中記錄清空:
delete from 表名;

八、顯示錶中的記錄:
select * from 表名;

九、表數據中的增刪改查
(所有插入)insert into 表名 valus('','',……,'');
(部分插入)insert into 表名(列x,列y,……,列z) valus('','',……,'');
insert into wifi_test values("1234567890ab","201506161330","300");
insert into wifi_test values("1234567890ad","201506161332",0);
 insert into wifi_test(dev_id,timestamp) values("1234567890ag","201506181405");
 insert into wifi_test(timestamp) values("201506181505");
select * from wifi_test;



10.向表中刪除行數據:
delect from 表名;(清空表)
delect from 表名 where [檢索條件表達式]
delete from wifi_test where dev_id=1234567890ab;
delete from table_xx where catch_time LIKE '2016-07-14 20:22:%';
 

11.修改,更改表中的數據:
update 表名 set 列名='表達式' [from 另外一表名] where [檢索條件表達式];
update wifi_test set interval='300' where dev_id=1234567890ag;
update wifi_test set interval=replace(interval,127,80);
 update wifi_test set timestamp=20150618143333 where dev_id;


update語法
Single-table語法:
UPDATE [LOW_PRIORITY] [IGNORE] tbl_name
    SET col_name1=expr1 [, col_name2=expr2 ...]
    [WHERE where_definition]
    [ORDER BY ...]
    [LIMIT row_count]
Multiple-table語法:
UPDATE [LOW_PRIORITY] [IGNORE] table_references
    SET col_name1=expr1 [, col_name2=expr2 ...]
    [WHERE where_definition]

UPDATE語法能夠用新值更新原有錶行中的各列。SET子句指示要修改哪些列和要給予哪些值。WHERE子句指定應更新哪些行。若是沒有WHERE子句,則更新全部的行。若是指定了ORDER BY子句,則按照被指定的順序對行進行更新。LIMIT子句用於給定一個限值,限制能夠被更新的行的數目。

若是您在一個表達式中經過tbl_name訪問一列,則UPDATE使用列中的當前值。例如,如下語句把年齡列設置爲比當前值多一:
UPDATE persondata SET age=age+1;
UPDATE賦值被從左到右評估。例如,如下語句對年齡列加倍,而後再進行增長:
UPDATE persondata SET age=age*2, age=age+1;
若是您把一列設置爲其當前含有的值,則MySQL會注意到這一點,但不會更新。
update表的某些字段爲null
update person set number=null,name=null;
若是您把被已定義爲NOT NULL的列更新爲NULL,則該列被設置到與列類型對應的默認值,而且累加警告數。對於數字類型,默認值爲0;對於字符串類型,默認值爲空字符串('');對於日期和時間類型,默認值爲「zero」值。

多個表的UPDATE操做
UPDATE items,month SET items.price=month.price WHERE items.id=month.id;
以上的例子顯示出了使用逗號操做符的內部聯合,可是multiple-table UPDATE語句能夠使用在SELECT語句中容許的任何類型的聯合,好比LEFT JOIN,可是您不能把ORDER BY或LIMIT與multiple-table UPDATE同時使用。



12.查詢表中的數據:select          */表字段1,表字段2,……表字段n     from 表名 【where 查詢條件】;
mysql> select * from student;
mysql> select * from student where id=1;
mysql> select id,name from student;
mysql> select id,name from student where id in(1,3,4);//in表示集合。php

 

 //看當前使用的是哪一個數據庫 ,若是你還沒選擇任何數據庫,結果是NULL。
mysql>select database();
+------------+
| DATABASE() |
+------------+
| menagerie  |
+------------+

//查看有哪些數據庫
 mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| test               |
+--------------------+

//選擇數據庫
mysql>use test;  //;號無關緊要,必須單行使用.  

爲了找出當前的數據庫包含什麼表(例如,當你不能肯定一個表的名字),使用這個命令:

//看數據庫裏有哪些表
mysql>show tables;
+---------------------+
| Tables in menagerie |
+---------------------+
| event               |
| pet                 |
+---------------------+
若是你想要知道一個表的結構,能夠使用DESCRIBE命令;它顯示錶中每一個列的信息:

//看錶裏有哪些列
mysql> describe pet;
+---------+-------------+------+-----+---------+-------+
| Field   | Type        | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| name    | varchar(20) | YES  |     | NULL    |       |
| owner   | varchar(20) | YES  |     | NULL    |       |
| species | varchar(20) | YES  |     | NULL    |       |
| ***     | char(1)     | YES  |     | NULL    |       |
| birth   | date        | YES  |     | NULL    |       |
| death   | date        | YES  |     | NULL    |       |
+---------+-------------+------+-----+---------+-------+
Field顯示列名字,Type是列的數據類型,Null表示列是否能包含NULL值,Key顯示列是否被索引而Default指定列的默認值。

若是表有索引,SHOW INDEX FROM tbl_name生成有關索引的信息。

刪除數據庫.
mysql>drop database test;  





 如先輸入mysql,成功啓動後輸入use mysql,出現以下錯誤:Access denied for user ''@'localhost' to database 'mysql'
還有,輸mysql能夠,輸mysql -u root就出錯了:
Access denied for user 'root'@'localhost' (using password: NO).
The reason is:
是昨日更新ROOT密碼時出錯
update user set password = '123456' where user ="root" //這樣寫是錯的,密碼其實不是123456
應該爲update user set password = password ('123456') where user = "root"
具體操做步驟:
關閉mysql:
# service mysqld stop
而後:
# mysqld_safe --skip-grant-tables(該命令完成後,可能終端不會提示輸入下一命令,下面命令在新開的終端中實現)
啓動mysql:
# service mysqld start
mysql -u root
mysql> use mysql
mysql> UPDATE user SET Password=PASSWORD('xxx') WHERE user='root';
mysql> flush privileges;
mysql>\q




ERROR 1044 (42000): Access denied for user ''@'localhost' to database
 解決 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) 問題
最近新裝好的mysql在進入mysql工具時,老是有錯誤提示:
# mysql -u root -p
Enter password:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
或者
# mysql -u root -p password 'newpassword'
Enter password:
mysqladmin: connect to server at 'localhost' failed
error: 'Access denied for user 'root'@'localhost' (using password: YES)'
如今終於找到解決方法了。原本準備重裝的,如今沒必要了。
方法操做很簡單,以下:
# /etc/init.d/mysql stop
# mysqld_safe --user=mysql --skip-grant-tables --skip-networking &
# mysql -u root mysql
mysql> UPDATE user SET Password=PASSWORD('newpassword') where USER='root' and host='root' or host='localhost';//把空的用戶密碼都修改爲非空的密碼就好了。
mysql> FLUSH PRIVILEGES;
mysql> quit # /etc/init.d/mysqld restart
# mysql -uroot -p
Enter password: <輸入新設的密碼newpassword>


html

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)前端

此問題是沒有開啓mysqld服務.mysql




  root 用戶的 create_priv 權限是否被設置爲N了?


在建立數據庫時報錯
mysql> create database haha;
ERROR 1044 (42000): Access denied for user ''@'localhost' to database 'haha' mysql>  
解決方案:這是由於在mysql的usr表中,存在用戶名爲空的帳戶,雖然登錄時用的是root,可是匿名登錄。刪除user.user中值爲NULL的,或更新NULL爲test 1)delete from user where user is NULL
2)update user set user='test' where user is NULL





ERROR 1044 (42000): Access denied for user 'root'@'%' to database
我這裏root有三種解析登陸方式分別是:Host: bidevedw\_db、Host: ::一、Host: %
通常狀況還有Host:127.0.0.一、Host:localhost個人裏面把哪兩種刪了。
請注意 !
 注意上面每條記錄的的紅色字體部分Grant_priv: Y
這個表示,以這種方式解析登陸的root用戶,是否有grant權限,Y則表示有受權限給其餘用戶的權限,N表示沒有。
這裏剛好,就是咱們要找的緣由,由於個人/my.cnf文件裏面有skip-name-resolve參數,因此root都是解析到@'%'方式登陸,因而就沒有grant_priv權限。

解決方法:
一、在不重啓MySQL服務的狀況下,只須要在登陸的時候加上-h參數。
例如:(a). /usr/local/mysql/bin/mysql -uroot -p123456 -h::1
         (b)./usr/local/mysql/bin/mysql -uroot -p123456 -h127.0.0.1
二、須要重啓MySQL。把skip-name-resolve參數去掉  ---- 還沒驗證。不過我記得,若是去掉了,日誌裏面會有大量的警告信息。我是由於那些警告信息,才添加的這個參數。





use testdb;
簡單描述表結構,字段類型:
desc tb_content;

查看錶生成的DDL,這個命令雖然顯示起來不是太容易看, 這個不是問題能夠用\G來結尾,使得結果容易閱讀;該命令把建立表的DDL顯示出來,因而表結構、類型,外鍵,備註所有顯示出來了。我比較喜歡這個命令:輸入簡單,顯示結果全面。
show create table tb_content;

查詢表中列的註釋信息
select * from information_schema.columns where table_schema = 'testdb';
select * from information_schema.columns where table_schema = 'testdb' and table_name = 'tb_content';

只查詢列名和註釋
select  column_name, column_comment from information_schema.columns where table_schema ='testdb'  and table_name = 'tb_content' ;

查看當前使用的數據庫:
mysql>select database();
mysql>status;










 
修改root密碼
mysql> use mysql
Database changed
mysql> update user set password=PASSWORD('123456') where user='root';
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1  Changed: 0  Warnings: 0
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)


查看全部用戶密碼:
SELECT User, Password, Host FROM user;


windows添加防火牆端口:
.須要設置防火牆放開mysql 3306端口的訪問,控制面板->windows防火牆->高級設置,打開另外一個界面,
  在該界面中選擇入站規則,而後在右邊欄選擇 新建規則,下一步選擇端口,下一步選擇TCP/特定本地端口並輸入3306,下一步選擇容許鏈接,下一步默認選擇,下一步輸入你想給的名稱好比mysqlport,而後點擊完成。
打開防火牆,選擇例外選項卡,添加端口
名稱:mysqlport
端口號:3306
選中TCP
  設置好後,務必從新啓動計算機


iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT
打開防火牆配置文件可查看當前防火牆狀況:vi  /etc/sysconfig/iptables
iptables-save
sudo service iptables save
iptables-save, service iptables save 做用同樣,只不過iptables-save須要手動指定路徑及文件名,而service iptables save的文件爲/etc/sysconfig/iptables
注意:增長的開放3306端口的語句必定要在icmp-host-prohibited以前



linux

 

 

 

CREATE TABLE tab2 AS (SELECT * FROM tab1)
這種作法表的存儲引擎也會採用服務器默認的存儲引擎而不是源表的存儲引擎,此種複製方法把表的內容也一塊兒複製過來了。正則表達式

CREATE TALBE tab2 ENGINE=MYISAM, CHARSET='UTF8' AS (SELECT * FROM tab1)
能夠本身指定存儲引擎和字符集,彌補方法一的不足算法

CREATE TABLE tab2 LIKE tab1
使用和tab1表相同的結構來建立一個新表,列名、數據類型、空指和索引也將複製,可是表的內容不會被複制。外鍵和專用的權限也沒有被複制。sql

MySQL複製表結構及數據到新表
CREATE TABLE tab_new SELECT * FROM tab_oldshell

複製舊錶的數據到新表(假設兩個表結構同樣)
INSERT INTO tab1 SELECT * FROM tab2數據庫

複製舊錶的數據到新表(假設兩個表結構不同)
INSERT INTO tab1(字段1, 字段2, ...) SELECT 字段1, 字段2, ... FROM tab2

更改表名
ALTER TABLE employee RENAME TO staff

更改列類型
ALTER TABLE employee MODIFY COLUMN truename VARCHAR(10) NOT NULL DEFAULT ''

更改列名
ALTER TABLE employee CHANGE COLUMN truename employeename VARCHAR(10) NOT NULL DEFAULT ''

添加默認值
ALTER TABLE employee ALTER COLUMN truename SET DEFAULT ''

刪除默認值
ALTER TABLE employee ALTER COLUMN truename DEOP DEFAULT


mysql修改表
表的結構以下:

mysql> show create table person;
| person | CREATE TABLE `person` (
`number` int(11) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`birthday` date DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 |
刪除列:

ALTER TABLE person DROP COLUMN birthday;
添加列:

ALTER TABLE person ADD COLUMN birthday datetime;
修改列,把number修改成bigint:

ALTER TABLE person MODIFY number BIGINT NOT NULL;
或者是把number修改成id,類型爲bigint:

ALTER TABLE person CHANGE number id BIGINT;

添加主鍵:

ALTER TABLE person ADD PRIMARY KEY (id);
刪除主鍵:

ALTER TABLE person DROP PRIMARY KEY;
添加惟一索引:

ALTER TABLE person ADD UNIQUE name_unique_index (`name`);
爲name這一列建立了惟一索引,索引的名字是name_unique_index.

 

添加普通索引:

ALTER TABLE person ADD INDEX birthday_index (`birthday`);

刪除索引:

ALTER TABLE person DROP INDEX birthday_index;
ALTER TABLE person DROP INDEX name_unique_index;

禁用非惟一索引

ALTER TABLE person DISABLE KEYS;
ALTER TABLE...DISABLE KEYS讓MySQL中止更新MyISAM表中的非惟一索引。

激活非惟一索引

ALTER TABLE person ENABLE KEYS;
ALTER TABLE ... ENABLE KEYS從新建立丟失的索引。

 

把表默認的字符集和全部字符列(CHAR, VARCHAR, TEXT)改成新的字符集:

ALTER TABLE person CONVERT TO CHARACTER SET utf8;
修改表某一列的編碼

ALTER TABLE person CHANGE name name varchar(255) CHARACTER SET utf8;
僅僅改變一個表的默認字符集

ALTER TABLE person DEFAULT CHARACTER SET utf8;
修改表名

RENAME TABLE person TO person_other;
移動表到其餘數據庫

RENAME TABLE current_db.tbl_name TO other_db.tbl_name;

 


在mysql中咱們對數據表字段的修改命令只要使用alter就能夠了,下面我來給你們詳細介紹mysql中修改表字段名/字段長度/字段類型等等一些方法介紹,有須要瞭解的朋友可參考。

先來看看經常使用的方法
MySql的簡單語法,經常使用,卻不容易記住。固然,這些Sql語法在各數據庫中基本通用。下面列出:
1.增長一個字段
alter table user add COLUMN new1 VARCHAR(20) DEFAULT NULL; //增長一個字段,默認爲空
alter table user add COLUMN new2 VARCHAR(20) NOT NULL;    //增長一個字段,默認不能爲空
2.刪除一個字段
alter table user DROP COLUMN new2;                //刪除一個字段
3.修改一個字段
alter table user MODIFY new1 VARCHAR(10);            //修改一個字段的類型
alter table user CHANGE COLUMN new1 new4 varchar(512) default "";              //修改一個字段的名稱,此時必定要從新指定該字段的類型

//主鍵
alter table tabelname add new_field_id int(5) unsigned default 0 not null auto_increment ,add primary key (new_field_id);
//增長一個新列
alter table t2 add d timestamp;
alter table infos add ex tinyint not null default ‘0′;
//刪除列
alter table t2 drop column c;
//重命名列
alter table t1 change a b integer;
//改變列的類型
alter table t1 change b b bigint not null;
alter table infos change list list tinyint not null default ‘0′;
//重命名錶
alter table t1 rename t2;
加索引
mysql> alter table tablename change depno depno int(5) not null;
mysql> alter table tablename add index 索引名 (字段名1[,字段名2 …]);
mysql> alter table tablename add index emp_name (name);
加主關鍵字的索引
mysql> alter table tablename add primary key(id);
加惟一限制條件的索引
mysql> alter table tablename add unique emp_name2(cardnumber);
刪除某個索引
mysql>alter table tablename drop index emp_name;
增長字段:
mysql> ALTER TABLE table_name ADD field_name field_type;
修改原字段名稱及類型:
mysql> ALTER TABLE table_name CHANGE old_field_name new_field_name field_type;
刪除字段:
mysql> ALTER TABLE table_name DROP field_name;
mysql修改字段長度
alter table 表名 modify column 字段名 類型;
例如
數據庫中user表 name字段是varchar(30)
能夠用
alter table user modify column name varchar(50) ;

 

 

 

 


mysql更改表結構:添加、刪除、修改字段、調整字段順序
mysqltablenulluserlist
添加字段:

alter table `user_movement_log`
Add column GatewayId int not null default 0 AFTER `Regionid` (在哪一個字段後面添加)

刪除字段:

alter table `user_movement_log` drop column Gatewayid

調整字段順序:

ALTER TABLE `user_movement_log` CHANGE `GatewayId` `GatewayId` int not null default 0 AFTER RegionID

//主鍵

alter table tabelname add new_field_id int(5) unsigned default 0 not null auto_increment ,add primary key (new_field_id);

//增長一個新列

alter table t2 add d timestamp;
alter table infos add ex tinyint not null default '0';

//刪除列

alter table t2 drop column c;

//重命名列

alter table t1 change a b integer;

//改變列的類型

alter table t1 change b b bigint not null;
alter table infos change list list tinyint not null default '0';

//重命名錶

alter table t1 rename t2;

加索引

mysql> alter table tablename change depno depno int(5) not null;
mysql> alter table tablename add index 索引名 (字段名1[,字段名2 …]);
mysql> alter table tablename add index emp_name (name);

加主關鍵字的索引

mysql> alter table tablename add primary key(id);

加惟一限制條件的索引

mysql> alter table tablename add unique emp_name2(cardnumber);

刪除某個索引

mysql>alter table tablename drop index emp_name;

修改表:

增長字段:

mysql> ALTER TABLE table_name ADD field_name field_type;

修改原字段名稱及類型:

mysql> ALTER TABLE table_name CHANGE old_field_name new_field_name field_type;

刪除字段:

mysql> ALTER TABLE table_name DROP field_name;

 

 

 


 

 


MySql表結構修改詳解

修改表的語法
=========================
增長列[add 列名]
=========================
①alter table 表名 add 列名 列類型 列參數【加的列在表的最後面】
例:alter table test add username char(20) not null default '';
alter table test add birth date not null default '0000-00-00';

②alter table 表名 add 列名 列類型 列參數 after 某列【把新列加在某列後面】
例:alter table test add gender char(1) not null default '' after username;

③alter table 表名 add 列名 列類型 列參數 first【把新列加在最前面】
例:alter table test add pid int not null default 0 first;

=========================
刪除列[drop 列名]
=========================
①alter table 表名 drop 列名
例:alter table test drop pid;

=========================
修改列[modife 列名]
=========================
①alter table 表名 modify 列名 新類型 新參數【修改列類型】
例:alter table test modify gender char(4) not null default '';
②alter table 表名 change 舊列名 新列名 新類型 新參數【修改列名和列類型】
例:alter table test change pid uid int unsigned not null default 0;

=========================
查詢列
=========================
①desc 表名【查詢全部列】
例: desc test;
mysql> desc department;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| dId | int(11) | NO | PRI | | |
| dName | varchar(32) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+

②show columns from 表名【效果和desc同樣】
mysql> show columns from department;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| dId | int(11) | NO | PRI | | |
| dName | varchar(32) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+

③show create table 表名【查看錶的建立代碼】
mysql> show create table department;
CREATE TABLE `department` (
`dId` int(11) NOT NULL,
`dName` varchar(32) DEFAULT NULL,
PRIMARY KEY (`dId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

 


總結一下對mysql表結構的修改操做,包括對字段及索引的修改操做: 添加字段: alter table `user_movement_log` Add column GatewayId int not null default 0 AFTER `Regionid` (在哪一個字段後面添加) 刪除字段: alter table `user_movement_log` drop column Gatewayid 調整字段順序: ALTER TABLE `user_movement_log` CHANGE `GatewayId` `GatewayId` int not null default 0 AFTER RegionID //主鍵 alter table tabelname add new_field_id int(5) unsigned default 0 not null auto_increment ,add primary key (new_field_id); //增長一個新列 alter table t2 add newfield timestamp; (簡單語法,只指定新添字段newfield 類型爲timestamp) alter table infos add newfield tinyint not null default '0'; (同時指定字段null屬性、默認值) //刪除列 alter table t2 drop column c; (刪除列c) //重命名列 alter table t1 change a b integer; (把列a更名爲b,注意要指定列類型) //改變列的類型 alter table t1 change b b bigint not null; (把列a更名爲b,指定列類型及null屬性) alter table infos change list list tinyint not null default '0'; //重命名錶 alter table t1 rename t2; 加索引 mysql> alter table tablename change depno depno int(5) not null; mysql> alter table tablename add index 索引名 (字段名1[,字段名2 …]); mysql> alter table tablename add index emp_name (name); 加主關鍵字的索引 mysql> alter table tablename add primary key(id); 加惟一限制條件的索引 mysql> alter table tablename add unique emp_name2(cardnumber); 刪除某個索引 mysql>alter table tablename drop index emp_name; 修改表: 增長字段: mysql> ALTER TABLE table_name ADD field_name field_type; 修改原字段名稱及類型: mysql> ALTER TABLE table_name CHANGE old_field_name new_field_name field_type; 刪除字段: mysql> ALTER TABLE table_name DROP field_name;


ORDER BY _column1, _column2; /* _column1升序,_column2升序 */
ORDER BY _column1, _column2 DESC; /* _column1升序,_column2降序 */
ORDER BY _column1 DESC, _column2 ; /* _column1降序,_column2升序 */
ORDER BY _column1 DESC, _column2 DESC; /* _column1降序,_column2降序 */
用 DESC 表示按倒序排序(即:從大到小排序)
用 ACS 表示按正序排序(即:從小到大排序)

 

order應該是以漢字的 ASCII 碼排序,下面是按照漢字拼音排序
select * from corp_data where Chengshi like "圖木舒克" order by convert(name using gbk);


#select count(*) as count from corp_data where Chengshi like "圖木舒克";
select * from corp_data where Chengshi like "圖木舒克" order by convert(name using gbk);
#delete from corp_data where Chengshi like "圖木舒克";
#desc corp_data;
#alter table corp_data modify column hangye varchar(100) ;
#alter table corp_data modify column jianjie varchar(10000) ;

 

 

 

 

 

mysql如何查詢最新的5條數據
select * from tb_content where id=(select msx(id) from tb_content) limit 0,5;

jdbcTemplate.execute("CREATE
建數據庫不合適,要手動drop database ,再create database.


查總數:
select count(*) as count from tb_content;
select count(id) as count from tb_content;
navicat->分析表->取得表的總數

select * from corp_data where Chengshi like "上海";
select * from corp_data where Shengzhixiashi like "河南";

select name ,count(distinct(url)) from corp_data group by  name;
select Chengshi ,count(distinct(url)) from corp_data group by  Chengshi;
select Chengshi ,count(*) from corp_data group by  Chengshi;
select count(*) from corp_data where Chengshi like "北京";
select * from corp_data where Chengshi like "北京";
select name ,url  from corp_data limit 1;
select *  from corp_data limit 1;

select *  from corp_data limit 10;

select count(*) as count from corp_data limit 10;
select count(distinct(name)) as count from corp_data;

 varchar(N),  這裏的N是指字符數,並非字節數.佔用的字節數與編碼有關
utf-8, 一個漢字3字節 英文字母1字節

CREATE TABLE IF NOT EXISTS corp_url_all_20150909 (id int(11) NOT NULL AUTO_INCREMENT,url varchar(500),PRIMARY KEY (id))
insert into corp_url_all_20150909 select * from corp_url_all;

 

備份:

mysql> create table corp_url_all_20150909 select * from corp_url_all;
Query OK, 3186326 rows affected (1 min 14.19 sec)
Records: 3186326  Duplicates: 0  Warnings: 0
mysql> select count(distinct(url)) as count from corp_url_all_20150909;
+--------+
| count  |
+--------+
| 357399 |
+--------+
1 row in set (11.21 sec)

去重:

create table corp_url_all_single select distinct(url) from corp_url_all_20150909;
select count(distinct(url)) as count from corp_url_all_single;


 

 

 

 

 

基本的SQL語句

2、數據定義語言(DDL)

數據定義語言:Data Definition Language。如CREATE, DROP,ALTER等語句。須要注意的是,數據庫中的命令不區分大小寫

建數據庫,命名爲mydb:

CREATE DATABASE mydb; 

注:如若要刪除數據庫,將「create」改成「drop」便可。

建立一個名爲teacher的表:

複製代碼
CREATE TABLE teacher( id int primary key auto_increment, name varchar(20), gender char(1), age int(2), birth date,
description varchar(100) );
複製代碼
查看錶結構:
desc teacher; 

須要注意的是:主鍵是用來惟一表明一條記錄的字段(主鍵值必須是惟一)

修改表結構(ALTER TABLE語句):(假設表名爲test)
  • alter table test add column job varchar(10); --添加表列
  • alter table test rename test1; --修改表名
  • alter table test drop column name; --刪除表列
  • alter table test modify address char(10) --修改表列類型(改類型)
  • alter table test change address address1  char(40) --修改表列類型(更名字和類型,和下面的一行效果同樣)
  • alter table test change column address address1 varchar(30)--修改表列名(更名字和類型)

自動增加

alter table tab_teacher change id id int auto_increment;

 

增長數據
insert into tab_teacher(name,gender,age,createDate) values('smyh','b',22,now()); 

now()函數能夠調出當前系統的時間。

 

修改數據(UPDATE … SET語句):

UPDATE 表名 SET 字段1名=值,字段2名=值,字段3名=值 where 字段名=值; 

注:where後面的部分表示修改的條件。修改時,按照字段一、字段二、字段3的前後順序修改。

 

刪除數據

DELETE FROM 表名; 

 

刪除ID爲1的記錄:

DELETE FROM 表名 where id=1; 

 

4、數據查詢語言(DRL):

數據查詢語言(Data Retrieval Language --DRL):SELECT語句。

在實際開發中,數據查詢語言用的是最多的。注:實際開發中,要避免使用通配符"*"(通配符表明全部字段),由於系統要先解析出全部的字段名,將其還原爲真實的名字,而後再進行操做。若是記錄數據庫內容特別多,會影響效率。

查詢全部信息:

select id,name,gender,age,job,createDate from tab_teacher; 

 

在沒有表被引用的狀況下,容許指定DUAL做爲一個假的表名:

DUAL是虛擬表。也就是說,表中沒有這個數據,可是要執意使用sql語句,系統就會用這個虛擬表來知足你。舉例效果以下:

查詢ID爲2的老師信息:

select * from tab_teacher where id=2; 

 

查詢職業爲空的老師信息:

select * from tab_teacher where job is null;#字段爲空用「job is null」來表示,而不是「job=null」。

 

查詢ID爲2的老師的姓名和性別:

select name,gender from tab_teacher where id=2; 

 

查詢性別爲女和指定日期的老師信息:

select $ from tab_teacher where gender='w' and ceateDate='2014-10-14'; #而且用「and」,或用「or」。

 

查詢性別爲男或者ID小於2的老師:

select * from tab_teacher where gender='m' or id<2; 

 

查詢姓名的最後一個字符爲「e」的老師:(關鍵字:like '%+指定字符')

select * from tab_teacher where name like '%e'; 

 

查詢姓名以指定字符開頭的老師:

select * from tab_teacher where name like 's%'; 

 

查詢姓名中包含「m」的老師:

select * from tab_teacher where name like '%m%'; 

 

查詢全部老師信息,並按日期降序或者升序排列:ORDER BY 字段,+默認爲升序:ASC/降序:DESC

  • 升序:
select * from tab_teacher order by createDate; #最後一個單詞ASC可寫可不寫,由於默認爲升序

 

  • 降序:
select * from tab_teacher order by createDate desc; 

 

多個排序條件:(當第一個條件相同時,按照第二個條件排序)

例如:上面圖片的排序中,是按照日期降序排序的,可是id爲2和id爲3的日期相同,這兩條記錄按照默認順序排序。

舉例:如今排序的第一條件爲:日期降序,第二條件爲:年齡降序。多個排序條件用逗號隔開。命令爲:

select * from tab_teacher order by createDate desc,age desc;

 

按性別分組查詢男女老師的人數(GROUP BY ):

select gender,count(gender) from tab_teacher group by gender;

上面的命令表示,查找gender這個字段;並計算gender有多少個(count(gender));而後按照gender裏的內容將個數進行分組(group by gender)。

問題:我以爲應該是先分組,再查詢性別,再數性別的個數。

注:這裏面用到了count()這個內置的函數。關於count()這個聚合函數,將在下一篇文章中講到。

正確的效果和錯誤的效果以下:

按性別分組,查詢出女老師人數的總數:

select gender,count(gender) from tab_teacher group by gender having gender='m';

這裏在上一個命令的基礎上,增長了一個關鍵字:having。having關鍵字專門用來在分組以後添加的條件。意思是:先求總數,而後進行分組,而後再從分組裏找到字段等於「m」的個數。注:不能用where做爲關鍵字,由於where是加在分組以前的條件。

顯示效果以下:

注:這種寫法操做繁瑣,效率較低,having語句儘可能少用,能夠用其餘語句代替,例如:

select gender,count(gender) from tab_teacher where gender='m';

效果是同樣的。

查詢表的總記錄數:

  • 方式一:(不推薦)
select count(*) from tab_teacher;
  • 方式二:(使用主鍵的方式查詢)
select count(id) from tab_teacher;

方式一將空記錄也包含進來了。因此採用方式二,由於主鍵惟一,且不能爲空,此時id總數則表明總記錄數。

別名的用法:

  • 使用別名查詢表的總記錄數:
select count(id) as counts from tab_teacher; 

不用別名和用別名的效果對好比下:(命令中的"as"能夠省略)

  • 使用別名來代替表的名字:

舉例:將表的名字起爲t。

select t.name,t.age from tab_teacher t;

當表名比較長,或者同時有多個表存在時,用別名就顯得很是方便了。

查詢老師記錄的前三條(從0位置開始找出3條):(很是有用)

select * from tab_teacher limit 0,3;

命令解釋:limit後面有兩個參數:第一個參數是起始位置,第二個參數是偏移量。聲明:第一條記錄的id無論爲多少,索引位置都是0。

注:這種分頁查詢方式很是有用,例如使用百度搜索時,告訴你總記錄數,可是會分頁顯示。

 

5、事務控制語言(TCL):

事務控制語言:Transaction Control Language--TCL。如COMMIT,ROLLBACK語句。

一、事務:

事務(Transaction)的概念:事務(Transaction)是訪問並可能更新數據庫中各類數據項的一個程序執行單元(unit)。在關係數據庫中,一個事務能夠是一條SQL語句,一組SQL語句或整個程序。

事務的屬性:原子性(atomicity)、一致性(consistency)、隔離性(isolation)、持續性(durability)。這四個屬性一般稱爲ACID特性。

事務的特色:事務就是對數據庫的多步操做,要麼一塊兒成功,要麼一塊兒失敗。

總結:事務就是能夠把多步操做當作一個總體,這個總體要麼一塊兒成功,要麼一塊兒失敗。

二、事務的提交和回滾命令:

設置默認事務提交方式:(默認爲true)

  • 設置事務提交方式爲「手動提交」:
set autocommit = false;
  • 設置事務提交方式爲自動提交」:
set autocommit = true;

手動提交事務:

commit;

回滾事務:

rollback;

 

注:只要還沒手動commit提交,一旦回滾,以前的修改操做都將清零。

注:commit命令和rollback命令只有在提交方式爲「手動提交」時,才能夠用。

三、保存還原點的命令:

當數據未commit以前,增刪改查的操做都是暫時保存在內存之中的,當咱們修改操做進行到某一步時,能夠給這一步設置一個還原點,方便之後回滾到此還原點(相似於PS當中的快照)。

保存還原點:

savepoint name_point;

回滾到指定還原點:

rollback to name_point;

 

 

 

 


 9、MySQL的一些函數:
  一、字符串連接——CONCAT()
    >SELECT CONCAT(name,'=>',score) FROM tb_name

  二、數學函數:
    AVG、SUM、MAX、MIN、COUNT;

  三、文本處理函數:
    TRIM、LOCATE、UPPER、LOWER、SUBSTRING

  四、運算符:
    +、-、*、\

  五、時間函數:
    DATE()、CURTIME()、DAY()、YEAR()、NOW().....

 10、分組查詢:
   一、分組查詢能夠按照指定的列進行分組:
    >SELECT COUNT(*) FROM tb_name GROUP BY score HAVING COUNT(*)>1;
  二、條件使用Having;
  三、ORDER BY 排序:
    ORDER BY DESC|ASC    =>按數據的降序和升序排列

11、UNION規則——能夠執行兩個語句(能夠去除重複行)
 12、全文檢索——MATCH和AGAINST
  一、SELECT MATCH(note_text)AGAINST('PICASO') FROM tb_name;
  二、InnoDB引擎不支持全文檢索,MyISAM能夠;

 十3、視圖

  一、建立視圖

    >CREATE VIEW name AS SELECT * FROM tb_name WHERE ~~ ORDER BY ~~;

  二、視圖的特殊做用:

      a、簡化表之間的聯結(把聯結寫在select中);

      b、從新格式化輸出檢索的數據(TRIM,CONCAT等函數);

      c、過濾不想要的數據(select部分)

      d、使用視圖計算字段值,如彙總這樣的值。

 十4、使用存儲過程:

  我的理解,存儲過程就是一個自定義函數,有局部變量參數,可傳入參數,能夠返回值,不過這語法夠呆滯的~~~

  一、建立存儲過程:

    >CREATE PROCEDURE pro(

    >IN num INT,OUT total INT)

    >BEGIN

    >SELECT SUM(score) INTO total FROM tb_name WHERE id=num;

    >END;

   ***這裏的  IN (傳遞一個值給存儲過程),OUT(從存儲過程傳出一個值),INOUT(對存儲過程傳入、傳出),INTO(保存變量)

  二、調用存儲過程:

    >CALL pro(13,@total)      //這裏的存儲過程兩個變量,一個是IN一個是OUT,這裏的OUT也是須要寫上的,不寫會出錯

    >SELECT @total         //這裏就能夠看到結果了;

  三、存儲過程的其餘操做:

    >SHOW PROCEDURE STATUS;      //顯示當期的存儲過程

    >DROP PROCEDURE pro;         //刪除指定存儲過程

十5、使用遊標:

  對這個理解不是很懂,朋友多多指點哦~~~

   一、遊標的操做

    >CREATE PROCEDURE pro()

    >BEGIN

    >DECLARE ordername CURSOR FOR

    >SELECT order_num FROM orders;

    >END;

    

    >OPEN ordername;    //打開遊標

 

    >CLOSE ordername;    //關閉遊標

十6、觸發器:

  觸發器是指在進行某項指定操做時,觸發觸發器內指定的操做;

  一、支持觸發器的語句有DELETE、INSERT、UPDATE,其餘均不支持

  二、建立觸發器:

    >CREATE TRIGGER trig AFTER INSERT ON ORDERS FOR EACH ROW SELECT NEW.orser_name;

    >INSERT語句,觸發語句,返回一個值

  三、刪除觸發器

    >DROP TRIGGER trig;

十7、語法整理:

  一、ALTER TABLE(修改表)

    ALTER TABLE table_name

    (  ADD    column  datatype    [ NULL | NOT NULL ]  [ CONSTRAINTS ]

       CHANGE  column   datatype   COLUMNS  [ NULL | NOT NULL ]   [ CONSTRAINTS ]

       DROP    column,

       。。。。

    )

  二、COMMIT(處理事務)

    >COMMIT;

   三、CREATE INDEX(在一個或多個列上建立索引)

    CREATE INDEX index_name ON tb_name (column [ ASC | DESC ] , .......);

   四、CREATE PROCEDURE (建立存儲過程)

    CREATE PROCEDURE pro([ parameters ])

    BEGIN

    ........

    END

   五、CREATE TABLE(建立表)

    CREATE TABLE tb_name(

    column_name  datetype  [ NULL | NOT NULL ]   [ condtraints]   ,

    column_name  datetype  [ NULL | NOT NULL ]   [ condtraints]   ,

    .......

    PRIMARY KEY( column_name )

    )ENGINE=[  InnoDB | MyiSAM ]DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

   六、CREATE USER(建立用戶)

    CREATE USER user_name [ @hostname ] [ IDENTIFIED BY [ PASSWORD ] 'pass_word' ];

   七、CREATE VIEW (在一個或多個表上建立視圖)

    CREATE [ OR REPLACE ] VIEW view_name AS SELECT。。。。。。

   八、DELETE (從表中刪除一行或多行)

    DELETE FROM table_name [WHERE ......]

   九、DROP(永久刪除數據庫及對象,如視圖、索引等)

    DROP DATEBASE | INDEX | PROCEDURE | TABLE | TRIGGER | USER | VIEW  name

   十、INSERT (給表添加行)

    INSERT INTO tb_name [ ( columns,...... ) ]  VALUES(value1,............);

    使用SELECT值插入:

    INSERT INTO tb_name [ ( columns,...... ) ]

    SELECT columns , .......   FROM tb_name [ WHERE ...... ] ;

   十一、ROLLBACK(撤銷一個事務處理塊)

    ROLLBACK [  TO  savapointname  ];

   十二、SAVEPOINT(爲ROLLBACK設置保留點)

    SAVEPOINT sp1;

   1三、SELECT (檢索數據,顯示信息)

    SELECT column_name,.....FROM tb_name  [ WHERE ]   [ UNION ]    [ RROUP BY ]   [ HAVING ]   [ ORDER BY ]

   1四、START TRANSACTION (一個新的事務處理塊的開始)

    START TRANSACTION

   1五、UPDATE(更新一個表中的一行或多行)

    UPDATE tb_name SET column=value,......[ where ]

 


其它mysql基本操做:
http://www.cnblogs.com/RanNing/archive/2012/11/17/2870484.html





幾個最經常使用的api函數
mysql_affected_rows()     返回被最新的UPDATE, DELETE或INSERT查詢影響的行數。
mysql_close()     關閉一個服務器鏈接。
mysql_errno()     返回最近被調用的MySQL函數的出錯編號。
mysql_error()     返回最近被調用的MySQL函數的出錯消息。
mysql_fetch_row()     從結果集合中取得下一行。
mysql_field_count()     返回最近查詢的結果列的數量。
mysql_init()     得到或初始化一個MYSQL結構。
mysql_insert_id()     返回有前一個查詢爲一個AUTO_INCREMENT列生成的ID。
mysql_num_rows()     返回一個結果集合中的行的數量。
mysql_query()     執行指定爲一個空結尾的字符串的SQL查詢。
mysql_real_connect()     鏈接一個MySQL服務器。
mysql_real_query()     執行指定爲帶計數的字符串的SQL查詢。





mysql經常使用字符串操做函數大全,以及實例
http://www.cnblogs.com/xiangxiaodong/archive/2011/02/21/1959589.html





CREATE TABLE tab2 AS (SELECT * FROM tab1)
這種作法表的存儲引擎也會採用服務器默認的存儲引擎而不是源表的存儲引擎,此種複製方法把表的內容也一塊兒複製過來了。

CREATE TALBE tab2 ENGINE=MYISAM, CHARSET='UTF8' AS (SELECT * FROM tab1)
能夠本身指定存儲引擎和字符集,彌補方法一的不足

CREATE TABLE tab2 LIKE tab1
使用和tab1表相同的結構來建立一個新表,列名、數據類型、空指和索引也將複製,可是表的內容不會被複制。外鍵和專用的權限也沒有被複制。

MySQL複製表結構及數據到新表
CREATE TABLE tab_new SELECT * FROM tab_old

複製舊錶的數據到新表(假設兩個表結構同樣)
INSERT INTO tab1 SELECT * FROM tab2

複製舊錶的數據到新表(假設兩個表結構不同)
INSERT INTO tab1(字段1, 字段2, ...) SELECT 字段1, 字段2, ... FROM tab2

更改表名
ALTER TABLE employee RENAME TO staff

更改列類型
ALTER TABLE employee MODIFY COLUMN truename VARCHAR(10) NOT NULL DEFAULT ''

更改列名
ALTER TABLE employee CHANGE COLUMN truename employeename VARCHAR(10) NOT NULL DEFAULT ''

添加默認值
ALTER TABLE employee ALTER COLUMN truename SET DEFAULT ''

刪除默認值
ALTER TABLE employee ALTER COLUMN truename DEOP DEFAULT


mysql修改表
表的結構以下:

mysql> show create table person;
| person | CREATE TABLE `person` (
`number` int(11) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`birthday` date DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 |
刪除列:

ALTER TABLE person DROP COLUMN birthday; 
添加列:

ALTER TABLE person ADD COLUMN birthday datetime;
修改列,把number修改成bigint:

ALTER TABLE person MODIFY number BIGINT NOT NULL;
或者是把number修改成id,類型爲bigint:

ALTER TABLE person CHANGE number id BIGINT;

添加主鍵:

ALTER TABLE person ADD PRIMARY KEY (id);
刪除主鍵:

ALTER TABLE person DROP PRIMARY KEY;
添加惟一索引:

ALTER TABLE person ADD UNIQUE name_unique_index (`name`);
爲name這一列建立了惟一索引,索引的名字是name_unique_index.

 

添加普通索引:

ALTER TABLE person ADD INDEX birthday_index (`birthday`);

刪除索引:

ALTER TABLE person DROP INDEX birthday_index;
ALTER TABLE person DROP INDEX name_unique_index;

禁用非惟一索引

ALTER TABLE person DISABLE KEYS;
ALTER TABLE...DISABLE KEYS讓MySQL中止更新MyISAM表中的非惟一索引。

激活非惟一索引

ALTER TABLE person ENABLE KEYS;
ALTER TABLE ... ENABLE KEYS從新建立丟失的索引。

 

把表默認的字符集和全部字符列(CHAR, VARCHAR, TEXT)改成新的字符集:

ALTER TABLE person CONVERT TO CHARACTER SET utf8;
修改表某一列的編碼

ALTER TABLE person CHANGE name name varchar(255) CHARACTER SET utf8;
僅僅改變一個表的默認字符集

ALTER TABLE person DEFAULT CHARACTER SET utf8;
修改表名

RENAME TABLE person TO person_other;
移動表到其餘數據庫

RENAME TABLE current_db.tbl_name TO other_db.tbl_name;

 


在mysql中咱們對數據表字段的修改命令只要使用alter就能夠了,下面我來給你們詳細介紹mysql中修改表字段名/字段長度/字段類型等等一些方法介紹,有須要瞭解的朋友可參考。

先來看看經常使用的方法
MySql的簡單語法,經常使用,卻不容易記住。固然,這些Sql語法在各數據庫中基本通用。下面列出:
1.增長一個字段
alter table user add COLUMN new1 VARCHAR(20) DEFAULT NULL; //增長一個字段,默認爲空
alter table user add COLUMN new2 VARCHAR(20) NOT NULL;    //增長一個字段,默認不能爲空
2.刪除一個字段
alter table user DROP COLUMN new2;                //刪除一個字段
3.修改一個字段
alter table user MODIFY new1 VARCHAR(10);            //修改一個字段的類型
alter table user CHANGE new1 new4 int;              //修改一個字段的名稱,此時必定要從新

//主鍵
alter table tabelname add new_field_id int(5) unsigned default 0 not null auto_increment ,add primary key (new_field_id);
//增長一個新列
alter table t2 add d timestamp;
alter table infos add ex tinyint not null default ‘0′;
//刪除列
alter table t2 drop column c;
//重命名列
alter table t1 change a b integer;
//改變列的類型
alter table t1 change b b bigint not null;
alter table infos change list list tinyint not null default ‘0′;
//重命名錶
alter table t1 rename t2;
加索引
mysql> alter table tablename change depno depno int(5) not null;
mysql> alter table tablename add index 索引名 (字段名1[,字段名2 …]);
mysql> alter table tablename add index emp_name (name);
加主關鍵字的索引
mysql> alter table tablename add primary key(id);
加惟一限制條件的索引
mysql> alter table tablename add unique emp_name2(cardnumber);
刪除某個索引
mysql>alter table tablename drop index emp_name;
增長字段:
mysql> ALTER TABLE table_name ADD field_name field_type;
修改原字段名稱及類型:
mysql> ALTER TABLE table_name CHANGE old_field_name new_field_name field_type;
刪除字段:
mysql> ALTER TABLE table_name DROP field_name;
mysql修改字段長度
alter table 表名 modify column 字段名 類型;
例如
數據庫中user表 name字段是varchar(30)
能夠用
alter table user modify column name varchar(50) ;

 

 

 

 


mysql更改表結構:添加、刪除、修改字段、調整字段順序
mysqltablenulluserlist
添加字段:

alter table `user_movement_log`
Add column GatewayId int not null default 0 AFTER `Regionid` (在哪一個字段後面添加)

刪除字段:

alter table `user_movement_log` drop column Gatewayid

調整字段順序:

ALTER TABLE `user_movement_log` CHANGE `GatewayId` `GatewayId` int not null default 0 AFTER RegionID

//主鍵

alter table tabelname add new_field_id int(5) unsigned default 0 not null auto_increment ,add primary key (new_field_id);

//增長一個新列

alter table t2 add d timestamp;
alter table infos add ex tinyint not null default '0';

//刪除列

alter table t2 drop column c;

//重命名列

alter table t1 change a b integer;

//改變列的類型

alter table t1 change b b bigint not null;
alter table infos change list list tinyint not null default '0';

//重命名錶

alter table t1 rename t2;

加索引

mysql> alter table tablename change depno depno int(5) not null;
mysql> alter table tablename add index 索引名 (字段名1[,字段名2 …]);
mysql> alter table tablename add index emp_name (name);

加主關鍵字的索引

mysql> alter table tablename add primary key(id);

加惟一限制條件的索引

mysql> alter table tablename add unique emp_name2(cardnumber);

刪除某個索引

mysql>alter table tablename drop index emp_name;

修改表:

增長字段:

mysql> ALTER TABLE table_name ADD field_name field_type;

修改原字段名稱及類型:

mysql> ALTER TABLE table_name CHANGE old_field_name new_field_name field_type;

刪除字段:

mysql> ALTER TABLE table_name DROP field_name;

 

 

 

 

 

 


MySql表結構修改詳解

修改表的語法
=========================
增長列[add 列名]
=========================
①alter table 表名 add 列名 列類型 列參數【加的列在表的最後面】
例:alter table test add username char(20) not null default '';
alter table test add birth date not null default '0000-00-00';

②alter table 表名 add 列名 列類型 列參數 after 某列【把新列加在某列後面】
例:alter table test add gender char(1) not null default '' after username;

③alter table 表名 add 列名 列類型 列參數 first【把新列加在最前面】
例:alter table test add pid int not null default 0 first;

=========================
刪除列[drop 列名]
=========================
①alter table 表名 drop 列名
例:alter table test drop pid;

=========================
修改列[modife 列名]
=========================
①alter table 表名 modify 列名 新類型 新參數【修改列類型】
例:alter table test modify gender char(4) not null default '';
②alter table 表名 change 舊列名 新列名 新類型 新參數【修改列名和列類型】
例:alter table test change pid uid int unsigned not null default 0;

=========================
查詢列
=========================
①desc 表名【查詢全部列】
例: desc test;
mysql> desc department;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| dId | int(11) | NO | PRI | | |
| dName | varchar(32) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+

②show columns from 表名【效果和desc同樣】
mysql> show columns from department;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| dId | int(11) | NO | PRI | | |
| dName | varchar(32) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+

③show create table 表名【查看錶的建立代碼】
mysql> show create table department;
CREATE TABLE `department` (
`dId` int(11) NOT NULL,
`dName` varchar(32) DEFAULT NULL,
PRIMARY KEY (`dId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

 


總結一下對mysql表結構的修改操做,包括對字段及索引的修改操做: 添加字段: alter table `user_movement_log` Add column GatewayId int not null default 0 AFTER `Regionid` (在哪一個字段後面添加) 刪除字段: alter table `user_movement_log` drop column Gatewayid 調整字段順序: ALTER TABLE `user_movement_log` CHANGE `GatewayId` `GatewayId` int not null default 0 AFTER RegionID //主鍵 alter table tabelname add new_field_id int(5) unsigned default 0 not null auto_increment ,add primary key (new_field_id); //增長一個新列 alter table t2 add newfield timestamp; (簡單語法,只指定新添字段newfield 類型爲timestamp) alter table infos add newfield tinyint not null default '0'; (同時指定字段null屬性、默認值) //刪除列 alter table t2 drop column c; (刪除列c) //重命名列 alter table t1 change a b integer; (把列a更名爲b,注意要指定列類型) //改變列的類型 alter table t1 change b b bigint not null; (把列a更名爲b,指定列類型及null屬性) alter table infos change list list tinyint not null default '0'; //重命名錶 alter table t1 rename t2; 加索引 mysql> alter table tablename change depno depno int(5) not null; mysql> alter table tablename add index 索引名 (字段名1[,字段名2 …]); mysql> alter table tablename add index emp_name (name); 加主關鍵字的索引 mysql> alter table tablename add primary key(id); 加惟一限制條件的索引 mysql> alter table tablename add unique emp_name2(cardnumber); 刪除某個索引 mysql>alter table tablename drop index emp_name; 修改表: 增長字段: mysql> ALTER TABLE table_name ADD field_name field_type; 修改原字段名稱及類型: mysql> ALTER TABLE table_name CHANGE old_field_name new_field_name field_type; 刪除字段: mysql> ALTER TABLE table_name DROP field_name;

 

ORDER BY _column1, _column2; /* _column1升序,_column2升序 */ 
ORDER BY _column1, _column2 DESC; /* _column1升序,_column2降序 */ 
ORDER BY _column1 DESC, _column2 ; /* _column1降序,_column2升序 */ 
ORDER BY _column1 DESC, _column2 DESC; /* _column1降序,_column2降序 */ 
用 DESC 表示按倒序排序(即:從大到小排序)
用 ACS 表示按正序排序(即:從小到大排序)

 

order應該是以漢字的 ASCII 碼排序,下面是按照漢字拼音排序
select * from corp_data where Chengshi like "圖木舒克" order by convert(name using gbk);


#select count(*) as count from corp_data where Chengshi like "圖木舒克";
select * from corp_data where Chengshi like "圖木舒克" order by convert(name using gbk);
#delete from corp_data where Chengshi like "圖木舒克";
#desc corp_data;
#alter table corp_data modify column hangye varchar(100) ;
#alter table corp_data modify column jianjie varchar(10000) ;

 

 

 

 

 

mysql如何查詢最新的5條數據
select * from tb_content where id=(select msx(id) from tb_content) limit 0,5;

jdbcTemplate.execute("CREATE
建數據庫不合適,要手動drop database ,再create database.


查總數:
select count(*) as count from tb_content;
select count(id) as count from tb_content;
navicat->分析表->取得表的總數

select * from corp_data where Chengshi like "上海";
select * from corp_data where Shengzhixiashi like "河南";

select name ,count(distinct(url)) from corp_data group by  name;
select Chengshi ,count(distinct(url)) from corp_data group by  Chengshi;
select Chengshi ,count(*) from corp_data group by  Chengshi;
select count(*) from corp_data where Chengshi like "北京";
select * from corp_data where Chengshi like "北京";
select name ,url  from corp_data limit 1;
select *  from corp_data limit 1;

select *  from corp_data limit 10;

select count(*) as count from corp_data limit 10;
select count(distinct(name)) as count from corp_data;

 varchar(N),  這裏的N是指字符數,並非字節數.佔用的字節數與編碼有關
utf-8, 一個漢字3字節 英文字母1字節 

 

 


mysql編碼最好使用utf-8,導出導入不用考濾編碼。
GB2312是GBK的子集,GBK是GB18030的子集,是國標。utf-8爲國際標準,特殊中文時使用gb18030。














 

 

 

下面總結的知識點全是常常用的,全都是乾貨,好好收藏吧。

/* 啓動mysql */
net start mysql

/* 鏈接與斷開服務器 */
mysql -h 地址 -p 端口 -u 用戶名 -p 密碼

/* 跳過權限驗證登陸mysql */
mysqld --skip-grant-tables
-- 修改root密碼
密碼加密函數password()
update mysql.user set password=password('root');

show processlist -- 顯示哪些線程正在運行
show variables --

/* 數據庫操做 */ ------------------
-- 查看當前數據庫
select database();
-- 顯示當前時間、用戶名、數據庫版本
select now(), user(), version();
-- 建立庫
create database[ if not exists] 數據庫名 數據庫選項
數據庫選項:
character set charset_name
collate collation_name
-- 查看已有庫
show databases[ like 'pattern']
-- 查看當前庫信息
show create database 數據庫名
-- 修改庫的選項信息
alter database 庫名 選項信息
-- 刪除庫
drop database[ if exists] 數據庫名
同時刪除該數據庫相關的目錄及其目錄內容

/* 表的操做 */ ------------------
-- 建立表
create [temporary] table[ if not exists] [庫名.]表名 ( 表的結構定義 )[ 表選項]
每一個字段必須有數據類型
最後一個字段後不能有逗號
temporary 臨時表,會話結束時表自動消失
對於字段的定義:
字段名 數據類型 [not null | null] [default default_value] [auto_increment] [unique [key] | [primary] key] [comment 'string']
-- 表選項
-- 字符集
charset = charset_name
若是表沒有設定,則使用數據庫字符集
-- 存儲引擎
engine = engine_name 
表在管理數據時採用的不一樣的數據結構,結構不一樣會致使處理方式、提供的特性操做等不一樣
常見的引擎:innodb myisam memory/heap bdb merge example csv maxdb archive
不一樣的引擎在保存表的結構和數據時採用不一樣的方式
myisam表文件含義:.frm表定義,.myd表數據,.myi表索引
innodb表文件含義:.frm表定義,表空間數據和日誌文件
show engines -- 顯示存儲引擎的狀態信息
show engine 引擎名 {logs|status} -- 顯示存儲引擎的日誌或狀態信息
-- 數據文件目錄
data directory = '目錄'
-- 索引文件目錄
index directory = '目錄'
-- 表註釋
comment = 'string'
-- 分區選項
partition by ... (詳細見手冊)
-- 查看全部表
show tables[ like 'pattern']
show tables from 表名
-- 查看錶機構
show create table 表名 (信息更詳細)
desc 表名 / describe 表名 / explain 表名 / show columns from 表名 [like 'pattern']
show table status [from db_name] [like 'pattern']
-- 修改表
-- 修改表自己的選項
alter table 表名 表的選項
eg: alter table 表名 engine=myisam;
-- 對錶進行重命名
rename table 原表名 to 新表名
rename table 原表名 to 庫名.表名 (可將表移動到另外一個數據庫)
-- rename能夠交換兩個表名
-- 修改表的字段機構
alter table 表名 操做名
-- 操做名
add[ column] 字段名 -- 增長字段
after 字段名 -- 表示增長在該字段名後面
first -- 表示增長在第一個
add primary key(字段名) -- 建立主鍵
add unique [索引名] (字段名)-- 建立惟一索引
add index [索引名] (字段名) -- 建立普通索引
add 
drop[ column] 字段名 -- 刪除字段
modify[ column] 字段名 字段屬性 -- 支持對字段屬性進行修改,不能修改字段名(全部原有屬性也需寫上)
change[ column] 原字段名 新字段名 字段屬性 -- 支持對字段名修改
drop primary key -- 刪除主鍵(刪除主鍵前需刪除其auto_increment屬性)
drop index 索引名 -- 刪除索引
drop foreign key 外鍵 -- 刪除外鍵

-- 刪除表
drop table[ if exists] 表名 ...
-- 清空表數據
truncate [table] 表名
-- 複製表結構
create table 表名 like 要複製的表名
-- 複製表結構和數據
create table 表名 [as] select * from 要複製的表名
-- 檢查表是否有錯誤
check table tbl_name [, tbl_name] ... [option] ...
-- 優化表
optimize [local | no_write_to_binlog] table tbl_name [, tbl_name] ...
-- 修復表
repair [local | no_write_to_binlog] table tbl_name [, tbl_name] ... [quick] [extended] [use_frm]
-- 分析表
analyze [local | no_write_to_binlog] table tbl_name [, tbl_name] ...

 

/* 數據操做 */ ------------------
-- 增
insert [into] 表名 [(字段列表)] values (值列表)[, (值列表), ...]
-- 若是要插入的值列表包含全部字段而且順序一致,則能夠省略字段列表。
-- 可同時插入多條數據記錄!
replace 與 insert 徹底同樣,可互換。
insert [into] 表名 set 字段名=值[, 字段名=值, ...]
-- 查
select 字段列表 from 表名[ 其餘子句]
-- 可來自多個表的多個字段
-- 其餘子句能夠不使用
-- 字段列表能夠用*代替,表示全部字段
-- 刪
delete from 表名[ 刪除條件子句]
沒有條件子句,則會刪除所有
-- 改
update 表名 set 字段名=新值[, 字段名=新值] [更新條件]

/* 字符集編碼 */ ------------------
-- mysql、數據庫、表、字段都可設置編碼
-- 數據編碼與客戶端編碼不需一致
show variables like 'character_set_%' -- 查看全部字符集編碼項
character_set_client 客戶端向服務器發送數據時使用的編碼
character_set_results 服務器端將結果返回給客戶端所使用的編碼
character_set_connection 鏈接層編碼
set 變量名 = 變量值
set character_set_client = gbk;
set character_set_results = gbk;
set character_set_connection = gbk;
set names gbk; -- 至關於完成以上三個設置
-- 校對集
校對集用以排序
show character set [like 'pattern']/show charset [like 'pattern'] 查看全部字符集
show collation [like 'pattern'] 查看全部校對集
charset 字符集編碼 設置字符集編碼
collate 校對集編碼 設置校對集編碼

/* 數據類型(列類型) */ ------------------
1. 數值類型
-- a. 整型 ----------
類型 字節 範圍(有符號位)
tinyint 1字節 -128 ~ 127 無符號位:0 ~ 255
smallint 2字節 -32768 ~ 32767
mediumint 3字節 -8388608 ~ 8388607
int 4字節
bigint 8字節

int(m) m表示總位數
- 默認存在符號位,unsigned 屬性修改
- 顯示寬度,若是某個數不夠定義字段時設置的位數,則前面以0補填,zerofill 屬性修改
例:int(5) 插入一個數'123',補填後爲'00123'
- 在知足要求的狀況下,越小越好。
- 1表示bool值真,0表示bool值假。mysql沒有布爾類型,經過整型0和1表示。經常使用tinyint(1)表示布爾型。

-- b. 浮點型 ----------
類型 字節 範圍
float(單精度) 4字節
double(雙精度) 8字節
浮點型既支持符號位 unsigned 屬性,也支持顯示寬度 zerofill 屬性。
不一樣於整型,先後均會補填0.
定義浮點型時,需指定總位數和小數位數。
float(m, d) double(m, d)
m表示總位數,d表示小數位數。
m和d的大小會決定浮點數的範圍。不一樣於整型的固定範圍。
m既表示總位數(不包括小數點和正負號),也表示顯示寬度(全部顯示符號均包括)。
支持科學計數法表示。
浮點數表示近似值。

-- c. 定點數 ----------
decimal -- 可變長度
decimal(m, d) m也表示總位數,d表示小數位數。
保存一個精確的數值,不會發生數據的改變,不一樣於浮點數的四捨五入。
將浮點數轉換爲字符串來保存,每9位數字保存爲4個字節。

2. 字符串類型
-- a. char, varchar ----------
char 定長字符串,速度快,但浪費空間
varchar 變長字符串,速度慢,但節省空間
m表示能存儲的最大長度,此長度是字符數,非字節數。
不一樣的編碼,所佔用的空間不一樣。
char,最多255個字符,與編碼無關。
varchar,最多65535字符,與編碼有關。
一條有效記錄最大不能超過65535個字節。
utf8 最大爲21844個字符,gbk 最大爲32766個字符,latin1 最大爲65532個字符
varchar 是變長的,須要利用存儲空間保存 varchar 的長度,若是數據小於255個字節,則採用一個字節來保存長度,反之須要兩個字節來保存。
varchar 的最大有效長度由最大行大小和使用的字符集肯定。
最大有效長度是65532字節,由於在varchar存字符串時,第一個字節是空的,不存在任何數據,而後還需兩個字節來存放字符串的長度,因此有效長度是64432-1-2=65532字節。
例:若一個表定義爲 create table tb(c1 int, c2 char(30), c3 varchar(n)) charset=utf8; 問n的最大值是多少? 答:(65535-1-2-4-30*3)/3

-- b. blob, text ----------
blob 二進制字符串(字節字符串)
tinyblob, blob, mediumblob, longblob
text 非二進制字符串(字符字符串)
tinytext, text, mediumtext, longtext
text 在定義時,不須要定義長度,也不會計算總長度。
text 類型在定義時,不可給default值

-- c. binary, varbinary ----------
相似於char和varchar,用於保存二進制字符串,也就是保存字節字符串而非字符字符串。
char, varchar, text 對應 binary, varbinary, blob.

3. 日期時間類型
通常用整型保存時間戳,由於php能夠很方便的將時間戳進行格式化。
datetime 8字節 日期及時間 1000-01-01 00:00:00 到 9999-12-31 23:59:59
date 3字節 日期 1000-01-01 到 9999-12-31
timestamp 4字節 時間戳 19700101000000 到 2038-01-19 03:14:07
time 3字節 時間 -838:59:59 到 838:59:59
year 1字節 年份 1901 - 2155

datetime 「yyyy-mm-dd hh:mm:ss」
timestamp 「yy-mm-dd hh:mm:ss」
「yyyymmddhhmmss」
「yymmddhhmmss」
yyyymmddhhmmss
yymmddhhmmss
date 「yyyy-mm-dd」
「yy-mm-dd」
「yyyymmdd」
「yymmdd」
yyyymmdd
yymmdd
time 「hh:mm:ss」
「hhmmss」
hhmmss
year 「yyyy」
「yy」
yyyy
yy

4. 枚舉和集合
-- 枚舉(enum) ----------
enum(val1, val2, val3...)
在已知的值中進行單選。最大數量爲65535.
枚舉值在保存時,以2個字節的整型(smallint)保存。每一個枚舉值,按保存的位置順序,從1開始逐一遞增。
表現爲字符串類型,存儲倒是整型。
null值的索引是null。
空字符串錯誤值的索引值是0。

-- 集合(set) ----------
set(val1, val2, val3...)
create table tab ( gender set('男', '女', '無') );
insert into tab values ('男, 女');
最多能夠有64個不一樣的成員。以bigint存儲,共8個字節。採起位運算的形式。
當建立表時,set成員值的尾部空格將自動被刪除。

/* 選擇類型 */
-- php角度
1. 功能知足
2. 存儲空間儘可能小,處理效率更高
3. 考慮兼容問題

-- ip存儲 ----------
1. 只需存儲,可用字符串
2. 若是需計算,查找等,可存儲爲4個字節的無符號int,即unsigned
1) php函數轉換
ip2long可轉換爲整型,但會出現攜帶符號問題。需格式化爲無符號的整型。
利用sprintf函數格式化字符串
sprintf("%u", ip2long('192.168.3.134'));
而後用long2ip將整型轉回ip字符串
2) mysql函數轉換(無符號整型,unsigned)
inet_aton('127.0.0.1') 將ip轉爲整型
inet_ntoa(2130706433) 將整型轉爲ip

 

/* 列屬性(列約束) */ ------------------
1. 主鍵
- 能惟一標識記錄的字段,能夠做爲主鍵。
- 一個表只能有一個主鍵。
- 主鍵具備惟一性。
- 聲明字段時,用 primary key 標識。
也能夠在字段列表以後聲明
例:create table tab ( id int, stu varchar(10), primary key (id));
- 主鍵字段的值不能爲null。
- 主鍵能夠由多個字段共同組成。此時須要在字段列表後聲明的方法。
例:create table tab ( id int, stu varchar(10), age int, primary key (stu, age));

2. unique 惟一索引(惟一約束)
使得某字段的值也不能重複。

3. null 約束
null不是數據類型,是列的一個屬性。
表示當前列是否能夠爲null,表示什麼都沒有。
null, 容許爲空。默認。
not null, 不容許爲空。
insert into tab values (null, 'val');
-- 此時表示將第一個字段的值設爲null, 取決於該字段是否容許爲null

4. default 默認值屬性
當前字段的默認值。
insert into tab values (default, 'val'); -- 此時表示強制使用默認值。
create table tab ( add_time timestamp default current_timestamp );
-- 表示將當前時間的時間戳設爲默認值。
current_date, current_time

5. auto_increment 自動增加約束
自動增加必須爲索引(主鍵或unique)
只能存在一個字段爲自動增加。
默認爲1開始自動增加。能夠經過表屬性 auto_increment = x進行設置,或 alter table tbl auto_increment = x;

6. comment 註釋
例:create table tab ( id int ) comment '註釋內容';

7. foreign key 外鍵約束
用於限制主表與從表數據完整性。
alter table t1 add constraint `t1_t2_fk` foreign key (t1_id) references t2(id);
-- 將表t1的t1_id外鍵關聯到表t2的id字段。
-- 每一個外鍵都有一個名字,能夠經過 constraint 指定

存在外鍵的表,稱之爲從表(子表),外鍵指向的表,稱之爲主表(父表)。

做用:保持數據一致性,完整性,主要目的是控制存儲在外鍵表(從表)中的數據。

mysql中,能夠對innodb引擎使用外鍵約束:
語法:
foreign key (外鍵字段) references 主表名 (關聯字段) [主表記錄刪除時的動做] [主表記錄更新時的動做]
此時須要檢測一個從表的外鍵須要約束爲主表的已存在的值。外鍵在沒有關聯的狀況下,能夠設置爲null.前提是該外鍵列,沒有not null。

能夠不指定主表記錄更改或更新時的動做,那麼此時主表的操做被拒絕。
若是指定了 on update 或 on delete:在刪除或更新時,有以下幾個操做能夠選擇:
1. cascade,級聯操做。主表數據被更新(主鍵值更新),從表也被更新(外鍵值更新)。主表記錄被刪除,從表相關記錄也被刪除。
2. set null,設置爲null。主表數據被更新(主鍵值更新),從表的外鍵被設置爲null。主表記錄被刪除,從表相關記錄外鍵被設置成null。但注意,要求該外鍵列,沒有not null屬性約束。
3. restrict,拒絕父表刪除和更新。

注意,外鍵只被innodb存儲引擎所支持。其餘引擎是不支持的。


/* 建表規範 */ ------------------
-- normal format, nf
- 每一個表保存一個實體信息
- 每一個具備一個id字段做爲主鍵
- id主鍵 + 原子表
-- 1nf, 第一範式
字段不能再分,就知足第一範式。
-- 2nf, 第二範式
知足第一範式的前提下,不能出現部分依賴。
消除符合主鍵就能夠避免部分依賴。增長單列關鍵字。
-- 3nf, 第三範式
知足第二範式的前提下,不能出現傳遞依賴。
某個字段依賴於主鍵,而有其餘字段依賴於該字段。這就是傳遞依賴。
將一個實體信息的數據放在一個表內實現。


/* select */ ------------------

select [all|distinct] select_expr from -> where -> group by [合計函數] -> having -> order by -> limit

a. select_expr
-- 能夠用 * 表示全部字段。
select * from tb;
-- 能夠使用表達式(計算公式、函數調用、字段也是個表達式)
select stu, 29+25, now() from tb;
-- 能夠爲每一個列使用別名。適用於簡化列標識,避免多個列標識符重複。
- 使用 as 關鍵字,也可省略 as.
select stu+10 as add10 from tb;

b. from 子句
用於標識查詢來源。
-- 能夠爲表起別名。使用as關鍵字。
select * from tb1 as tt, tb2 as bb;
-- from子句後,能夠同時出現多個表。
-- 多個表會橫向疊加到一塊兒,而數據會造成一個笛卡爾積。
select * from tb1, tb2;

c. where 子句
-- 從from得到的數據源中進行篩選。
-- 整型1表示真,0表示假。
-- 表達式由運算符和運算數組成。
-- 運算數:變量(字段)、值、函數返回值
-- 運算符:
=, <=>, <>, !=, <=, <, >=, >, !, &&, ||, 
in (not) null, (not) like, (not) in, (not) between and, is (not), and, or, not, xor
is/is not 加上ture/false/unknown,檢驗某個值的真假
<=>與<>功能相同,<=>可用於null比較

d. group by 子句, 分組子句
group by 字段/別名 [排序方式]
分組後會進行排序。升序:asc,降序:desc

如下[合計函數]需配合 group by 使用:
count 返回不一樣的非null值數目 count(*)、count(字段)
sum 求和
max 求最大值
min 求最小值
avg 求平均值
group_concat 返回帶有來自一個組的鏈接的非null值的字符串結果。組內字符串鏈接。

e. having 子句,條件子句
與 where 功能、用法相同,執行時機不一樣。
where 在開始時執行檢測數據,對原數據進行過濾。
having 對篩選出的結果再次進行過濾。
having 字段必須是查詢出來的,where 字段必須是數據表存在的。
where 不能夠使用字段的別名,having 能夠。由於執行where代碼時,可能還沒有肯定列值。
where 不能夠使用合計函數。通常需用合計函數纔會用 having
sql標準要求having必須引用group by子句中的列或用於合計函數中的列。

f. order by 子句,排序子句
order by 排序字段/別名 排序方式 [,排序字段/別名 排序方式]...
升序:asc,降序:desc
支持多個字段的排序。

g. limit 子句,限制結果數量子句
僅對處理好的結果進行數量限制。將處理好的結果的看做是一個集合,按照記錄出現的順序,索引從0開始。
limit 起始位置, 獲取條數
省略第一個參數,表示從索引0開始。limit 獲取條數

h. distinct, all 選項
distinct 去除重複記錄
默認爲 all, 所有記錄


/* union */ ------------------
將多個select查詢的結果組合成一個結果集合。
select ... union [all|distinct] select ...
默認 distinct 方式,即全部返回的行都是惟一的
建議,對每一個select查詢加上小括號包裹。
order by 排序時,需加上 limit 進行結合。
須要各select查詢的字段數量同樣。
每一個select查詢的字段列表(數量、類型)應一致,由於結果中的字段名以第一條select語句爲準。


/* 子查詢 */ ------------------
- 子查詢需用括號包裹。
-- from型
from後要求是一個表,必須給子查詢結果取個別名。
- 簡化每一個查詢內的條件。
- from型需將結果生成一個臨時表格,可用以原表的鎖定的釋放。
- 子查詢返回一個表,表型子查詢。
select * from (select * from tb where id>0) as subfrom where id>1;
-- where型
- 子查詢返回一個值,標量子查詢。
- 不須要給子查詢取別名。
- where子查詢內的表,不能直接用以更新。
select * from tb where money = (select max(money) from tb);
-- 列子查詢
若是子查詢結果返回的是一列。
使用 in 或 not in 完成查詢
exists 和 not exists 條件
若是子查詢返回數據,則返回1或0。經常使用於判斷條件。
select column1 from t1 where exists (select * from t2);
-- 行子查詢
查詢條件是一個行。
select * from t1 where (id, gender) in (select id, gender from t2);
行構造符:(col1, col2, ...) 或 row(col1, col2, ...)
行構造符一般用於與對能返回兩個或兩個以上列的子查詢進行比較。

-- 特殊運算符
!= all() 至關於 not in
= some() 至關於 in。any 是 some 的別名
!= some() 不等同於 not in,不等於其中某一個。
all, some 能夠配合其餘運算符一塊兒使用。


/* 鏈接查詢(join) */ ------------------
將多個表的字段進行鏈接,能夠指定鏈接條件。
-- 內鏈接(inner join)
- 默認就是內鏈接,可省略inner。
- 只有數據存在時才能發送鏈接。即鏈接結果不能出現空行。
on 表示鏈接條件。其條件表達式與where相似。也能夠省略條件(表示條件永遠爲真)
也可用where表示鏈接條件。
還有 using, 但需字段名相同。 using(字段名)

-- 交叉鏈接 cross join
即,沒有條件的內鏈接。
select * from tb1 cross join tb2;
-- 外鏈接(outer join)
- 若是數據不存在,也會出如今鏈接結果中。
-- 左外鏈接 left join
若是數據不存在,左表記錄會出現,而右表爲null填充
-- 右外鏈接 right join
若是數據不存在,右表記錄會出現,而左表爲null填充
-- 天然鏈接(natural join)
自動判斷鏈接條件完成鏈接。
至關於省略了using,會自動查找相同字段名。
natural join
natural left join
natural right join

select info.id, info.name, info.stu_num, extra_info.hobby, extra_info.sex from info, extra_info where info.stu_num = extra_info.stu_id;

/* 導入導出 */ ------------------
select * into outfile 文件地址 [控制格式] from 表名; -- 導出表數據
load data [local] infile 文件地址 [replace|ignore] into table 表名 [控制格式]; -- 導入數據
生成的數據默認的分隔符是製表符
local未指定,則數據文件必須在服務器上
replace 和 ignore 關鍵詞控制對現有的惟一鍵記錄的重複的處理
-- 控制格式
fields 控制字段格式
默認:fields terminated by '\t' enclosed by '' escaped by '\\'
terminated by 'string' -- 終止
enclosed by 'char' -- 包裹
escaped by 'char' -- 轉義
-- 示例:
select a,b,a+b into outfile '/tmp/result.text'
fields terminated by ',' optionally enclosed by '"'
lines terminated by '\n'
from test_table;
lines 控制行格式
默認:lines terminated by '\n'
terminated by 'string' -- 終止

/* insert */ ------------------
select語句得到的數據能夠用insert插入。

能夠省略對列的指定,要求 values () 括號內,提供給了按照列順序出現的全部字段的值。
或者使用set語法。
insert into tbl_name set field=value,...;

能夠一次性使用多個值,採用(), (), ();的形式。
insert into tbl_name values (), (), ();

能夠在列值指定時,使用表達式。
insert into tbl_name values (field_value, 10+10, now());
能夠使用一個特殊值 default,表示該列使用默認值。
insert into tbl_name values (field_value, default);

能夠經過一個查詢的結果,做爲須要插入的值。
insert into tbl_name select ...;

能夠指定在插入的值出現主鍵(或惟一索引)衝突時,更新其餘非主鍵列的信息。
insert into tbl_name values/set/select on duplicate key update 字段=值, …;

/* delete */ ------------------
delete from tbl_name [where where_definition] [order by ...] [limit row_count]

按照條件刪除

指定刪除的最多記錄數。limit

能夠經過排序條件刪除。order by + limit

支持多表刪除,使用相似鏈接語法。
delete from 須要刪除數據多表1,表2 using 錶鏈接操做 條件。

/* truncate */ ------------------
truncate [table] tbl_name
清空數據
刪除重建表

區別:
1,truncate 是刪除表再建立,delete 是逐條刪除
2,truncate 重置auto_increment的值。而delete不會
3,truncate 不知道刪除了幾條,而delete知道。
4,當被用於帶分區的表時,truncate 會保留分區


/* 備份與還原 */ ------------------
備份,將數據的結構與表內數據保存起來。
利用 mysqldump 指令完成。

-- 導出
1. 導出一張表
  mysqldump -u用戶名 -p密碼 庫名 表名 > 文件名(d:/a.sql)
2. 導出多張表
  mysqldump -u用戶名 -p密碼 庫名 表1 表2 表3 > 文件名(d:/a.sql)
3. 導出全部表
  mysqldump -u用戶名 -p密碼 庫名 > 文件名(d:/a.sql)
4. 導出一個庫 
  mysqldump -u用戶名 -p密碼 -b 庫名 > 文件名(d:/a.sql)

能夠-w攜帶備份條件

-- 導入
1. 在登陸mysql的狀況下:
  source 備份文件
2. 在不登陸的狀況下
  mysql -u用戶名 -p密碼 庫名 < 備份文件


/* 視圖 */ ------------------
什麼是視圖:
視圖是一個虛擬表,其內容由查詢定義。同真實的表同樣,視圖包含一系列帶有名稱的列和行數據。可是,視圖並不在數據庫中以存儲的數據值集形式存在。行和列數據來自由定義視圖的查詢所引用的表,而且在引用視圖時動態生成。
視圖具備表結構文件,但不存在數據文件。
對其中所引用的基礎表來講,視圖的做用相似於篩選。定義視圖的篩選能夠來自當前或其它數據庫的一個或多個表,或者其它視圖。經過視圖進行查詢沒有任何限制,經過它們進行數據修改時的限制也不多。
視圖是存儲在數據庫中的查詢的sql語句,它主要出於兩種緣由:安全緣由,視圖能夠隱藏一些數據,如:社會保險基金錶,能夠用視圖只顯示姓名,地址,而不顯示社會保險號和工資數等,另外一緣由是可以使複雜的查詢易於理解和使用。

-- 建立視圖
create [or replace] [algorithm = {undefined | merge | temptable}] view view_name [(column_list)] as select_statement
- 視圖名必須惟一,同時不能與表重名。
- 視圖能夠使用select語句查詢到的列名,也能夠本身指定相應的列名。
- 能夠指定視圖執行的算法,經過algorithm指定。
- column_list若是存在,則數目必須等於select語句檢索的列數

-- 查看結構
show create view view_name

-- 刪除視圖
- 刪除視圖後,數據依然存在。
- 可同時刪除多個視圖。
drop view [if exists] view_name ...

-- 修改視圖結構
- 通常不修改視圖,由於不是全部的更新視圖都會映射到表上。
alter view view_name [(column_list)] as select_statement

-- 視圖做用
1. 簡化業務邏輯
2. 對客戶端隱藏真實的表結構

-- 視圖算法(algorithm)
merge 合併
將視圖的查詢語句,與外部查詢須要先合併再執行!
temptable 臨時表
將視圖執行完畢後,造成臨時表,再作外層查詢!
undefined 未定義(默認),指的是mysql自主去選擇相應的算法。

 

/* 事務(transaction) */ ------------------
事務是指邏輯上的一組操做,組成這組操做的各個單元,要不全成功要不全失敗。 
- 支持連續sql的集體成功或集體撤銷。
- 事務是數據庫在數據晚自習方面的一個功能。
- 須要利用 innodb 或 bdb 存儲引擎,對自動提交的特性支持完成。
- innodb被稱爲事務安全型引擎。

-- 事務開啓
start transaction; 或者 begin;
開啓事務後,全部被執行的sql語句均被認做當前事務內的sql語句。
-- 事務提交
commit;
-- 事務回滾
rollback;
若是部分操做發生問題,映射到事務開啓前。

-- 事務的特性
1. 原子性(atomicity)
事務是一個不可分割的工做單位,事務中的操做要麼都發生,要麼都不發生。
2. 一致性(consistency)
事務先後數據的完整性必須保持一致。
- 事務開始和結束時,外部數據一致
- 在整個事務過程當中,操做是連續的
3. 隔離性(isolation)
多個用戶併發訪問數據庫時,一個用戶的事務不能被其它用戶的事物所幹擾,多個併發事務之間的數據要相互隔離。
4. 持久性(durability)
一個事務一旦被提交,它對數據庫中的數據改變就是永久性的。

-- 事務的實現
1. 要求是事務支持的表類型
2. 執行一組相關的操做前開啓事務
3. 整組操做完成後,都成功,則提交;若是存在失敗,選擇回滾,則會回到事務開始的備份點。

-- 事務的原理
利用innodb的自動提交(autocommit)特性完成。
普通的mysql執行語句後,當前的數據提交操做都可被其餘客戶端可見。
而事務是暫時關閉「自動提交」機制,須要commit提交持久化數據操做。

-- 注意
1. 數據定義語言(ddl)語句不能被回滾,好比建立或取消數據庫的語句,和建立、取消或更改表或存儲的子程序的語句。
2. 事務不能被嵌套

-- 保存點
savepoint 保存點名稱 -- 設置一個事務保存點
rollback to savepoint 保存點名稱 -- 回滾到保存點
release savepoint 保存點名稱 -- 刪除保存點

-- innodb自動提交特性設置
set autocommit = 0|1; 0表示關閉自動提交,1表示開啓自動提交。
- 若是關閉了,那普通操做的結果對其餘客戶端也不可見,須要commit提交後才能持久化數據操做。
- 也能夠關閉自動提交來開啓事務。但與start transaction不一樣的是,
set autocommit是永久改變服務器的設置,直到下次再次修改該設置。(針對當前鏈接)
而start transaction記錄開啓前的狀態,而一旦事務提交或回滾後就須要再次開啓事務。(針對當前事務)


/* 鎖表 */
表鎖定只用於防止其它客戶端進行不正當地讀取和寫入
myisam 支持表鎖,innodb 支持行鎖
-- 鎖定
lock tables tbl_name [as alias]
-- 解鎖
unlock tables


/* 觸發器 */ ------------------
觸發程序是與表有關的命名數據庫對象,當該表出現特定事件時,將激活該對象
監聽:記錄的增長、修改、刪除。

-- 建立觸發器
create trigger trigger_name trigger_time trigger_event on tbl_name for each row trigger_stmt
參數:
trigger_time是觸發程序的動做時間。它能夠是 before 或 after,以指明觸發程序是在激活它的語句以前或以後觸發。
trigger_event指明瞭激活觸發程序的語句的類型
insert:將新行插入表時激活觸發程序
update:更改某一行時激活觸發程序
delete:從表中刪除某一行時激活觸發程序
tbl_name:監聽的表,必須是永久性的表,不能將觸發程序與temporary表或視圖關聯起來。
trigger_stmt:當觸發程序激活時執行的語句。執行多個語句,可以使用begin...end複合語句結構

-- 刪除
drop trigger [schema_name.]trigger_name

能夠使用old和new代替舊的和新的數據
更新操做,更新前是old,更新後是new.
刪除操做,只有old.
增長操做,只有new.

-- 注意
1. 對於具備相同觸發程序動做時間和事件的給定表,不能有兩個觸發程序。


-- 字符鏈接函數
concat(str1[, str2,...])

-- 分支語句
if 條件 then
執行語句
elseif 條件 then
執行語句
else
執行語句
end if;

-- 修改最外層語句結束符
delimiter 自定義結束符號
sql語句
自定義結束符號

delimiter ; -- 修改回原來的分號

-- 語句塊包裹
begin
語句塊
end

-- 特殊的執行
1. 只要添加記錄,就會觸發程序。
2. insert into on duplicate key update 語法會觸發:
若是沒有重複記錄,會觸發 before insert, after insert;
若是有重複記錄並更新,會觸發 before insert, before update, after update;
若是有重複記錄可是沒有發生更新,則觸發 before insert, before update
3. replace 語法 若是有記錄,則執行 before insert, before delete, after delete, after insert


/* sql編程 */ ------------------

--// 局部變量 ----------
-- 變量聲明
declare var_name[,...] type [default value] 
這個語句被用來聲明局部變量。要給變量提供一個默認值,請包含一個default子句。值能夠被指定爲一個表達式,不須要爲一個常數。若是沒有default子句,初始值爲null。

-- 賦值
使用 set 和 select into 語句爲變量賦值。

- 注意:在函數內是能夠使用全局變量(用戶自定義的變量)


--// 全局變量 ----------
-- 定義、賦值
set 語句能夠定義併爲變量賦值。
set @var = value;
也能夠使用select into語句爲變量初始化並賦值。這樣要求select語句只能返回一行,可是能夠是多個字段,就意味着同時爲多個變量進行賦值,變量的數量須要與查詢的列數一致。
還能夠把賦值語句看做一個表達式,經過select執行完成。此時爲了不=被看成關係運算符看待,使用:=代替。(set語句能夠使用= 和 :=)。
select @var:=20;
select @v1:=id, @v2=name from t1 limit 1;
select * from tbl_name where @var:=30;

select into 能夠將表中查詢得到的數據賦給變量。
-| select max(height) into @max_height from tb;

-- 自定義變量名
爲了不select語句中,用戶自定義的變量與系統標識符(一般是字段名)衝突,用戶自定義變量在變量名前使用@做爲開始符號。
@var=10;

- 變量被定義後,在整個會話週期都有效(登陸到退出)


--// 控制結構 ----------
-- if語句
if search_condition then 
statement_list 
[elseif search_condition then
statement_list]
...
[else
statement_list]
end if;

-- case語句
case value when [compare-value] then result
[when [compare-value] then result ...]
[else result]
end


-- while循環
[begin_label:] while search_condition do
statement_list
end while [end_label];

- 若是須要在循環內提早終止 while循環,則須要使用標籤;標籤須要成對出現。

-- 退出循環
退出整個循環 leave
退出當前循環 iterate
經過退出的標籤決定退出哪一個循環


--// 內置函數 ----------
-- 數值函數
abs(x) -- 絕對值 abs(-10.9) = 10
format(x, d) -- 格式化千分位數值 format(1234567.456, 2) = 1,234,567.46
ceil(x) -- 向上取整 ceil(10.1) = 11
floor(x) -- 向下取整 floor (10.1) = 10
round(x) -- 四捨五入去整
mod(m, n) -- m%n m mod n 求餘 10%3=1
pi() -- 得到圓周率
pow(m, n) -- m^n
sqrt(x) -- 算術平方根
rand() -- 隨機數
truncate(x, d) -- 截取d位小數

-- 時間日期函數
now(), current_timestamp(); -- 當前日期時間
current_date(); -- 當前日期
current_time(); -- 當前時間
date('yyyy-mm-dd hh:ii:ss'); -- 獲取日期部分
time('yyyy-mm-dd hh:ii:ss'); -- 獲取時間部分
date_format('yyyy-mm-dd hh:ii:ss', '%d %y %a %d %m %b %j'); -- 格式化時間
unix_timestamp(); -- 得到unix時間戳
from_unixtime(); -- 從時間戳得到時間

-- 字符串函數
length(string) -- string長度,字節
char_length(string) -- string的字符個數
substring(str, position [,length]) -- 從str的position開始,取length個字符
replace(str ,search_str ,replace_str) -- 在str中用replace_str替換search_str
instr(string ,substring) -- 返回substring首次在string中出現的位置
concat(string [,...]) -- 鏈接字串
charset(str) -- 返回字串字符集
lcase(string) -- 轉換成小寫
left(string, length) -- 從string2中的左邊起取length個字符
load_file(file_name) -- 從文件讀取內容
locate(substring, string [,start_position]) -- 同instr,但可指定開始位置
lpad(string, length, pad) -- 重複用pad加在string開頭,直到字串長度爲length
ltrim(string) -- 去除前端空格
repeat(string, count) -- 重複count次
rpad(string, length, pad) --在str後用pad補充,直到長度爲length
rtrim(string) -- 去除後端空格
strcmp(string1 ,string2) -- 逐字符比較兩字串大小

-- 流程函數
case when [condition] then result [when [condition] then result ...] [else result] end 多分支
if(expr1,expr2,expr3) 雙分支。

-- 聚合函數
count()
sum();
max();
min();
avg();
group_concat()

-- 其餘經常使用函數
md5();
default();


--// 存儲函數,自定義函數 ----------
-- 新建
create function function_name (參數列表) returns 返回值類型
函數體

- 函數名,應該合法的標識符,而且不該該與已有的關鍵字衝突。
- 一個函數應該屬於某個數據庫,能夠使用db_name.funciton_name的形式執行當前函數所屬數據庫,不然爲當前數據庫。
- 參數部分,由"參數名"和"參數類型"組成。多個參數用逗號隔開。
- 函數體由多條可用的mysql語句,流程控制,變量聲明等語句構成。
- 多條語句應該使用 begin...end 語句塊包含。
- 必定要有 return 返回值語句。

-- 刪除
drop function [if exists] function_name;

-- 查看
show function status like 'partten'
show create function function_name;

-- 修改
alter function function_name 函數選項


--// 存儲過程,自定義功能 ----------
-- 定義
存儲存儲過程 是一段代碼(過程),存儲在數據庫中的sql組成。
一個存儲過程一般用於完成一段業務邏輯,例如報名,交班費,訂單入庫等。
而一個函數一般專一與某個功能,視爲其餘程序服務的,須要在其餘語句中調用函數才能夠,而存儲過程不能被其餘調用,是本身執行 經過call執行。

-- 建立
create procedure sp_name (參數列表)
過程體

參數列表:不一樣於函數的參數列表,須要指明參數類型
in,表示輸入型
out,表示輸出型
inout,表示混合型

注意,沒有返回值。


/* 存儲過程 */ ------------------
存儲過程是一段可執行性代碼的集合。相比函數,更偏向於業務邏輯。
調用:call 過程名
-- 注意
- 沒有返回值。
- 只能單獨調用,不可夾雜在其餘語句中

-- 參數
in|out|inout 參數名 數據類型
in 輸入:在調用過程當中,將數據輸入到過程體內部的參數
out 輸出:在調用過程當中,將過程體處理完的結果返回到客戶端
inout 輸入輸出:既可輸入,也可輸出

-- 語法
create procedure 過程名 (參數列表)
begin
過程體
end

 

/* 表維護 */
-- 分析和存儲表的關鍵字分佈
analyze [local | no_write_to_binlog] table 表名 ...
-- 檢查一個或多個表是否有錯誤
check table tbl_name [, tbl_name] ... [option] ...
option = {quick | fast | medium | extended | changed}
-- 整理數據文件的碎片
optimize [local | no_write_to_binlog] table tbl_name [, tbl_name] ...


/* 雜項 */ ------------------
1. 可用反引號(`)爲標識符(庫名、表名、字段名、索引、別名)包裹,以免與關鍵字重名!中文也能夠做爲標識符!
2. 每一個庫目錄存在一個保存當前數據庫的選項文件db.opt。
3. 註釋:
單行註釋 # 註釋內容
多行註釋 /* 註釋內容 */
單行註釋 -- 註釋內容 (標準sql註釋風格,要求雙破折號後加一空格符(空格、tab、換行等))
4. 模式通配符:
_ 任意單個字符
% 任意多個字符,甚至包括零字符
單引號須要進行轉義 \'
5. cmd命令行內的語句結束符能夠爲 ";", "\g", "\g",僅影響顯示結果。其餘地方仍是用分號結束。delimiter 可修改當前對話的語句結束符。
6. sql對大小寫不敏感
7. 清除已有語句:\c

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

MySQL學習筆記

Chapter 1. MySQL數據庫的數據

 
 

MySQL數據庫是由數據組成的,爲了能方便管理和使用這些數據,咱們把這些數據進行分類,造成各類數據類型,有數據值的類型,有表中數據列的類型,有數據表的類型。理解MySQL的這些數據類型能使咱們更好地使用MySQL數據庫。下面對各類數據類型進行簡單的介紹。

1.1. 數據值類型(data type)

 

對MySQL中數據值的分類,有數值型、字符型、日期型和空值等,這和通常的編程語言的分類差很少。

1.1.1. 數值

 

MySQL中的數值分整型和浮點型兩種。MySQL支持科學記數法。整型能夠是十進制,也但是十六進制數。

1.1.2. 字符串

 

MySQL支持以單或雙引號包圍的字符序列。如「MySQL tutorial」、‘Mysql Database’。

MySQL能識別字符串中的轉義序列,轉義序列用反斜槓(\)表示。下面是一個轉義序列列表。

Table 1.1. 轉義序列

轉義序列 含義
\0 NUL(ASCII的0值)
\' 單引號
\" 雙引號
\b 後退符
\n 換行符
\r 回車符
\t 製表符
\\ 反斜槓
\Z Ctrl+Z

若是字符串自己包含有單雙引號,則用如下三種方法中的一種來表示:

  • 字符串的引號和字符串兩端的引號雙同,則雙寫該引號。如:'mysql''s test'。

  • 用與字符串的引號不一樣的引號把字符串引發來,如:"mysql's test"。

  • 用反斜槓轉義引號,如:"mysql\' test",'mysql\' test'。這樣就不用理會字符串兩端的是單引號仍是雙引號了。

字符串可由一個十六進制數表示,如0x61表示字符"a"。由MySQL 4.0開始,字符串值也可用ANSI SQL表示法X'val'來表示。如X'61'表示字符"a"。

從MySQL 4.1開始,能夠爲字符串值專門指定一個字符集。

1.1.3. 日期和時間

 

MySQL默認按「年-月-日」的順序顯示日期。

1.2. 列類型(column type)

 

MySQL數據庫的表是一個二維表,由一個或多個數據列構成。每一個數據列都有它的特定類型,該類型決定了MySQL如何看待該列數據,咱們能夠把整型數值存放到字符類型的列中,MySQL則會把它當作字符串來處理。MySQL中的列類型有三種:數值類、字符串類和日期/時間類。從大類來看列類型和數值類型同樣,都是隻有三種。但每種列類型都還可細分。下面對各類列類型進行詳細介紹。

1.2.1. 數值類的數據列類型

 

數值型的列類型包括整型和浮點型兩大類。

Table 1.2. 數值類數據列類型

數據列類型 存儲空間 描述
TINYINT 1字節 很是小的正整數,帶符號:-128~127,不帶符號:0~255
SMALLINT 2字節 小整數,帶符號:-32768~32767,不帶符號:0~65535
MEDIUMINT 3字節 中等大小的整數,帶符號:-8388608~8388607,不帶符號:0~16777215
INT 4字節 標準整數,帶符號:-2147483648~2147483647,不帶符號:0~4294967295
BIGINT 8字節 大整數,帶符號:-9223372036854775808~9233372036854775807,不帶符號:0~18446744073709551615
FLOAT 4字節 單精度浮點數,最小非零值:+-1.175494351E-38,最大非零值:+-3.402823466E+38
DOUBLE 8字節 雙精度浮點數,最小非零值:+-2.2250738585072014E-308,最大非零值:+-1.7976931348623157E+308
DECIMAL M+2字節 以字符串形式表示的浮點數,它的取值範圍可變,由M和D的值決定。

1.2.1.1. 整型數據列類型

 

MySQL有五種整型數據列類型,即TINYINT,SMALLINT,MEDIUMINT,INT和BIGINT。它們之間的區別是取值範圍不一樣,存儲空間也各不相同。在整型數據列後加上UNSIGNED屬性能夠禁止負數,取值從0開始。

聲明整型數據列時,咱們能夠爲它指定個顯示寬度M(1~255),如INT(5),指定顯示寬度爲5個字符,若是沒有給它指定顯示寬度,MySQL會爲它指定一個默認值。顯示寬度只用於顯示,並不能限制取值範圍和佔用空間,如:INT(3)會佔用4個字節的存儲空間,而且容許的最大值也不會是999,而是INT整型所容許的最大值。

1.2.1.2. 浮點型數據列類型

 

MySQL有三種浮點型數據列類型,分別是:FLOAT,DOUBLE和DECIMAL。浮點類數據類型有一個最大可表示值和一個最小非零可表示值,最小非零可表示值決定了該類型的精確度。

MySQL 4.0.2版以後,FLOAT和DOUBLE均可以指定UNSIGNED屬性。當指定該屬性時,取值範圍不平移到正數區間,而只是簡單地把浮點類型的負數部份去掉。

浮點類型也有M(1~255)和D(1~30,且不能大於M-2)。分別表示顯示寬度和小數位數。M和D在FLOAT和DOUBLE中是可選的,默認,當MySQL版本大於3.23.6時,FLOAT和DOUBLE類型將被保存爲硬件所支持的最大精度。DECIMAL的M和D值在MySQL3.23.6後可選,默認D值爲0,M值爲10。

1.2.1.3. 如何選擇數值類數據列類型?

 

爲了節省存儲空間和提升數據庫處理效率,咱們應根據應用數據的取值範圍來選擇一個最適合的數據列類型。若是把一個超出數據列取值範圍的數存入該列,則MySQL就會截短該值,如:咱們把99999存入SMALLINT(3)數據列裏,由於SMALLINT(3)的取值範圍是-32768~32767,因此就會被截短成32767存儲。顯示寬度3不會影響數值的存儲。隻影響顯示。

對於浮點數據列,存入的數值會被該列定義的小數位進行四捨五入。如把一個1.234存入FLOAT(6.1)數據列中,結果是1.2。

DECIMAL與FLOAT和DOUBLE的區別是:DECIMAL類型的值是以字符串的形式被儲存起來的,它的小數位數是固定的。它的優勢是,不會象FLOAT和DOUBLE類型數據列那樣進行四捨五入而產生偏差,因此很適合用於財務計算;而它的缺點是:因爲它的存儲格式不一樣,CPU不能對它進行直接運算,從而影響運算效率。DECIMAL(M,D)總共要佔用M+2個字節。

1.2.1.4. 數值類數據列的屬性

 
  • ZEROFILL屬性適用於全部數值類數據列類型,做用是,若是數值的寬度小於定義的顯示寬度,則在數值前填充0。

  • UNSIGNED屬性不容許數據列出現負數。

  • AUTO_INCREMENT屬性可生成獨一無二的數字序列。只對整數類的數據列有效。

  • NULL和NOT NULL屬性設置數據列是否可爲空。

  • DEFAULT屬性可爲數據列指定默認值。

1.2.2. 字符串類數據列類型

 

字符串能夠用來表示任何一種值,因此它是最基本的類型之一。咱們能夠用字符串類型來存儲圖象或聲音之類的二進制數據,也可存儲用gzip壓縮的數據。下表介紹了各類字符串類型:

Table 1.3. 字符串類數據列類型

類型 最大長度 佔用存儲空間
CHAR[(M)] M字節 M字節
VARCHAR[(M)] M字節 L+1字節
TINYBLOD,TINYTEXT 2^8-1字節 L+1字節
BLOB,TEXT 2^16-1字節 L+2
MEDIUMBLOB,MEDIUMTEXT 2^24-1字節 L+3
LONGBLOB,LONGTEXT 2^32-1字節 L+4
ENUM('value1','value2',...) 65535個成員 1或2字節
SET('value1','value2',...) 64個成員 1,2,3,4或8字節

L+一、L+2是表示數據列是可變長度的,它佔用的空間會根據數據行的增減面則改變。數據行的總長度取決於存放在這些數據列裏的數據值的長度。L+1或L+2裏多出來的字節是用來保存數據值的長度的。在對長度可變的數據進行處理時,MySQL要把數據內容和數據長度都保存起來。

若是把超出字符串最大長度的數據放到字符類數據列中,MySQL會自動進行截短處理。

ENUM和SET類型的數據列定義裏有一個列表,列表裏的元素就是該數據列的合法取值。若是試圖把一個沒有在列表裏的值放到數據列裏,它會被轉換爲空字符串(「」)。

字符串類型的值被保存爲一組連續的字節序列,並會根據它們容納的是二進制字符串仍是非二進制字符而被區別對待爲字節或者字符:

  • 二進制字符串被視爲一個連續的字節序列,與字符集無關。MySQL把BLOB數據列和帶BINARY屬性的CHAR和VARCHAR數據列裏的數據看成二進制值。

  • 非二進制字符串被視爲一個連續排列的字符序列。與字符集有關。MySQL把TEXT列與不帶BINARY屬性的CHAR和VARCHAR數據列裏的數據看成二進制值對待。

在MySQL4.1之後的版本中,不一樣的數據列能夠使用不一樣的字符集。在MySQL4.1版本之前,MySQL用服務器的字符集做爲默認字符集。

非二進制字符串,即咱們一般所說的字符串,是按字符在字符集中前後次序進行比較和排序的。而二進制字符串由於與字符集無關,因此不以字符順序排序,而是以字節的二進制值做爲比較和排序的依據。下面介紹兩種字符串的比較方式:

  • 二進制字符串的比較方式是一個字節一個字節進行的,比較的依據是兩個字節的二進制值。也就是說它是區分大小寫的,由於同一個字母的大小寫的數值編碼是不同的。

  • 非二進制字符串的比較方式是一個字符一個字符進行的,比較的依據是兩個字符在字符集中的前後順序。在大多數字符集中,同一個字母的大小寫每每有着相同的前後順序,因此它不區分大小寫。

二進制字符串與字符集無關,因此不管按字符計算仍是按字節計算,二進制字符串的長度都是同樣的。因此VARCHAR(20)並不表示它最多能容納20個字符,而是表示它最多隻能容納能夠用20個字節表示出來的字符。對於單字節字符集,每一個字符只佔用一個字節,因此這二者的長度是同樣的,但對於多字節字符集,它能容納的字符個數確定少於20個。

1.2.2.1. CHAR和VARCHAR

 

CHAR和VARCHAR是最經常使用的兩種字符串類型,它們之間的區別是:

  • CHAR是固定長度的,每一個值佔用相同的字節,不夠的位數MySQL會在它的右邊用空格字符補足。

  • VARCHAR是一種可變長度的類型,每一個值佔用其恰好的字節數再加上一個用來記錄其長度的字節即L+1字節。

CHAR(0)和VARCHAR(0)都是合法的。VARCHAR(0)是從MySQL4.0.2版開始的。它們的做用是做爲佔位符或用來表示各類on/off開關值。

如何選擇CHAR和VARCHAR,這裏給出兩個原則:

  • 若是數據都有相同的長度,選用VARCHAR會多佔用空間,由於有一位用來存儲其長度。若是數據長短不一,選用VARCHAR能節省存儲空間。而CHAR不論字符長短都需佔用相同的空間,即便是空值也不例外。

  • 若是長度出入不大,並且是使用MyISAM或ISAM類型的表,則用CHAR會比VARCHAR好,由於MyISAM和ISAM類型的表對處理固定長度的行的效率高。

[Note]  
在一個數據表裏,只要有一個數據列的長度是可變的,則全部數據列的長度將是可變的。MySQL會進行自動地轉換。一個例外,CHAR長度小於4的不會進行自動轉換,由於MySQL會認爲這樣作不必,節省不了多少空間。反而MySQL會把大量長度小的VARCHAR轉換成CHAR,以減小空間佔用量。

1.2.2.2. BLOB和TEXT

 

BLOB是二進制字符串,TEXT是非二進制字符串。二者均可存放大容量的信息。

有關BLOB和TEXT索引的創建:

  • BDB表類型和MySQL3.23.2以上版本的MyISAM表類型容許在BLOB和TEXT數據列上創建索引。

  • ISAM、HEAP和InnoDB表不支持大對象列的索引。

使用BLOB和TEXT應注意的問題:

  • 因爲這兩個列類型所存儲的數據量大,因此刪除和修改操做容易在數據表裏產生大量的碎片,需按期運行OPTIMIZE TABLE以減小碎片和提升性能。

  • 若是使用的值很是巨大,就需對服務器進行相應的優化調整,增長max_allowed_packet參數的值。對那些可會用到變些巨大數據的客戶程序,也需加大它們的數據包大小。

1.2.2.3. ENUM和SET

 

ENUM和SET都是比較特殊的字符串數據列類型,它們的取值範圍是一個預先定義好的列表。ENUM或SET數據列的取值只能從這個列表中進行選擇。ENUM和SET的主要區別是:

  • ENUM只能取單值,它的數據列表是一個枚舉集合。它的合法取值列表最多容許有65535個成員。例如:ENUM("N","Y")表示,該數據列的取值要麼是"Y",要麼就是"N"。

  • SET可取多值。它的合法取值列表最多容許有64個成員。空字符串也是一個合法的SET值。

ENUM和SET的值是以字符串形式出現的,但在內部,MySQL以數值的形式存儲它們。

  • ENUM的合法取值列表中的字符串被按聲明定義的順序被編號,從1開始。

  • SET的編號不是按順序進行編號的,SET中每個合法取值都對應着SET值裏的一個位。第一個合法取值對應0位,第二個合法取值對應1位,以此類推,若是數值形式的SET值等於0,則說明它是一個空字符串,若是某個合法的取值出如今SET數據列裏,與之對應的位就會被置位;若是某個合法的取值沒有出如今SET數據列裏,與之對應的位就會被清零。正由於SET值與位有這樣的對應關係,因此SET數據列的多個合法取值才能同時出現並構成SET值。

1.2.2.4. 字符串類型數據列的字符集屬性

 

在MySQL 4.1之前的版本,字符串數據列的字符集由服務器的字符決定,MySQL 4.1版之後的版本可對每一個字符串數據列指定不一樣的字符串。若是按默認方式設置,可按數據列、數據表、數據庫、服務器的順序關聯字符串的字符集,直到找一個明肯定義的字符集。

1.2.3. 日期,時間型數據列類型

 

MySQL的日期時間類型有:DATE,DATETIME,TIME,TIMESTAMP和YEAR,下表是這些類型的取值範圍和存儲空間要求:

Table 1.4. 日期,時間類型列

類型 取值範圍 存儲空間 零值表示法
DATE 1000-01-01~9999-12-31 3字節(MySQL3.23版之前是4字節 ) 0000-00-00
TIME -838:59:59~838:59:59 3字節 00:00:00
DATETIME 1000-01-01 00:00:00~9999-12-31 23:59:59 8字節 0000-00-00 00:00:00
TIMESTAMP 19700101000000~2037年的某個時刻 4字節 00000000000000
YEAR YEAR(4):1901~2155 YEAR(2):1970~2069 1字節 0000
[Note]  
MySQL老是把日期和日期裏的年份放在最前面,按年月日的順序顯示。

1.2.3.1. DATE、TIME、DATATIME數據列類型

 

DATE、TIME和DATATIME類型分別存放日期值、時間值、日期和時間值的組合。它們的格式分別是「CCYY-MM-DD」、「hh:mm:ss」、「CCYY-MM-DD hh:mm:ss」。

DATATIME裏的時間值和TIME值是有區別的,DATATIME裏的時間值表明的是幾點幾分,TIME值表明的是所花費的時間。當向TIME數據列插值時,需用時間的完整寫法,如12分30秒要寫成「00:12:30」。

1.2.3.2. TIMESTAMP數據列類型

 

TIMESTAMP數據列的格式是CCYYMMDDhhmmss,取值範圍從19700101000000開始,即1970年1月1號,最大到2037年。它的特色是能把數據行的建立或修改時間記錄下來:

  • 若是把一個NULL值插入TIMESTAMP列,這個數據列就將自動取值爲當前的日期和時間。

  • 在建立和修改數據行時,若是沒有明確對TIMESTAMP數據列進行賦值,則它就會自動取值爲當前的日期和時間。若是行中有多個TIMESTAMP列,只有第一個會自動取值。

  • 若是對TIMESTAMP設置一個肯定的日期和時間值,則會使TIMESTAMP的自動取值功能失效。

TIMESTAMP默認的列寬是14,可指定列寬,以改變顯示效果。但不論你指定的列寬如何,MySQL都是以4字節來存儲TIMESTAMP值,也老是以14位精度來計算。

若是須要把建立時間和最近一次修改時間同時記錄下來,能夠用兩個時間戳來記錄,一個記錄建立時間,一個記錄修改時間。不過需記住兩件事,一是要把記錄修改時間的TIMESTAMP數據列放在最前面,這樣纔會自動取值;二是建立一條新記錄時,要用now()函數來初始化建立時間TIMESTAMP數據列,這樣,該TIMESTAMP數據列就不會再變化。

1.2.3.3. YEAR

 

YEAR是一種單字節的數據列類型,YEAR(4)的取值範圍是1901~2155,YEAR(2)的取值範圍是1970~2069,但只顯示最後兩位數。MySQL能自動把兩位數字年份轉換成四位數字的年份,如97和14分被轉換成1997和2014。轉換規則是這樣的:

  • 年份值00~69將被轉換成2000~2069;

  • 年份值70~99將被轉換成1970~1999。

[Note]  
00被轉換成0000,而不是2000。由於數值00也就是0,而0值是YEAR的一個合法取值。

1.3. 惟一編號

 

在數據庫應用,咱們常常要用到惟一編號,以標識記錄。在MySQL中可經過數據列的AUTO_INCREMENT屬性來自動生成。MySQL支持多種數據表,每種數據表的自增屬性都有差別,這裏將介紹各類數據表裏的數據列自增屬性。

  • ISAM表

    • 若是把一個NULL插入到一個AUTO_INCREMENT數據列裏去,MySQL將自動生成下一個序列編號。編號從1開始,並1爲基數遞增。

    • 把0插入AUTO_INCREMENT數據列的效果與插入NULL值同樣。但不建議這樣作,仍是以插入NULL值爲好。

    • 當插入記錄時,沒有爲AUTO_INCREMENT明確指定值,則等同插入NULL值。

    • 當插入記錄時,若是爲AUTO_INCREMENT數據列明確指定了一個數值,則會出現兩種狀況,狀況一,若是插入的值與已有的編號重複,則會出現出錯信息,由於AUTO_INCREMENT數據列的值必須是惟一的;狀況二,若是插入的值大於已編號的值,則會把該插入到數據列中,並使在下一個編號將從這個新值開始遞增。也就是說,能夠跳過一些編號。

    • 若是自增序列的最大值被刪除了,則在插入新記錄時,該值被重用。

    • 若是用UPDATE命令更新自增列,若是列值與已有的值重複,則會出錯。若是大於已有值,則下一個編號從該值開始遞增。

    • 若是用replace命令基於AUTO_INCREMENT數據列裏的值來修改數據表裏的現有記錄,即AUTO_INCREMENT數據列出如今了replace命令的where子句裏,相應的AUTO_INCREMENT值將不會發生變化。但若是replace命令是經過其它的PRIMARY KEY OR UNIQUE索引來修改現有記錄的(即AUTO_INCREMENT數據列沒有出如今replace命令的where子句中),相應的AUTO_INCREMENT值--若是設置其爲NULL(如沒有對它賦值)的話--就會發生變化。

    • last_insert_id()函數可得到自增列自動生成的最後一個編號。但該函數只與服務器的本次會話過程當中生成的值有關。若是在與服務器的本次會話中還沒有生成AUTO_INCREMENT值,則該函數返回0。

    其它數據表的自動編號機制都以ISAM表中的機制爲基礎。

  • MyISAM數據表

    • 刪除最大編號的記錄後,該編號不可重用。

    • 可在建表時可用「AUTO_INCREMENT=n」選項來指定一個自增的初始值。

    • 可用alter table table_name AUTO_INCREMENT=n命令來重設自增的起始值。

    • 可以使用複合索引在同一個數據表裏建立多個相互獨立的自增序列,具體作法是這樣的:爲數據表建立一個由多個數據列組成的PRIMARY KEY OR UNIQUE索引,並把AUTO_INCREMENT數據列包括在這個索引裏做爲它的最後一個數據列。這樣,這個複合索引裏,前面的那些數據列每構成一種獨一無二的組合,最末尾的AUTO_INCREMENT數據列就會生成一個與該組合相對應的序列編號。

  • HEAP數據表

    • HEAP數據表從MySQL4.1開始才容許使用自增列。

    • 自增值可經過CREATE TABLE語句的 AUTO_INCREMENT=n選項來設置。

    • 可經過ALTER TABLE語句的AUTO_INCREMENT=n選項來修改自增始初值。

    • 編號不可重用。

    • HEAP數據表不支持在一個數據表中使用複合索引來生成多個互不干擾的序列編號。

  • BDB數據表

    • 不可經過CREATE TABLE OR ALTER TABLE的AUTO_INCREMENT=n選項來改變自增初始值。

    • 可重用編號。

    • 支持在一個數據表裏使用複合索引來生成多個互不干擾的序列編號。

  • InnDB數據表

    • 不可經過CREATE TABLE OR ALTER TABLE的AUTO_INCREMENT=n選項來改變自增初始值。

    • 不可重用編號。

    • 不支持在一個數據表裏使用複合索引來生成多個互不干擾的序列編號。

在使用AUTO_INCREMENT時,應注意如下幾點:

  • AUTO_INCREMENT是數據列的一種屬性,只適用於整數類型數據列。

  • 設置AUTO_INCREMENT屬性的數據列應該是一個正數序列,因此應該把該數據列聲明爲UNSIGNED,這樣序列的編號個可增長一倍。

  • AUTO_INCREMENT數據列必須有惟一索引,以免序號重複。

  • AUTO_INCREMENT數據列必須具有NOT NULL屬性。

  • AUTO_INCREMENT數據列序號的最大值受該列的數據類型約束,如TINYINT數據列的最大編號是127,如加上UNSIGNED,則最大爲255。一旦達到上限,AUTO_INCREMENT就會失效。

  • 當進行全表刪除時,AUTO_INCREMENT會從1從新開始編號。全表刪除的意思是發出如下兩條語句時:

    delete from table_name;
    or
    truncate table table_name
    

    這是由於進行全表操做時,MySQL實際是作了這樣的優化操做:先把數據表裏的全部數據和索引刪除,而後重建數據表。若是想刪除全部的數據行又想保留序列編號信息,可這樣用一個帶where的delete命令以抑制MySQL的優化:

    delete from table_name where 1;
    

    這將迫使MySQL爲每一個刪除的數據行都作一次條件表達式的求值操做。

  • 強制MySQL不復用已經使用過的序列值的方法是:另外建立一個專門用來生成AUTO_INCREMENT序列的數據表,並作到永遠不去刪除該表的記錄。當須要在主數據表裏插入一條記錄時,先在那個專門生成序號的表中插入一個NULL值以產生一個編號,而後,在往主數據表裏插入數據時,利用LAST_INSERT_ID()函數取得這個編號,並把它賦值給主表的存放序列的數據列。如:

    insert into id set id = NULL;
    insert into main set main_id = LAST_INSERT_ID();
    
  • 可用alter命令給一個數據表增長一個具備AUTO_INCREMENT屬性的數據列。MySQL會自動生成全部的編號。

  • 要從新排列現有的序列編號,最簡單的方法是先刪除該列,再重建該,MySQL會從新生連續的編號序列。

  • 在不用AUTO_INCREMENT的狀況下生成序列,可利用帶參數的LAST_INSERT_ID()函數。若是用一個帶參數的LAST_INSERT_ID(expr)去插入或修改一個數據列,緊接着又調用不帶參數的LAST_INSERT_ID()函數,則第二次函數調用返回的就是expr的值。下面演示該方法的具體操做:

    先建立一個只有一個數據行的數據表:
    create table seq_table (id int unsigned not null);
    insert into seq_table values (0);
    接着用如下操做檢索出序列號:
    update seq_table set seq = LAST_INSERT_ID( seq + 1 );
    select LAST_INSERT_ID();
    經過修改seq+1中的常數值,可生成不一樣步長的序列,如seq+10可生成步長爲10的序列。
    

    該方法可用於計數器,在數據表中插入多行以記錄不一樣的計數值。再配合LAST_INSERT_ID()函數的返回值生成不一樣內容的計數值。這種方法的優勢是不用事務或LOCK,UNLOCK表就可生成惟一的序列編號。不會影響其它客戶程序的正常表操做。

1.4. 字符集支持

 

MySQL4.1之前版本服務器只能使用單一字符集,從MySQL4.1版本開始,不只服務器可以使用多種字符集,並且在服務器、數據庫、數據表、數據列以及字符串常數多個級別上設置不一樣的字符集。

1.4.1. MySQL4.1之前版本

 

MySQL4.1之前版本的字符集由服務器默認指定,默認值是編譯系統時指定的字符集,該字符集也可經過在啓動服務器時指定--default-character-set來修改。這種修改會對數據表的索引形成影響,由於索引的順序是和字符集有關的,修改字符集會使這個已排序的順序產生錯誤。要解決該問題,咱們要用修改後的字符集的排序順序重建表的索引。重建索引有如下幾種方法:

  • 用mysqldump導出數據,再清除表裏的內容,最後用導出文件從新導入。數據表的索引將在導入數時重建。該方法適用於全部數據表類型。

  • 刪除索引,而後重建。用alter table命令或drop index和create index命令來完成。該方法也適用於全部數據表類型。但該方法須要咱們瞭解重建索引的精肯定義。

  • MyISAM數據表的索引能夠用myisamchk程序的--recover和--quick選項加上一個用來設定新字符集的--set-character-set選項進行重建。還能夠用mysqlcheck程序的--repair和--quick選項或者一個帶QUICK選項的REPLACE TABLE語句來重建索引,這種方式較方便。

1.4.2. MySQL4.1之後版本

 

MySQL4.1之後的版本對字符集的支持好了不少,具備如下新增功能:

  • 支持服務器同時使用多種字符集。

  • 容許在服務器,數據庫,數據表,數據列等多級別上設置不一樣的字符集。

    • 服務器的默認字符集在編譯時選定,但可在啓動服務器時用--default-character-set選項來更改。

    • 用ALTER DATABASE db_name DEFAULT CHARACTER SET charset來設置數據庫字符集。 若是隻有default參數,則使用服務器的字符集。

    • 用CREATE TABLE table_name(...) CHARACTER SET = charset設置數據表字符集。若是charset爲default,則使用數據表所在數據庫的字符集做爲數據表的字符集。

    • 在數據列中,可用CHARACTER SET charset屬性來設置數據列的字符集。charset不能是default,若是沒有該屬性,則默認使用數據表的字符集。容許設置字符集的數據列有char,varchar(不帶binary屬性)及TEXT類型。

    • 用_charset str轉換字符串常數的字符集。如:_utf8 'mysql',_latinl 'oracle'。該方法只適用於括在引號內的字符串,其它十六進制常數 、字符串表達式等可用CONVERT()函數進行轉換,如:SELECT CONVERT( str USING charset)。

  • 經過MySQL提供的函數可進行字符集轉換和查詢。

  • 新增的COLLATE操做符使咱們可按某一種字符集的排序順序來處理另外一種字符集的數據。如:SELECT a from t ORDER BY a COLLATE utf-8;

  • 用SHOW CHARACTER SET命令可顯示服務器支持的字符集列表。

  • 當服務器轉換到另外一種字符集時,會自動對索引進行從新排序。

  • 經過UTF-8和UCS2字符集提供了Unicode支持。

MySQL如今還不支持:1,在同一個字符串裏混用不一樣字符集的字符;2,在同一個數據列裏混用不一樣的字符集。

1.4.3. 各級字符集的查詢方法

 
  • 服務器級

    SHOW CHARACTER SET;可查出可供使用的全部字符集。
    SHOW VARIABLES LIKE 'character_set';可查出服務器的默認字符集。
    
  • 可查出數據庫級的字符集。

    SHOW CREATE DATABASE db_name;
    
  • 兩條命令可查出數據表的字符集。

    SHOW CREATE TABLE table_name;
    SHOW TABLE STATUS LIKE 'table_name'
    
  • 如下幾命令可查出數據列的字符集:

    DESCRIBE table_name;
    SHOW COLUMNS FROM table_name;
    SHOW CREATE TABLE table_name;
    
  • 用CHARSET()函數可肯定特定字符串,字符串表達式或數據列值相關聯的字符串的字符集。如:SELECT CHARSET(str)。

1.4.4. Unicode支持

 

MySQL提供兩種字符集來支持Unicode。一個是UTF-8,一種可變長的編碼格式,需用1至4個字節來表示一個字符;另外一個是UCS2,該字符集中的每一個字符須要用兩個字節來表示。

1.5. 如何選擇數據列類型?

 

選擇正確的數據列類型能大大提升數據庫的性能和使數據庫具備高擴展性。在選擇數據列類型時,請從如下幾個方面考慮:

  • 存放到數據列中的數據類型。

  • 數據值的取值範圍。

  • 考慮性能和處理效率。

    • 數值操做比字符操做快。

    • 小類型的處理速度比大類型快。

    • 不一樣數據表中固定長度類型和可變長度類型的處理效率是不一樣的。

      可變長度類型在通過刪除和修改操做後容易產生碎片,下降系統性能,需按期運行OPTIMIZE TABLE命令以優化數據表。

      固定長度類型因爲有固定的長度,因此容易肯定每條記錄的起始點,可加快數據表的修復速度。

      在MyISAM和ISAM表中使用固定長度類型數據列有助改善數據庫性能。

      在InnoDB表中,固定長度和可變長度數據列類型都以相同方式存儲,因此固定長度數據列類型並無性能優點,反而因爲可度長度數據列類型因爲佔用存儲空間較少,因此處理速度會快些。

    • 可索引類型能加快數據的查詢速度。

    • 明確指定數據列的NOT NULL屬性可以使MySQL在檢索過程當中不用去判斷數據列是不是NULL,因此可加快處理速度。

  • 數據如何進行比較,是否區分大小寫。

  • 是否要在數據列上創建索引。

1.6. 表達式操做符

 

Table 1.5. 算術操做符

操做符 語法 含義
+ a + b 相加
- a - b 相減
- - a 求負
* a * b 乘法
/ a / b 除法
% a % b 求餘

Table 1.6. 邏輯操做符

操做符 語法 含義
AND 或 && a AND b 或 a && b 邏輯與,若兩個操做數同時爲真,則爲真
OR 或 || a OR b 或 a || b 邏輯或,只要有一個操做數爲真,則爲真
XOR a XOR b 邏輯異或,如有且僅有一個操做數爲真,則爲真
NOT 或 ! NOT a 或 !a 邏輯非,若操做數爲假,則爲真

Table 1.7. 位操做符

操做符 語法 含義
& a & b 按位與,若操做數同位同爲1,則該位爲1
| a | b 按位或,若操做數同位有一位爲1,則該位爲1
^ a ^ b 按拉異或,若操做數同一位分別爲1和0,則該位爲1
<< a << b 把a中的各個位左移b個位置
>> a >> b 把a中的各個位右移b個位置

Table 1.8. 比較操做符

操做符 語法 含義
= a = b 若兩個操做數相等,則爲真
<=> a <=> b 若兩個操做數相等,則爲真,可用於NULL值比較
!= 或 <> a != b 或 a <> b 若兩個操用數不等,則爲真
< a < b 若a小於b,則爲真
<= a <= b 若a小於或等於b,則爲真
> a > b 若a大於b,則爲真
>= a > b 若a大於或等於b,則爲真
IN a IN (b1,b2,...) 若a等於b1,b2,...中的某一個,則爲真
BETWEEN a BETWEEN b AND c 若a在b和c之間(包括b和c),則爲真
NOT BETWEEN a NOT BETWEEN b AND c 若a不在b和c之間(包括b和c),則爲真
LIKE a LIKE b SQL模式匹配,若a匹配b,則爲真
NOT LIKE a NOT LIKE b SQL模式匹配,若a不匹配b,則爲真
REGEXP a REGEXP b 正則表達式匹配,若a匹配b,則爲真
NOT REGEXP a NOT REGEXP b 正則表達式匹配,若a不匹配b,則爲真
IS NULL a IS NULL 若a爲NULL,則爲真
IS NOT NULL a IS NOT NULL 若a不爲NULL,則爲真
[Note]  
LIKE模式匹配中的「%」匹配任意個字符,「_」匹配一個字符。匹配不區分大小寫字符。

Table 1.9. 操做符優先級(由高至低排列)

操做符
BINARY,COLLATE
NOT、!
^
XOR
-(一元求負操做符)、~(一元取反操做符)
*、/、%
+、-
<<、>>
&
|
<、<=、=、<=>、!=、<>、>=、>、IN、IS、LIKE、REGEXP、RLIKE
BETWEEN、CASE、WHEN、THEN、ELSE
AND、&&
OR、||
:=

1.7. 類型轉換

 

在MySQL的表達式中,若是某個數據值的類型與上下文所要求的類型不相符,MySQL則會根據將要進行的操做自動地對數據值進行類型轉換。如:

1 + '2'      會轉換成1 + 2 = 3
1+ 'abc'     會轉換成1 + 0 = 1 因爲abc不能轉換成任何的值,因此默認爲0

MySQL會根據表達式上下文的要求,把字符串和數值自動轉換爲日期和時間值

對於超範圍或非法的值,MySQL也會進行轉換,但轉換出來的結果是錯誤的。出現該狀況時,MySQL會提示警告信息,咱們可捕獲該信息以進行相應的處理。

Chapter 2. 查詢優化

 

數據庫是數據的集合,與數學的集合論有密不可分的關係。

爲提升查詢速度,咱們能夠:

  • 對數據表添加索引,以加快搜索速度;

  • 經過編程技巧最大限度地利用索引;

  • 優化查詢語句,以使服務器最快響應多客戶的請求。

  • 研究硬件處理過程,減小物理約束。

2.1. 索引

 

索引技術是關係數據查詢中最重要的技術。若是要加提高數據庫的性能,索引優化是首先應該考慮的。由於它能使咱們的數據庫獲得最大性能方面的提高。

索引的優勢:

  • 沒有索引的表是沒有排序的數據集合,若是要查詢數據需進行全表掃描。有索引的表是一個在索引列上排序了數據表,可經過索引快速定位記錄。在MyISAM和ISAM數據表中,數據行保存在數據文件中,索引保存在索引文件中。BDB與InnoDB數據表把數據與索引放在同一個文件中。

  • 在多表關聯查詢中,索引的做用就更大。若是沒有索引,在最壞的狀況下,全表掃描的次數多是各表數據行的組合個數,多是一個天文數字。這樣的查詢是破壞性的,可能會形成數據庫癱瘓。

  • 對於使用了MIN()或是MAX()函數的查詢,若是相關的數據列上有索引,MySQL能直接找到該最大、最小值的行,根本不用一個一個地去檢查數據行。

  • 索引加快ORDER BY 和 GROUP BY子句的操做。

  • 當在數值型數據列上查詢數據,而該列有索引,索引能使MySQL根本不用去讀取數據行,直接從索引取值。

索引的缺點:

  • 索引需佔用磁盤空間。

  • 索引會減慢在索引數據列上的插入、刪除和修改操做。

索引列的選擇

  • 索引應該建立在搜索、排序、分組等操做所涉及的數據列上。也就是說,在where子句,關聯檢索中的from子句、order by或group by子句中出現過的數據列最適合用來建立索引。

  • 儘可能使用惟一索引,它能使索引起揮最好的效能。

  • 儘可能用比較短的值進行索引。當對字符串進行索引時,應該指定一個前綴長度,好比對字符串的前10位或20位的字符進行排序,而不用把整個字符串幾十個字符用來索引排序。這樣能減小磁盤I/O,提升處理速度。最重要的一點是,鍵值越短,索引緩衝區裏容納的鍵值也就越多,而MySQL同時保存在內存裏的索引越多,索引緩衝區的命中率也就越高。固然,只對數據列第一個字符進行索引是沒什麼意義的。

  • 充分利用最左前綴。所謂最左前綴也就是在複合索引中最邊的索引列。如複合索引(a,b,c) ,其中a就是最左前綴。它是使用率最高的索引,需認真選擇。

  • 不要建太多索引,索引是會消耗系統資源的,要適可而止。

  • 索引主要用於<、<=、=、>=、>、BETWEEN等的比較操做中,因此索引應該創建在與這樣操做相關的數據列上。

  • 利用慢查詢日誌來找出性能差的查詢,經過mysqldumpslow可查看該日誌。針對性能差的查詢可利用索引來加快查詢速度。

2.2. 查詢優化程序

 

當咱們發一條查詢命令時,MySQL分對它進行分析,以優化查詢。把explain語名放到查詢前面可顯示查詢的執行路線,對優化查詢提供有用的信息。如下幾個原則可幫助系統挑選和使用索引:

  • 儘可能對同類型的數據列進行比較。如:VARCHAR(5)和VARCHAR(5)是同類型的,CHAR(5)和VARCHAR(5)是不一樣類型的。

  • 儘可能讓索引的數據列在比較表達式中單獨出現,不要把它包含在函數或複雜表達式。不然索引會不起做用。

  • 儘可能不要在LIKE模式的開頭使用通配符。如:%string%。

  • 對於MyISAM和BDB數據表,用ANALYZE TABLE語句讓服務器對索引鍵值的分佈進行分析,爲優化程序提供更有價值的信息。另外一個方法是用myisamchk --analyze(適用於MyISAM表)或isamchk --analyze(適用於ISAM表)命令。

  • 用EXPLAIN語句來分析查詢語句的執行效率。檢查查詢所使用的索引是否是可以迅速地排除不符合條件的數據行,若是不是,能夠試着用STRAIGHT_JOIN強制各有關數據表按指定順序進行關聯。

  • 嘗試查詢的不一樣寫法,比較運行狀況。

  • 不要濫用MySQL的類型自動轉換功能。自動轉換會減慢查詢的速度並會使有關的索引失效。

2.3. 數據列類型與查詢效率

 

選用適當的數據列類型有助於提升查詢命令的執行速度,下面是幾點關於如何選擇合適數據列類型的建議:

  • 儘可能選用尺寸較小的數據列。這樣能節約磁盤空間和加快查詢速度。若是較短的數據列上建有索引,則索引的處理速度會進一步提升。

  • 針對數據列類型,儘可能選擇最適用的數據表類型。如固定長度數據列在MyISAM或ISAM數據表中的速度是最快的,因此在這樣數據表中儘可能使用char類型而不是varchar類型來保存字符串數據。對於InnoDB數據表類型,因爲varchar類型可有效減小佔用空間,從而減小磁盤I/O,因此使用varchar類型是有利的。對於BDB類型數據表,使用定長和不定長列類型的區別就不大,可任選一種。

  • 儘可能把數據列聲明爲NOT NULL,以節約存儲空間和加快處理速度。

  • 對於取值範圍有限的數據列,考慮使用ENUM數據列類型。ENUM數據列類型在MySQL中的處理速度是很快。

  • 使用PROCEDURE ANALYSE()語句來分析數據表,它會對數據列的聲明提出建議,咱們可根據建議進行修改。

    select * from table_name PROCEDURE ANALYSE();
    select * from table_name PROCEDURE ANALYSE(16,256);    #(16,256)含義是:若是某列的不一樣取值在16個以上或長度超過256字節,就不提出使用ENUM的建議。
    
  • 用OPTIMIZE TABLE語句對容易出現碎片的數據表進行整理。包含可變長數據列的數據表都會產生碎片,從而佔用多餘的磁盤空間和影響查詢速度。因此要按期運行OPTIMIZE TABLE語句以防止數據表查詢性能下降。但該語句只對MyISAM數據表有效。對各類數據表通用的碎片整理方法是這樣的:先用工具程序mysqldump導出數據表,再刪除數據表後重建,如:

    $ mysqldump --opt db_name table_name > dump.sql
    $ mysql db_name < dump.sql
    
  • 把非結構化和變化大的數據放在BLOB數據列裏,按期用OPTIMIZE TABLE命令優化。

  • 人爲地給數據表增長一個數據列,以充當索引。作法是這樣的,先根據數據表裏的其它數據列計算出一個散列值,並保存在一個數據列裏,而後經過搜索散列值來檢索數據行。注意,該技巧只適用於精確匹配型查詢。散列值在大於,小於等的操做中不起做用。散列值能夠MD5()(適用於3.23及以上版本),SHA1()(適用於4.0.1及以上版本),CRC32()(適用於4.1及以上版本)等函數生成。使用散列值支檢索BLOB和TEXT值的作法比直接檢索BLOB和TEXT自己的作法快。

  • 儘可能避免對大尺寸的BLOB值進行檢索。若是要檢索都應該經過它的上面提到散列值先進行篩選。而不該該盲目地在網絡中傳送大量BLOB值。

  • 若是把BLOB值剝離到另一個數據表裏去,可實現數據表中其它數據列轉變成固定長度數據列的話。就便可減小數據表碎片,又可以使在原始表中的select *查詢不會把大尺寸的BLOB值沒必要要地經過網絡傳送。

2.4. 有效地加載數據

 

有時咱們需大量地把數據加載到數據表,採用批量加載的方式比一個一個記錄加載效率高,由於MySQL不用每加載一條記錄就刷新一次索引。下面介紹幾個有助於加快數據加載的操做:

  • 使用LOAD DATA語句要比INSERT語句的加載速度快。

  • LOAD DATA比LOAD DATA LOCAL語句的效率高。前者可由服務器直接從本地磁盤讀取加載數據,後者需由客戶程序去讀取文件並經過網絡傳送到服務器。

  • 若是必定要用INSERT語句,應儘可能在一條語句中插入多個數據行。

  • 若是必須使用多條INSERT語句,則應儘可能把它們集中在一塊兒放到一個事務中進行處理,而不是在自動提交模式下執行它們:如:

    BEGIN;
    INSERT INTO table_name values (...);
    INSERT INTO table_name values (...);
    INSERT INTO table_name values (...);
    ...
    COMMIT;
    

    對於不支持事務的表,應對錶進行寫鎖定,而後在表鎖按期間對錶進行INSERT操做,如:

    LOCK TABLES table_name WRITE;
    INSERT INTO table_name ...;
    INSERT INTO table_name ...;
    INSERT INTO table_name ...;
    ...
    UNLOCK TABLES;
    
  • 利用客戶/服務器通訊協議中的壓縮功能以減小網絡傳輸的數據量。但該壓縮會消耗大量的系統資源,因此當心使用。

  • 儘可能讓MySQL插入默認值。不要在INSERT中寫太多值,以減小網絡傳輸量和服務器端的語法分析時間。

  • 對於MyISAM和ISAM數據表,若是需加載大量數據,應先創建一個沒索引的表,加載數據後再建立索引。該方法不適用於InnoDB或BDB數據表。

禁用和從新激活索引的方法有兩種:

  • 使用ALTER TABLE語句的DISABLE KEYS和ENABLE KEYS命令,如:

    ALTER TABLE table_name DISABLE KEYS;
    ALTER TABLE table_name ENABLE KEYS;
    
  • 使用myisamchk或isamchk工具。如:

    $ myisamchk --keys-used=0 table_name                   #禁止
    $ myisamchk --recover --quick --key-used=n table_name  #激活
    n是用來代表須要激活索引的位掩碼,第0位對應第一個索引,若是有三個索引,n值就是7(二進制111)。索引編號能夠下命令肯定:
    $ myisamchk --description table_name
    

     

2.5. 調度和鎖定

 

在不少客戶一塊兒查詢數據表時,若是使客戶能最快地查詢到數據就是調度和鎖定作的工做了。在MySQL中,咱們把select操做叫作讀,把對數據表修改增長的操做(INSERT,UPDATE,REPLACE...)叫作寫。MySQL的基本調度策略能夠概括爲如下兩條:

  • 寫入請求將按它們到達服務器的順序進行處理;

  • 寫操做的優先級要高於讀操做。

MyISAM和ISAM數據表的調度策略是在數據表鎖的幫助下實現的,在客戶程序要訪問數據表以前,需得到相應的鎖,在完成對數據表的操做後,再釋放該鎖。鎖的管理一般由服務器管理,也可人爲地用LOCK TABLES和UNLOCK TABLES命令來申請和釋放鎖。寫操做時,須要申請一個獨佔性的鎖,也就是說在寫操做其間,該表只能由寫操做的客戶使用。讀操做時,客戶必須申請一個容許其餘客戶對數據表進行寫操做的鎖,以確保客戶在讀的過程當中數據表不會發生改變。但讀操做鎖不是獨佔的,可有多個讀操做同時做用於同一個數據表。

經過一些修飾符可影響調度策略,如LOW_PRIORITY(用於DELETE,INSERT,LOAD DATA,REPLACE,UPDATE語句)、HIGH_PRIORITY(用於SELECT語句)、DELAYED(用於INSERT和REPLACE語句)。它們的做用是這樣的:

  • LOW_PRIORITY會使寫操做的優先級下降到讀操做如下,也就是說讀操做會阻塞該級別的寫操做,SELECT的HIGH_PRIORITY有相似的做用。

  • INSERT語句中的DELAYED修飾會使插入操做被放入一個「延遲插入」隊列。並返回狀態信息給客戶,使客戶程序可在新數據行還沒插入到數據表以前繼續執行後面的操做。若是一直有客戶讀該數據表,新數據行會一直待在隊列中,直到數據表沒有讀操做時,服務器纔會把隊列中的數據行真正插入到數據表中。該語句可用在如下場合,在一個有冗長查詢的數據表中插入數據,而你又不想被阻塞,你就可發出INSERT DELAYED語句,把插入操做放入服務器「延遲插入」隊列,你無需等待就立刻可進行接下來的操做。

  • 當一個數據表裏從未進行過刪除操做或剛剛對它進行過碎片整理的狀況下,用INSERT語句插入的數據行只會被添加到數據表的末尾,而不會插入到數據表的中間位置。這樣,對於MyISAM表,MySQL容許在有其它客戶正在讀操做的時間進行寫操做。咱們稱之這併發插入。要使用該技巧,需注意如下兩個問題:

    • 不要在INSERT語句中使用LOW_PRIORITY修飾符。

    • 讀操做應用LOCK TABLES ... READ LOCAL而不是用LOCK TABLES ... READ語句來進行數據表讀鎖定。LOCAL關鍵字只對數據表中已存在行進行鎖定,不會阻塞把新行添加到數據表末尾。

BDB數據表使用頁面級操做鎖,InnoDB數據表使用數據行級操做鎖。因此這兩種表的併發性比MyISAM和ISAM數據表這種表級鎖的併發性會好不少。其中InnoDB的併發性最好。綜上所述,咱們可得出如下結論:

  • MyISAM和ISAM數據表的檢索速度最快,但若是在檢索和修改操做較多的場合,會出鎖競爭的問題,形成等待時間延長。

  • BDB和InnoDB數據表能在有大量修改操做的環境下提供很好的併發性,從而提供更好的性能。

  • MyISAM和ISAM數據表因爲進行表級鎖定,因此不會出現死鎖現象,BDB和InnoDB數據表則存在死鎖的可能性。

2.6. 服務器優化

 

優化原則:

  • 內存裏的數據要比磁盤上的數據訪問起來快;

  • 站數據儘量長時間地留在內存裏能減小磁盤讀寫活動的工做量;

  • 讓索引信息留在內存裏要比讓數據記錄的內容留在內存裏更重要。

針對以上幾個原則,咱們應該調整服務器:

  • 增長服務器的緩存區容量,以便數據在內存在停留的時間長一點,以減小磁盤I/0。下面介紹幾個重要的緩衝區:

    • 數據表緩衝區存放着與打開的數據表相的信息,它的大小可由服務器參數「table_cache」設置。Opened_tables參數記錄服務器進行過多少次數據表打開操做,若是該值變化很大,就多是數據表緩衝區已滿,需把一些不經常使用的表移出緩衝區,以騰出空打開新的數據表。可用如下命令查看Opened_tables的值:

      SHOW STATUS LIKE 'Opened_tables';
      
    • 在MyISAM和ISAM數據表中,索引被緩存在「key buffer」裏,它的大小由服務器參數「key_buffer_size」來控制。系統默認的大小是8M,若是內存充足的話可適當擴大該值,以使更多索引塊緩存在該區裏,以加快索引的速度。

    • InnoDB和BDB數據表也各有一個緩衝區,分別叫innodb_buffer_pool_size和bdb_cache_size。InnoDB還有一個日誌緩衝區叫innodb_log_buffer_size。

    • 自4.0.1開始,MySQL多了一個緩衝區,叫查詢緩衝區,主要用來存放重複執行的查詢文本和結果,當再次遇到相同的查詢,服務器會直接從緩衝區中返回結果。該功能是內建的功能,如不想支持該功能,可在編譯服務器時用configure腳本的--without-query-cache選項去掉該功能。

      查詢緩衝區由三個服務器參數控制,分別是:

      一、query_cache_size    
      控制緩衝區的大小,若是該值爲0,則禁用查詢緩衝功能。設置方法是在選項文件中設置:
      [mysqld]
      set-variable = query_cache_size = 16M     
      這樣就設置了一個16M的查詢緩衝區
      
      二、query_cache_limit
      緩衝結果集的最大容量(以字節爲單位),若是查詢的結果集大於該值,則不緩衝該值。
      
      三、query_cache_type
      緩衝區的操做模式。
      0表示不進行緩衝;
      1表示除SELECT SQL_NO_CACHE開頭的查詢外,其他的都緩衝;
      2表示只對以SELECT SQL_ON_CACHE開頭的查詢進行緩衝。
      

      默認狀況下,按服務器的設置進行緩衝,但客戶端也可經過命令改變服務器設置。客戶端可直接用SELECT SQL_NO_CACHE和SELECT SQL_CACHE命令來要求服務器緩衝或不緩衝查詢結果。若是不想每條查詢都寫參數,咱們也可在客戶端用SET SQL_QUERY_CACHE_TYPE = val;來改變服務器的查詢緩衝行爲。val可取值0,1,2或OFF,ON,或DEMAND。

  • 禁用用不着的數據表處理程序。如服務器是從源碼建立,就可完全禁用ISAM,InnoDB和BDB數據表。

  • 權限表裏的權限關係應儘量簡單,固然了,是要在保證安全的前提下。

  • 在從源碼建立服務器時,儘可能使用靜態庫而不是共享庫來完成其配置工做。靜態庫的執行速度更快,但若是要加載用戶定義函數(UDF)的話,就不能使用靜態庫,由於UDF機制必須依賴動態庫才能實現。

2.7. 硬件優化

 

爲了提升數據運行速度,升級硬件是最直接的解決方案。針對數據庫應用的特色,在升級硬件時應考慮如下內容:

  • 對於數據庫服務器,內存是最重要的一個影響性能因素。經過加大內存,數據庫服務器可把更多的數據保存在緩衝區,可大大減小磁盤I/O,從而提高數據庫的總體性能。

  • 配置高速磁盤系統,以減小讀盤的等待時間,提升響應速度。

  • 合理分佈磁盤I/O,應把磁盤I/O分散在多個設備上,以減小資源競爭,提升並行操做能力。

  • 配置多處理器,MySQL是多線程的數據庫,多處理器可同時執行多個線程。

Chapter 3. 數據庫管理

 

數據庫是一個複雜而又關鍵的系統,爲確保系統安全、高效運行,需熟悉數據庫內部的運做機制,掌握各類維護工具,並作好平常的管理工做。下面列舉幾項主要工做職責:

  • 服務器的關閉和啓動;

  • 管理用戶賬號;

  • 管理日誌文件;

  • 數據庫備份恢復;

  • 數據庫優化;

  • 確保數據庫數據安全;

  • 數據庫軟件升級。

3.1. 數據目錄

 

數據目錄是用來存放數據表和相關信息的地方,是數據庫的核心。在MySQL中的數據目錄根據不一樣平臺的有一些差別:

  • 在UNIX/Linux系統上,若是用源碼編譯安裝,數據目錄的位置默認是在/usr/local/mysql/var中;

  • 在UNIX/Linux系統上,若是用二進制發行版安裝,數據目錄的位置默認是在/usr/local/mysql/data中;

  • 在WINDOWS系統上,數據目錄的位置默認是在c:/mysql/data中;

[Note]  
在服務器啓動時,可用--datadir=dir_name來指定數據目錄,也可把它寫到配置文件中。

咱們還可用命令向服務器查詢數據目錄的位置,數據目錄的變量名是datadir,如:

  • % mysqladmin variables

    若是在一臺機器上同時運行多個服務器,則可根據端口的不時來查詢每一個服務器的數據目錄,如:

    % mysqladmin --host=127.0.0.1 --port=port_number variables

    若是--host是localhost,系統則會用一個UNIX套接字去鏈接數據庫服務器,這時要使用--socket選項,因此查詢語句變成:

    % mysqladmin --host=localhost --socket=/path/to/socket variables
  • mysql> SHOW VARIABLES LIKE 'datadir';
  • 在windows NT平臺上能夠使用「.」做爲一條命名管道鏈接的主機名,用--socket選項給出命名管道的名字,如:

    c:\ mysqladmin --host=. --socket=pipe_name variables
  • 配置文件的中[mysqld]段中的datadir=/path/to/datadir設置也可查詢到數據目錄。

  • 在mysqld程序的幫助信息裏也有程序編譯時默認的數據目錄信息,可用如下命令顯示:

    % mysqld --help

數據目錄是存放數據文件的地方,每一個數據庫對應目錄的不一樣文件。InnoDB數據表因爲用表空間來管理數據庫,因此就沒這種對應關係。但也是保存在數據目錄中的,在數據目錄除保存數據庫文件外,還可能會保存如下幾類文件:

  • 服務器的配置文件,my.cnf;

  • 服務器的進程ID(PID)文件;

  • 服務器的日誌文件和狀態文件,這些文件對管理數據庫有重要的價值;

  • DES密鑰文件或服務器的SSL證書與密鑰文件。

數據目錄中的全部數據庫所有由服務器(mysqld)來管理,客戶端不直接操做數據。服務器是客戶使用數據的惟一通道。

在MySQL中,每一個數據庫其實就是在數據目錄下一個子目錄,show databases命令至關於列出數據目錄中的目錄清單。create database db_name命令會在數據目錄下新建一個db_name的目錄,以存放數據庫的數據文件。因此咱們也可下面的shell命令方式來創建一個空數據庫:

% cd datadir
% mkdir db_name
% chmod u=rwx,go-rwx db_name

同理,刪除數據庫drop database db_name也就是刪除數據目錄中一個名爲db_name的目錄及目錄中的數據表文件。咱們也可用shell這進行操做:

% cd datadir
% rm -rf db_name
[Note]  
比較shell方式與drop database方式,drop database db_name命令不能刪除db_name目錄中建立的其它非數據表文件;因爲InnoDB是表空間來管理數據表,因此不能用rm或del命令刪除InnoDB的數據表。

3.2. MySQL數據表在系統中表現形式

 

MySQL數據表類型有:ISAM、MyISAM、MERGE、BDB、InnoDB和HEAP。每種數據表在文件系統中都有不一樣的表示方式,有一個共同點就是每種數據表至少有一個存放數據表結構定義的.frm文件。下面介紹每種數據表文件:

  • ISAM數據表是最原始的數據表,有三個文件,分別是:

    .frm,存放數據表的結構定義;

    .ISD,數據文件,存放數據表中的各個數據行的內空;

    .ISM,索引文件,存放數據表的全部索引信息。

  • MyISAM數據表是ISAM數據表的繼承者,也有三個文件,分別是:

    .frm,結構定義文件;

    .MYD,數據文件;

    .MYI,索引文件。

  • MERGE數據表是一個邏輯結構,表明一組結構徹底相同的MyISAM數據表構成的集合。它在文件系統中有二個文件,分別是:

    .frm,結構定義文件;

    .MRG,構成MERGE表的MyISAM數據表清單,每一個MyISAM數據表名佔一行。也就是說可經過改變該表的內容來改變MERGE數據表的結構。修改前請先刷新緩存(flush tables),但不建議這樣修改MERGE數據表。

  • BDB數據表用兩個文件來表示,分別是:

    .frm,結構定義文件;

    .db,數據表數據和索引文件

  • InnoDB因爲採用表空間的概念來管理數據表,因此它只有一個與數據表對應.frm文件,同一目錄下的其它文件表示爲表空間,存儲數據表的數據和索引。

  • HEAP數據表是一個存在於內存中的表,因此它的數據和索引都存在於內存中,文件系統中只有一個.frm文件,以定義結構。

瞭解MySQL數據表在文件系統中表現形式後,咱們可知道,建立、修改或刪除數據表,其實就是對這些文件進行操做。例如一些數據表(除InnoDB和HEAP數據表外),咱們可直接在文件系統中刪除相應的文件來刪除數據表。

% cd datadir
% rm -f mydb/mydb.*

以上命令可刪除mydb數據庫中的mydb數據表。

3.3. 數據表最大尺寸限制

 

在MySQL中影響數據表尺寸的因素有不少,下面分別進行介紹:

  • MySQL數據表類型的不一樣對數據表尺寸的限制:

    • ISAM數據表中單個.ISD和.ISM文件的最大尺寸爲4G;

    • MyISAM數據表中單個.MYD和.MYI文件的默認最大尺寸也是4G,但可在建立數據表時用AVG_ROW_LENGTH和MAX_ROWS選項把這個最值擴大到800萬TB。

    • MERGE數據表的最大尺寸是它的各組成MyISAM數據表的最大尺寸之和。

    • BDB數據表的尺寸受限於BDB處理程序所容許的.db文件的最大尺寸。這個最大尺寸隨着數據表頁面尺寸(編譯時肯定)而變化,但即便是最小的頁面尺寸(512字節),.db文件的最大尺寸也可達2TB。

    • InnoDB數據表的表空間的最大尺寸是40億個頁面,默認的頁面尺寸是16K,該值可在8K到64K之間,在編譯時肯定。InnoDB數據表的最大尺寸也就是表空間的最大尺寸。

  • 操做系統對文件的尺寸限制,通常文件系統都對單個文件不得超過2G的限制。該約束會對數據庫文件形成限制。InnoDB數據表可經過利用未格式化硬盤做爲表空間來繞過該限制。

  • 對於數據和索引分開兩個文件存放的數據表,其中任何一個文件達到操做系統文件的最大限制,數據庫表也就達到最大尺寸。

  • 包含AUTO_INCREMENT數據列的表受到該數據列類型最大上限值的限制。

  • 因爲InnoDB數據表用表空間來管理,一個表空間可同時空納多個數據表,因此數據表的最大尺寸受系統文件和同一表空間中數據表空間的約束。

3.4. 狀態文件和日誌文件

 

在MySQL數據目錄中還包含着許多狀態文件和日誌文件,這些文件的文件名都是以主機名加上相關後綴來命名的。下面是這些文件的一個說明列表:

Table 3.1. 狀態文件和日誌文件

文件類型 默認名 文件內容
進程ID文件 hostname.pid MySQL服務器進程的ID
常規查詢日誌 hostname.log 鏈接/斷開鏈接事件和查詢信息
慢查詢日誌 hostname-slow.log 記錄查詢時間很長的命令信息
變動日誌 hostname.nnn 建立或修改數據表結構和內容的查詢命令信息
二進制變動日誌 hostname-bin.nnn 建立或修改數據表結構和內容的查詢命令的二進制表示法
二進制變動日誌的索引文件 hostname-bin.index 使用中的「二進制變動日誌」列表
錯誤日誌 hostname.err 記錄「啓動/關閉」事件和異常狀況

變動日誌和二進制變動日誌主要用於MySQL數據庫服務器的崩潰恢復中,因爲變動日誌記錄了數據庫的全部變動操做,因此能夠進行事件重放。具體操做請參考相關數據庫備份恢復章節。對於變動日誌,咱們可用--log-long-format選項來讓它以擴展方式記錄有關事件。擴展方式可記錄誰發出查詢和何時發出查詢的信息。可以使咱們更好地掌握客戶端的操做狀況。日誌記錄着查詢命令的全部操做,裏面可能會有一些敏感信息。因此咱們要確保日誌文件的安全。

3.5. 調整MySQL數據目錄位置

 

MySQL數據庫的數據目錄位置,包括目錄裏的各類文件的位置)可根據實際狀況進行調整。調整的方法有兩種,一種是使用符號連接;一種用服務器啓動選項。下面一個列表說明了數據目錄及目錄中文件各自適宜採用的方法:

Table 3.2. MySQL數據目錄及目錄中文件位置的調整方法

調整對象 適用方法
整個數據目錄 啓動選項和符號連接
數據庫目錄 符號連接
數據表 符號連接
InnoDB數據表空間 啓動選項
PID文件 啓動選項
日誌文件 啓動選項

下面是各類調整方法的具體操做過程:

  • 在調整MySQL的數據目錄時,要先中止服務器,再把數據目錄移動到新的位置。接着,咱們可選擇在原來目錄下建立一個符號連接指向新的位置,或者用啓動選擇--datadir指向新的數據目錄。推薦用建立符號連接的方法,由於若是那個數據目錄中有my.cnf文件,相應的服務器還能找到它。

  • 數據庫只能存在於MySQL數據目錄中,因此只能使用符號連接的方法調整它的位置。在Linux系統的操做步驟如:

    1. 關閉服務器;

    2. 把數據庫目錄拷貝到新的位置;

    3. 刪除原來的數據庫目錄;

    4. 在原來的MySQL數據目錄中建立一個同名符號連接指向新的位置;

    5. 從新啓動服務器。

    在windows下的操做方法不些不一樣,操做方法以下:

    1. 關閉服務器;

    2. 把數據庫目錄移動新的位置;

    3. 刪除原來的數據庫目錄;

    4. 在原來數據目錄下建一個同名的.sym文件,在文件中輸入數據庫新目錄的全路徑,如c:\mysql\newdir\mydb。這個文件就至關於Linux下的符號連接;

    5. 重啓服務器。

      [Note]  
      爲了支持符號連接功能,必須用--use-symbolic-links選項啓動服務器;或在選項文件的[mysqld]節中添加use-symbolic-links選項。
      [Note]  
      MySQL必須是3.23.16以上版本且是max服務器(mysqld-max或mysqld-max-nt)。
  • 要移動數據表,必須知足如下全部條件才行:

    • MySQL的版本必須是4.0或以上的版本;

    • 操做系統必須有一個可用的realpath()調用;

    • 移動的數據表必須是MyISAM類型的數據表。

    在知足以上全部條件後,咱們就可把.MYD數據文件和MYI索引文件移到新位置,再在原來位置建立兩個同名符號連接指定新的位置。注意,.frm定義文件仍需留在原來的數據庫目錄中。

    如以上條件不能所有知足,最好不要移動數據表文件。不然一旦你運行ALTER TABLE、OPTIMIZE TABLE、REPAIR TABLE語句對移動過的數據表進行優化或修改,這樣數據表就會回到原來的位置,使移動操做失效。由於這些命令的執行過程是這樣的:它會先在數據目錄中建立一個臨時數據表並對這個臨時數據表進行優化或修改,而後刪除原來的數據表(這裏是你爲了移動數據表而建立的一個符號連接),再把臨時數據表改名爲原來的數據表名稱。這樣一來,你移走的數據表就和這個數據庫徹底沒有關係了。基於如下的不穩定因素,如無特殊必要,不建議移動數據表。

  • InnoDB表空間是經過在選項文件中使用innodb_data_home_dir和innodb_data_file_path選項列出InnoDB表空間組成文件清單的方法來配置的,因此咱們可經過修改這些選項來從新安置InnoDB表空間的組成文件。步驟以下:

    • 關閉服務器;

    • 移動組成表空間的文件;

    • 修改選項文件,指出組成表空間的文件的新位置;

    • 重啓服務器。

  • 狀態文件和日誌文件的位置可經過選項文件或啓動服務器時指定。

Chapter 4. MySQL數據庫平常管理

 

爲了確保數據庫平穩可靠運行,咱們需進行維護和管理,這是每一位數據庫管理員的職責。下面分幾個專題分別介紹。

4.1. 數據庫安全管理

 

MySQL數據庫經過用戶和密碼來控制用戶對數據庫的訪問,當咱們新安裝了一個數據庫服務器時,MySQL的權限表設置是很不安全,它默認容許任何人不須要密碼就可訪問數據庫。因此咱們安裝好服務器後第一件須要作的就是設置用戶密碼。

在MySQL中的mysql數據庫的user數據表中存有用戶的賬號信息,在初始狀態下已存在root和一些匿名用戶,且全部用戶都沒有設置密碼。該數據表的這些用戶信息是經過一個mysql_install_db腳本安裝的。該表的主要列有:

  • User,鏈接數據庫的用戶名。

  • Host,容許鏈接到數據庫服務器的主機名,「%」通配符表明全部主機。

  • Password,鏈接密碼,已加密。

  • 其它權限列,以「Y」或「N」標識是否有效。

在這種狀態下的數據庫是極不安全的,咱們可用如下命令輕易地訪問數據庫:

% mysql -h localhost -u root     #經過本地主機,root用戶訪問,不須要密碼驗證
% mysql -h localhost             #經過本地主機,匿名用戶訪問,不須要密碼驗證

設置MySQL用戶賬號密碼的方法有三種:

  • 使用mysqladmin程序:

    % mysqladmin -h localhost -u root password "password"   #設置在本地以root身分登陸的密碼
    % mysqladmin -h remote -u root password "password"      #設置遠程主機以root身分登陸的密碼
    

    在初始設置時,這兩條語句都要運行,以確保數據庫本地訪問和網絡訪問的安全。

  • 經過set password這條SQL語句設置:

    mysql> set password for 'root'@'localhost' = password('password');
    mysql> set password for 'root'@'remote' = password('password');
    
  • 直接修改user權限表:

    mysql> use mysql;
    mysql> update user set password=password('password') where user='root';
    mysql> flush privileges;                            #重載權限表,使修改立刻生效
    

    MySQL使用駐留在內存中的權限表拷貝來進行訪問控制,當使用mysqladmin和set password設置密碼,MySQL會監察到權限表已被修改,它自動重載該表。而用update的方式,MySQL就監察不到變化,需手動用flush privileges命令刷新內存中的權限表,以使它立刻生效。

爲root用戶設置密碼後,若是需以root身份鏈接數據庫,就需驗證密碼。咱們可用如下語句鏈接數據庫:

% mysql -u root -p
Enter password:                         #輸入root的密碼

在user表中,user列爲空的爲匿名用戶。它也是沒有密碼的,咱們需爲它們設置一個密碼,或乾脆把它們刪除。在windows系統上的本地匿名用戶賬號和root用戶有着一樣的權限,這是一個很大的安全漏洞。應該把它刪除或把權限削弱。

4.2. 服務器的啓動和關閉

 

在Linux和windows平臺下MySQL服務器的啓動方式有很大不一樣,這裏將分開介紹:

  • Linux平臺:

    Linux平臺下,每個進程都需由一個用戶來運行,MySQL最好不要以root用戶來運行。咱們可建立一個mysql用戶和mysql組,MySQL服務器程序目錄和數據目錄由這個用戶和組所擁有,其它用戶沒有任何權限。以mysql用戶來運行MySQL服務器。

    % mysqld --user=mysql     #即便以root用戶執行該命令,MySQL數據庫仍是會與mysql用戶ID關聯。
    

    爲了使服務器在系統啓動時自動以mysql用戶運行,需配置my.cnf配置文件 ,把user=mysql包含在[mysqld]段中。

    關閉服務器可用% mysql.server stop或% mysqladmin -u root -p shutdown

  • windows平臺:

    手動方式:直接運行c:\mysqld命令。

    做爲服務方式:運行c:\mysqld-nt --install命令,把mysqld-nt安裝爲windows的服務,此後,每當windows啓動時,它就會自動運行。mysqld-nt是一個支持命名管道的MySQL服務器。運行c:\mysqld-nt --remove可把服務刪除。手動啓動關閉服務的方法是運行c:\net start mysql和c:\net stop mysql命令。

4.3. 鏈接故障恢復

 

當因爲誤刪mysql套接字時(/tmp/mysql.sock),咱們就不能經過套接字鏈接服務器。這時咱們可經過tcp/ip來鏈接服務器,要創建一個tcp/ip鏈接,需用127.0.0.1代替locahost做爲-h參數的值來鏈接服務器。如:

% mysqladmin -h 127.0.0.1 -u root -p shutdown       #關閉服務器再重啓會重建套接字

當咱們由於忘記root用戶密碼而不能鏈接服務器時,重設置密碼的步驟如:

  • 用 % kill -TERM PID關閉服務器,用-TERM信息可以使服務器在關閉前把內存中的數據寫入磁盤。若是服務器沒有響應,咱們可用% kill -9 PID來強制刪除進程,但不建議這樣作。這時內存中的數據不會寫入磁盤,形成數據不完整。若是你是用mysql_safe腳本啓動MySQL服務器的,這個腳本會監控服務器的運行狀況並在它被終止時重啓服務器,因此如需關閉服務器,要先終止該進程,而後再真正終止mysqld進程。

  • 接着用--skip_grant-tables啓動服務器。這時MySQL服務器將不使用權限表對鏈接操做進行驗證。你就可在不提供root密碼的狀況下鏈接上服務器,並得到root的權限。這樣你就可用上面介紹的修改密碼的方法重設root用戶的密碼。注意:鏈接上服務器後,要立刻執行flush privileges命令,使權限表讀入內存並生效,以阻止其餘的鏈接。該語句還從新激活grant語句,在MySQL服務器不使用權限表時,grant語句被禁用。

  • 修改完root用戶密碼後,咱們就可關閉服務器並重啓使全部配置正常運做。

4.5. 日誌文件管理

 

有關MySQL的日誌文件前面章節已簡要討論過了,主要有四種日誌文件,分別是常規查詢日誌、慢查詢日誌、變動查詢日誌和二進制變動日誌。這些日誌文件的建立需在啓動服務器時用選項指定。

Table 4.3. 日誌啓動選項

啓動選項 激活日誌
--log[=file_name] 常規日誌文件
--log-bin[=file_name] 二進制變動日誌文件
--log-bin-index=file_name 二進制變動日誌文件索引文件
--log-update[=file_name] 變動日誌文件
--log-slow-queries[=file_name] 慢查詢日誌文件
--log-isam[=file_name] ISAM/MyISAM日誌文件
--log-long-format 設置慢查詢日誌和變動日誌的格式

BDB和InnoDB數據表的日誌文件會自動建立不用指定選項。但可用如下選項指時日誌文件的存放路徑。

Table 4.4. BDB和InnoDB數據表日誌選項

啓動選項 用途
--bdb-logdir=dir_name 存放BDB日誌文件的位置
--innodb-log_arch_dir=dir_name 存放InnoDB日誌文件的歸檔目錄
--innodb_log_group_home_dir=dir_name 存放InnoDB日誌文件的位置

MySQL日誌文件選項可在mysqld和mysqld_safe腳本中使用,也可在選項文件my.cnf的[mysqld]中使用。推薦在選項文件中使用,由於每次啓動服務器的日誌選項基本上都是一致的。

日誌的刷新可用mysqladmin flush-logs命令或flush logs語句實現。另外,對MySQL服務器發送一條SIGHUP信號也會刷新日誌。錯誤日誌和DBD/InnoDB日誌不能用以上方法刷新。

錯誤日誌記錄MySQL數據庫系統的論斷和出錯信息,由mysqld_safe腳本建立,文件名默認爲hostname.err,也可經過--err-log或選項文件的err-log語句指定另外的名字。若是直接用mysqld程序啓動服務器,錯誤信息會直接輸出到輸出設備,也就是屏幕。但咱們可用重定向方法把錯誤信息輸出到其它地方,如把錯誤信息輸出到/var/log/mysql.err文件中,能夠執行如下語句:

% mysqld > /var/log/mysql.err 2>&1 &

在windows平臺下,MySQL服務器默認把診斷信息寫到數據目錄的mysql.err文件中,而且不容許另外指定錯誤日誌文件名。如在啓動MySQL服務器時給出了--console選項,則MySQL會把診斷信息輸出到控制檯窗口而不建立錯誤日誌。但如MySQL是做爲一個服務運行,則--console選項不起做用。

4.5.1. 日誌失效處理

 

在服務器正常運行中,會產生大量的日誌文件。咱們要對這些日誌文件進行失效管理,以節省磁盤空間和方便查詢。進行日誌失效處理的方式主要有如下幾種:

  • 日誌輪轉。該方法適用於常規查詢日誌和慢查詢日誌這些文件名固定的日誌文件,在日誌輪轉時,應進行日誌刷新操做(mysqladmin flush-logs命令或flush logs語句),以確保緩存在內存中的日誌信息寫入磁盤;

    日誌輪轉的操做過程是這樣的:第一次輪轉時,把log改名爲log.1,而後服務器再建立一個新的log文件,在第二輪轉時,再把log.1改名爲log.2,把log改名爲log.1,而後服務器再建立一個新的log文件。如此循環,建立一系列的日誌文件。當到達日誌輪轉失效位置時,下次輪轉就再也不對它進行改名,直接把最後一個日誌文件覆蓋掉。例如:若是天天進行一第二天志輪轉並想保留最後7天的日誌文件,就須要保留log.1--log.7共七個日誌文件,等下次輪轉時,用log.6覆蓋原來的log.7成新的log.7,原來的log.7就天然失效。下面是一個失效處理的shell腳本,以供參考:

    #!/bin/sh
    # shell script ---  rotate_log.sh
    
    if [ $# -ne 1 ]; then
       echo "Usage: $0 logname" 1>&2
       exit 1
    if
    
    logfile=$1
    
    mv $logfile.6 $logfile.7
    mv $logfile.5 $logfile.6
    mv $logfile.4 $logfile.5
    mv $logfile.3 $logfile.4
    mv $logfile.2 $logfile.3
    mv $logfile.1 $logfile.2
    mv $logfile $logfile.1
    mysqladmin -u flush -pflushpass flush-logs     #執行mysqladmin flush-logs會打開一個日誌文件----從新生成一個新的日誌文件
    

    該腳本以日誌文件名爲參數,執行方法以下:

    % rotate_log.sh /usr/local/mysql/data/log
    

    注意,腳本中的mysqladmin命令是帶有-u和-p參數的,由於咱們進行日誌刷新時需鏈接服務器。爲確保安全,咱們創建一個flush用戶,密碼爲flushpass。該用戶只有日誌刷新的權限(reload權限)。建立該用戶的語句以下:

    GRANT RELOAD ON *.* TO 'flush'@'localhost' IDENTIFIED BY 'fulshpass';
    

    設置好後,咱們就可利用系統的自動處理機制按期運行該腳本以生成輪轉日誌。在Linux系統上的MySQL發行版中帶有一個用來安裝mysql-log-rotate日誌輪轉腳本的logrotate工具,如用RPM安裝,則在/usr/share/mysql目錄,如用二進制方式安裝,則在MySQL安裝目錄的support-files目錄,如用源碼安裝,則在安裝目錄的share/mysql目錄中。

    在windows平臺下,不能在線改名,需停掉服務器,再進行。下面是一個進行日誌改名的批處理文件:

    @echo off
    REM script name : rotate_log.bat
    
    if not "%1" == "" goto ROTATE
    
       @echo Usage: rotate_log logname
       goto DONE
    
    :ROTATE
    set logfile=%1
    erase %logfile%.7
    rename %logfile%.6 %logfile%.7
    rename %logfile%.5 %logfile%.6
    rename %logfile%.4 %logfile%.5
    rename %logfile%.3 %logfile%.4
    rename %logfile%.2 %logfile%.3
    rename %logfile%.1 %logfile%.2
    rename %logfile% %logfile%.1
    :DONE
    

    該腳本的執行方法以下:

    c:\rotate_log c:\mysql\data\log
    
  • 以時間爲依據對日誌進行失效處理。該方法將按期刪除超過給定時間的日誌文件,適用於變動日誌和二進制日誌等文件名用數字編號標識的日誌文件。下面是一個用Perl寫成的處理腳本:

    #!/usr/bin/perl -w
    
    # script name: expire_log.pl
    # Usage: expire_log.pl logfile ...
    
    use strict
    die "Usage: $0 logfile ...\n" if @ARGV == 0;
    my $max_allowed_age = 7;      #max allowed age in days
    foreach my $file (@ARGV)      #chack each argument
    {
       unlink ($file) if -e $file && -M $file >= $max_allowed_age;
    }
    exit(0);
    

    該腳本需提供一個將被輪轉的日誌文件名做爲參數,如:

    % expire_log.pl /usr/local/mysql/data/log.[0-9]*
    
    [Note]  
    在給腳本參數時請當心,如給出*爲參數,則會刪除目錄中全部更新時間大於7天的文件。
  • 鏡像機制。把日誌文件鏡像到全部的從服務器上。要使用鏡像機制,你必須知道主服務器有多少個從服務器,哪些正在運行,並需依次鏈接每個從服務器併發出show slave status語句以肯定它正處理主服務器的哪一個二進制日誌文件(語句輸出列表的Master_Log_File項),只有全部的從服務器都不會用到的日誌文件才能刪除。刪除方法是在主服務器上發出如下語句:

    mysql> PURGE MASTER LOGS TO 'last_log.xx';
    

    上面語句中的last_log.xx是全部從服務器已處理的最小編號日誌文件。

4.6. MySQL服務器的一些優化配置

 
  • 服務器的監聽端口設置

    • TCP/IP端口3306是MySQL服務器默認的網絡監聽端口,如用--skip-networking選項啓動服務器,則不監聽TCP/IP端口。可用--port端口另行指定一個監聽端口。如服務器主機有多個IP,還可用--bind-address選項對服務器在監聽客戶鏈接時使用的IP地址進行設定。

    • 在UNIX系統上,MySQL可在一個UNIX域套接字文件上監聽有無本地客戶在試圖以localhost爲主機名進行鏈接。默認的套接字文件是/tmp/mysql.sock,可用--socket選項指定另一個套接字文件。

    • 在基於NT的Windows平臺上,有-nt的MySQL服務器都支持命名管道。默認的命名管道是MySql,可用--socket選項另行指定。

  • 啓用或禁用LOAD DATA語句的LOCAL能力

    • 可在MySQL服務器編譯時,用configure腳本的--enable-local-infile或--disable-local-infile選項把LOAD DATA語句的LOCAL能力設置爲啓用或禁用;

    • 在MySQL服務器啓動是,能夠用--local-infile或--disable-local-infile選項來啓用或禁用服務器的LOCAL能力(在MySQL 4.0.2以前的版本里,要用--local-infile=0來禁用它)。

    若是在服務器端禁用了LOCAL的能力,則客戶端就不能使用該功能;如服務器啓用了LOCAL的能力,客戶端默認也是禁止使用的,但可用mysql程序的--local-infile選項啓用它。

  • 國際化和本地化,國際化是指軟件可以在世界多個國家地區使用,而本地化則是指可從國際化軟件中選擇一套適合本地區的語言和習慣的設置來使用。在MySQL中的國際化和本地化設置有如下幾方面內容:

    • 時區,若是時區設置不對,則服務器顯示的時間將會和當地時間有衝突。設置方法可經過mysqld_safe腳本的--timezone選項來設置,但最好仍是在選項文件裏設置,如:

      [mysqld_safe]
      timezone=US/Central
      
    • 配置顯示信息的語言,MySQL能用多種語言來顯示診斷信息與出錯信息,默認是英語。查看share/mysql目錄下有幾個以語言名稱做爲目錄名的目錄就可知道有哪些語言可供選擇。可用--language啓動選項來指定語言,如--language=/usr/local/mysql/share/mysql/french。

    • 配置服務器的字符集,MySQL支持多種字符集,可在share/mysql/charsets目錄下查詢支持的字符集,也可用show variables like 'character_sets'來顯示支持的字符集清單。MySQL把latin1做爲默認的字符集。可在編譯時用--with-charset指定另一個字符集爲默認字符集。如要增長另外的字符集支持,可用--with-extra-charasets選項進行添加。如:

      % ./configure --with-extra-charsets=latin1,gb2312,big5
      

      --with-extra-charsets有兩個特殊的選項,一個是all,表明全部可用字符集;一個是complex,表明全部的複雜字符集(包括多字節字符集和有特殊排序規則的字符集)。

      服務器啓動時,使用默認字符集,如需指定另外的字符集,需用--default-character-set選項指明。

      在MySQL 4.1之前,若是在建立好數據表後改變服務器的默認字符集,就需對索引從新排序才能保證索引鍵值可以正確反映出數據表記錄在新字符集下的排列順序。從新排序的操做命令以下:

      % myisamchk --recover --quick --set-character-set=gb2312       #在執行該語句需關閉服務器,適用於MyISAM數據表
      也可用:
      % mysqlcheck --repair --quick                                  #不需關閉服務器,適用於各類數據表
      或者用:
      mysql> REPLACE TABLE ... QUICK;
      

      在客戶端,可用--default-character-set選項指定客戶程序使用的字符集。--character-sets-dir選項可指出字符集文件的安裝目錄。

  • 升級數據表到4.1,支持多字符集數據表。步驟以下:

    1. 用mysqldump程序備份數據庫:

      % mysqldump -p -u root --all-databases --opt > dumpfile.sql
      --all-databases選項的做用是轉儲全部數據庫;
      --opt選項的做用是對轉儲文件進行優化。
      
    2. 關閉服務器,升級MySQL服務器軟件到4.1版。

    3. 用備份文件從新加載數據表:

      % mysql -p -u root < dumpfile.sql
      

    這樣,字符集信息就被分配到每個數據列中,此後,即便服務器改變了默認的字符集,各數據列的字符集也不會改變。當之後修改某個數據列的字符集時,服務器會自動重索引,以反映最新變化。

  • 配置InnoDB表空間。InnoDB表空間在邏輯上是一個鏈接的存儲區域,但其實是由一個或多個磁盤文件組成。這些文件能夠是普通的文件,也能夠是一個未格式化的原始硬盤分區。InnoDB表空間經過一系列的配置選項來設置,其中最重要的有如下兩個:

    爲確保服務器每次啓動時都能調用一樣的選項,InnoDB的選項最好存放到選文件中。下面是一個例子:

    innodb_data_home_dir = 
    innodb_data_file_path=/usr/loca/mysql/data/idbdata1:10M:autoextend:max:100M
    說明:
    InnoDB表空間文件默認存放到了MySQL的數據目錄中,名字叫idbdata1;
    文件長度爲10M;
    可自動擴展,以8M爲步長擴展,若有多個數據文件,只容許最後一個文件可自動擴展;
    規定了最大的可擴展尺寸爲100M。
    
    • innodb_data_home_dir,設置InnoDB表空間各組成文件的父目錄,若是沒有指出,則默認是MySQL的數據目錄。

    • innodb_data_file_path,描述InnoDB主目錄中各有關文件,包括文件名,文件長度和一些選項。各文件以分號分隔,各組成文件長度至少爲10M。

    把選項寫入選項文件後,啓動服務器就可自動建立和初始化InnoDB表空間。

    利用原始磁盤分區做爲InnoDB表空間可建立一個很是大的表空間,不受操做系統單文件最大容量的限制。而且能有效減小磁盤碎片的產生。要使用原始磁盤分區,需做以下配置:

    • 首先,要進行初始化,在選項文件的[mysqld]中配置:

      innodb_data_home_dir=
      innodb_data_file_path=/dev/hda1:10Gnewraw     #初始化/dev/hda1這個10G容量的分區
      

      啓動服務器,服務器會對這個10G的分區進行初始化。

    • 接着,關閉服務器,修改配置文件,把newraw改成raw,如:

      innodb_data_home_dir=
      innodb_data_file_path=/dev/hda1:10Graw
      

    從新啓動服務器,MySQL就會以讀/寫方式使用該表空間了。在windows平臺上配置InnoDB表空間時,windows路徑名中的反斜槓能夠寫成單個的斜線字符(/)。也可寫成兩個反斜槓(\\)。如:

    innodb_data_home_dir=
    innodb_data_file_path=c:/mysql/data/ibdata1:10M;d:/ibdata2:20M
    

    默認狀況下,InnoDB的日誌文件會存儲在MySQL的數據目錄,文件名以ib開頭。一旦完成InnoDB表空間的初始化,就不能改變組成文件的大小,但可經過添加數據文件或設置自動擴展來增長表空間容量。如需經過增長文件的方法擴大表空間的容量,可按如下步驟進行:

    1. 關閉正在運行的MySQL服務器

    2. 若是InnoDB表空間的最後一個組成文件是可自擴展的,就要先把它改變成一個固定長度文件才能把另外一個文件添加到它後面。方法是先計算出該文件的近似大小,從新設置,如:

      innodb_data_file_path=ibdata1:100M:autoextend
      改爲:
      innodb_data_file_path=ibdata1:150M
      
    3. 把新的組成文件添加到文件清單的末尾,該文件能夠是普通文件,也能夠是一個原始硬盤分區。

    4. 重啓服務器。

    還有一種方法從新配置InnoDB表空間,就是先備份,再從新配置,最後從新加載備份。具體步驟以下:

    1. 使用mysqldump備份整個InnoDB數據庫;

    2. 關閉服務器,刪除全部InnoDB表空間、InnoDB日誌文件 及InnoDB數據表的.frm文件;

    3. 從新配置InnoDB表空間;

    4. 配置完成後,用備份文件重載數據,生成新的InnoDB數據表。

4.7. 優化服務器

 

MySQL服務器爲咱們提供了豐富的參數,以調整服務器知足不一樣環境的要求。下面分別討論一下這些參數:

  • 服務器參數變量的設置。MySQL服務器參數可在服務器啓動時設置,在MySQL4.0.3及之後的版本中,有些參數也容許在線設置。在MySQL4.0.2及之後的版本里,能夠把一個變量名視爲一個選項名來設置。如數據表緩衝區的尺寸由服務器參數talbe_cache來設置。若是需把它設置爲128,則能夠在命令行裏增長

    --table_cache=128
    

    也可在選項文件中設置:

    [mysqld]
    table_cache=128       
    

    在命令行選項中'_'可寫'-',變成:

    --table-cache=128     #這種寫法更像一個標準選項
    

    還有一種是使用--set-variable或-O選項,如:

    --set-variable=table_cache=128
    or
    -O table_cache=128
    在選項文件中可寫成:
    [mysqld]
    set-variable=table_cache=128
    

    服務器參數分爲全局級和會話級兩個級別。全局級參數將影響整個服務器,會話級參數則隻影響某給定客戶鏈接上的工做。若是某個變量同時存在於兩個級別,則服務器在客戶創建鏈接時用全局變量的值去初始化相應的會話級參數,一旦客戶鏈接創建起來後,對全局參數所做的修改不會影響到相應的會話級參數當前值。設置全局參數和會話級參數的語句:

    全局級:
    mysql> SET GLOBAL variable = value;
    mysql> SET @@GLOBAL.variable = value;
    會話級:
    mysql> SET SESSION variable = value;
    mysql> SET @@SESSION.variable = value;
    默認不帶級別限定符的SET語句修改的參數屬會話級,如:
    mysql> SET variable = value;
    mysql> SET @@variable = value;
    可用一條SET語句設置多個參數,參數間用逗號分隔,如:
    SET SESSION variable = value1,value2,value3;
    

    SESSION和LOCAL是同義語,可用LOCAL代替SESSION,如:@@LOCAL

    具有SUPER權限才能設置全局參數,新設置值的效力將持續到該參數被再次修改或服務器退出。設置會話級參數不用特殊的權限,新設置值的效力將持續到該值被再次修改或鏈接斷開。顯示參數的語句以下:

    SHOW GLOBAL VARIABLES;
    SHOW GLOBAL VARIABLES LIKE 'TEST';
    SHOW SESSION VARIABLES;
    SHOW SESSION VARIABLES LIKE 'TEST';
    如不帶限定符,則返回會話級參數,如會話級參數不存在則返回全局級參數。
    也可用命令行方式顯示服務器參數變量,如:
    % mysqladmin variables
    
  • 下面介紹一些MySQL服務器通用的參數變量:

    • back_log,當多個客戶同時鏈接服務器時,客戶處理過程需進入一個隊列排隊等待服務器處理。該值定義服務器等待處理隊列長度的最大值,若是站點訪問量大,需加大該值。

    • delayed_queue_size,在實際插入數據表前,來自insert delayed語句的數據行會進入一個隊列等待服務器處理。該值定義該隊列能容納的數據行的最大個數。當隊列滿時,會阻塞後續的語句。加大該值能提升insert delayed語句的執行速度。

    • flush_time,自動存盤間隔。若是系統常常死機或重啓,把這個變量設置爲一個適當的非零值,使MySQL服務器每隔flush_time稱去刷新一次數據表緩衝區,將其中的信息寫入磁盤。這將致使系統性能降低,但可減小數據表被破壞或丟失數據的機率。在命令行上用--flush選項啓動服務器可以使數據表在每次修改後被自動存盤。

    • key_buffer_size,用來容納索引塊的緩衝區的長度。加大該值可加快索引建立和修改操做的速度,該索引緩衝區越大,在內存中找到鍵值的可能性就越大,讀盤次數就越少。MySQL3.23前的版本里,該參數叫key_buffer。3.23版本以後,兩種叫法均可以。

    • max_allowed_packet,服務器與客戶程序之間通訊時使用的緩衝區在最大值。MySQL 4版本以前,該最大值可取16MB,MySQL 4版本之後,該值的最大值是1GB。若是客戶端與服務器需傳送大容量的數據,如BLOB或TEXT值,就要加大該值。客戶端也有一個同名的變量,默認是16MB,該值也要加大。客戶端的啓動命令爲:

      % mysql --set-variable=max_allowed_packet=64M
      
    • max_connections,容許同時打開的鏈接數,若是站點繁忙,需加大該值。

    • table_cache,數據表緩存區的尺寸。加大該值可以使服務器可以同時打開更多的數據表,從而減小文件打開/關閉操做的次數。

    注意:加大max_connections和table_cache參數的值,會使服務器佔用更多的文件描述符。運行多個服務器可繞過該限制。對一些分配給每一個客戶的資源變量,設置時不能過大,由於當鏈接數快速增加時會很快耗盡服務器的資源,形成服務器性能降低。

  • InnoDB處理程序變量:

    • innodb_buffer_pool_size,InnoDB數據庫緩衝池的大小,若是有足夠的內存,可把該值設置得大些以減小讀盤操做。

    • innodb_log_file_size和innodb_log_files_in_group,前者設置日誌文件的長度,後者設置日誌文件的個數。InnoDB日誌文件的總長度是二者的乘積,它的總長度不得超過4GB。

4.8. 運行多個MySQL服務器

 

需運行多個服務器的緣由有不少,好比上面提到的可繞過最大文件描述符的限制,還有是進行版本測試和提供專用服務等。運行多個服務器比運行單個服務器複雜不少,需注意如下問題:

  • 在安裝不一樣版本的程序時,需分開目錄存放程序和數據目錄。若是同一版本的服務器軟件,則程序目錄可同樣,但數據目錄則要不一樣。可用--basedir=dir_name和--datadir=dir_name兩個啓動選項指時這兩個目錄。

  • 要爲不一樣的服務器指定不時的--port=port_name(TCP/IP監聽端口),--socket=file_name(套接字文件名)和--pid-file=file_name(進程ID文件)值。

  • 若是激活了日誌功能,就要爲不一樣的服務器指定不一樣的日誌文件名。

  • 在Windows平臺上,被安裝爲服務的多個MySQL服務器必須有不一樣的服務名。

多服務器環境下選項文件的配置方法:

  • 使用--defaults-file選項指定每一個選項文件,這樣,每一個服務器就不會去讀/etc/my.cnf這些配置文件,而會使用你所指定的配置文件。

  • 可把一些公共的選項放到/etc/my.cnf文件裏,再用--defaults-extra-file選項指出特定服務器的特定選項文件。這樣就不用在全部的配置文件時重複公共的選項。

  • 用mysql_multi腳本啓動服務器,它容許咱們把全部的選項放到同一個選項文件裏。每個服務器對應該文件中的一個選項組。

    下面介紹用mysql_multi腳本啓動多服務器的方法。

    1. 爲每一個服務器編一個編號xxx,對應選項文件的[mysqldxxx]選項組。mysql_multi自己要用到的選項可放到[mysqld_multi]裏。這樣/etc/my.cnf選項配置文件看起來就象下面這樣:

      [mysqld001]
      basedir=/usr/local/mysql/001
      datadir=/usr/local/mysql/001/data
      mysqld=/usr/local/mysql/001/bin/mysqld_safe
      socket=/usr/local/mysql/001/mysql.sock
      port=3306
      local-infile=1
      user=mysqladm
      log=log
      log-update=update-log
      innodb_data_file_path=ibdata1:10M
      
      [mysqld002]
      basedir=/usr/local/mysql/002
      datadir=/usr/local/mysql/002/data
      mysqld=/usr/local/mysql/002/bin/mysqld_safe
      socket=/usr/local/mysql/002/mysql.sock
      port=3307
      local-infile=1
      user=mysqladm
      log=log
      log-update=update-log
      innodb_data_file_path=ibdata1:10M
      
      ...
      
    2. 配置好選項文件後,就可用如下命令啓動服務器:

      % mysqld_multi --no-log start 001,002      
      #啓動001和002兩個服務器,並把啓動信息發送到控制檯,也可用區間的形式給出服務器編號
      

      用如下命令可查看服務器狀態:

      % mysqld_multi --no-log --user=root --password=password report 001
      

      可用如下命令中止MySQL服務器:

      % mysqld_multi --no-log --user=root --password=password stop 001
      
  • 在windows平臺下運行多個MySQL服務器的方式有兩種,一種是運行同一個MySQL程序的兩個實例,一種是運行多個windows服務,下面分別介紹:

    • 第一種狀況需設置兩個選項文件,指定不一樣的數據目錄,如:

      c:\mysql\my.cnf1
      
      [mysqld]
      basedir=c:/mysql
      datedir=c:/mysql/data1
      port=3306
      
      c:\mysql\my.cnf2
      
      [mysqld]
      basedir=c:/mysql
      datadir=c:/mysql/data2
      port=3307
      

      在啓動服務器時,用--defaults-file選項指出選項文件便可。如:

      c:\> mysqld --defaults-file=c:\mysql\my.cnf1
      c:\> mysqld --defaults-file=c:\mysql\my.cnf2
      
    • 在MySQL 4.0.2版本開始,能夠把MySQL安裝爲一個服務,並可指定一個服務名,如:

      c:\> mysql-nt --install service_name
      在MySQL 4.0.3開始,安裝服務還支持--defaults-file=file_name選項
      

      這樣,咱們就可把MySQL安裝爲一系列不一樣的服務,若是不指定service_name,則安裝的服務名默認爲MySql,若是指定service_name,則安裝的服務名爲指定的service_name,並對應選項文件中的[service_name]選項組。以默認服務名運行的服務器還支持一個名爲MySql的命名管道,而明確給出服務名的服務器將只監聽TCP/IP鏈接而不支持命名管道--除非還用socket選項明確指定一個套接字文件。

      移除服務需先用mysqladmin shutdown命令停掉服務器,再執行如下命令:

      c:\> mysql-nt --remove                 #移除默認的服務
      c:\> mysql-nt --remove service_name    #移除指定服務
      

4.9. MySQL服務器鏡像配置

 

經過鏡像機制可把數據從一個地方複製到另外一個地方,並能實現同步兩個或多個地方的數據。MySQL服務器也支持鏡像,大提升數據的安全性和穩定性。下面介紹一下MySQL數據中的鏡像機制:

  • 在鏡像關係中,一個MySQL服務器扮演主服務器角色,另一個或多個服務器扮演從服務器角色,從服務器中的數據和主服務器中的數據徹底同樣。

  • 在鏡像創建以前,主服務器和從服務器必須進行一次徹底同步。同步以後,在主服務器上所作的操做將會在從服務器上再實現,主服務器上的操做不是直接做用於從服務器上的。

  • 負責在主、從服務器上傳輸各類修改動做的媒介是主服務器上的二進制變動日誌,該日誌記錄着主服務器上全部的操做動做。所以,主服務器必須激活二進制日誌功能。

  • 從服務器必須有足夠的權限從主服務器上接收二進制日誌文件。鏡像協調信息記錄從服務器的進展狀況,包括,從服務器正在讀取的二進制變動日誌文件名和它在該文件裏的當前讀寫位置。

  • 每一個主服務器能夠有多個從服務器,但每一個從服務器只能有一個主服務器。但MySQL服務器容許把一個從服務器做爲另外一個從服務器的主服務器,這樣就可建立一個鏡像服務器鏈。

鏡像機制在MySQL中仍是一個新生事物,最先實現於3.23.15版。各版本間的鏡像能力有差別,通常來講,建議你們儘可能使用最新的版本,下面列舉了不一樣版本的MySQL服務器在鏡像機制方面的兼容規則:

  • 3.23.x系統版本的從服務器不能與4.x系統版本的主服務器通訊。

  • 4.0.0版本的從服務器只能與4.0.0版本的主服務器通訊。

  • 4.0.1或更高版本的從服務器既能與3.23.x系統版本的主服務器通訊,也能與4.x系統版本的主服務器通訊。但後一種狀況要求主服務器的版本號等於或大於從服務器的版本號。

通常來講,建議遵循如下原則:

  • 要儘量地讓主服務器和從服務器都使用同一版本系統。

  • 在選定系統後,儘可能使用該系統的最新版本。

創建主從鏡像服務器的步驟:

  • 肯定主從服務器的鏡像ID號,主從服務器的ID號不能相同。在啓動主從服務器時,用--server_id啓動選項給出其ID。

  • 從服務器必須在主服務器上有一個具有足夠的權限的賬戶,從服務器將使用該賬戶去鏈接主服務器並請求主服務器把二進制變動日誌發送給它。可用如下命令建立這個賬戶:

    mysql> GRANT REPLICATION SLAVE ON *.* TO 'slave_user'@'slave_host' IDENTIFIED BY 'slave_pass';
    #REPLICATION權限只MySQL4.0.2後版本,以前的版本請用FILE權限。
    
  • 把主服務器上的數據庫文件拷貝到從服務器上完成最初同步工做。也可用備份後再加載的方法。在MySQL 4.0.0及之後版本里,還可用在主服務器上運行LOAD DATA FROM MASTER語句來創建從服務器。但有約束條件:

    • 數據表要所有是MyISAM表

    • 爲發出這條指令而在鏈接從服務器時使用的賬戶必須有SUPER權限。

    • 從服務器用來鏈接主服務器的賬戶必須具有RELOAD和SUPER權限。注意,這是一個主服務器上的賬戶,而用來發出LOAD DATA FROM MASTER語句的賬戶是一個從服務器上的賬戶。

    • LOAD DATA FROM MASTER語句在執行時需申請一個全局性的讀操做鎖,這個鎖在語句執行期間阻塞主服務器上一切的寫操做。

    不管用哪一種方法同步數據,都要確保在開始製做備份到給主服務器從新配置好二進制日誌功能這段時間,不能在主服務器上發生修改操做。

  • 關閉服務器。

  • 對主服務器的配置進行修改--把它的鏡像ID告訴它並激活其二進制日誌功能。在主服務器要讀取的選項文件內增長如下內容:

    [mysqld]
    server-id=master_server_id
    log-bin=binlog_name
    
  • 從新啓動主服務器,從如今開始,它將把客戶對數據庫的修改操做記錄到二進制變動日誌裏。若是在此以前已經激活了二進制日誌功能,則要在重啓前把二進制變動日誌備份下來,在重啓後再發一條RESET MASTER語句去清除現有的二進制變動日誌。

  • 關閉從服務器。

  • 對從服務器進行配置,使它知道自已的鏡像ID,到哪裏去找主服務器以及如何去鏈接主服務器。配置內容以下:

    [mysqld]
    server-id=slave_server_id
    master-host=master_host
    master-user=slave_user          #在主服務器上爲從服務器創建的賬戶
    msater-password=slave_pass      #在主服務器上爲從服務器創建的賬戶的密碼
    master-connet-retry=30         #設置鏈接重試間隔,默認爲60秒
    master-retry-count=100000       #設置重試次數,默認爲86400次
    注:最後兩個選項在網絡鏈接不可靠時設置
    
  • 從新啓動從服務器。從服務器用兩個信息源來肯定它自已在鏡像工做中的進度位置:一個是數據目錄中的master.info文件,另外一個是啓動選項所給定的配置信息。第一次啓動從服務器時,master.info文件不存在,從服務器會根據選項文件中給出的各類master-xxx選項值去鏈接主服務器。一旦鏈接成功,從服務器會建立一個master.info文件以保存各類鏈接參數和它自已的鏡像工做狀態。若是之後再重啓從服務器,從服務器會優先讀取該文件,而不是選項文件。因此若是你修改了選項文件的內容,想該選項生效就要刪除master.info文件並重啓從服務器。

以上步驟是鏡像全部數據庫的操做過程,若是咱們想把mysql權限數據保留在主服務器上,排除在鏡像機制外的話,可用在選項文件的[mysqld]中加入--binlog-ignore-db=mysql選項,這樣,mysql數據庫上的操做就不會記錄在二進制變動日誌裏。如要排除其它數據庫,只要增長多幾個該選項便可。

經過如下幾個命令可監控和管理主從服務器:

  • SLAVE STOP,SLAVE START用於掛起來恢復從服務器上鏡像,如當備份時,可用該語句讓從服務器暫時中止鏡像活動。

  • SHOW SLAVE STATUS,在從服務器上查看其鏡像協調信息,這些信息能夠用來判斷哪些二進制變動日誌已經再也不使用。

  • PURGE MASTER,在主服務器上對二進制變動日誌進行失效處理。刪除全部從服務器都再也不使用的二進制變動日誌。

  • CHANGE MASTER,在從服務器上修改鏡像參數。如正在讀取主服務器上哪一個二進制變動日誌,正在寫哪一個中繼日誌文件等。

在MySQL4.0.2以後版本中,鏡像機制中的從服務器由兩個內部線程組成:

  • 一個叫「I/O線程」,負責與主服務器通訊,請求主服務器發送二進制變動日誌,並把接收到的數據修改命令寫入某個中繼日誌文件;用SLAVE STOP IO_THREAD或SLAVE START IO_THREAD可掛起或恢復該線程。

  • 另外一個叫「SQL線程」,負責從中繼日誌中讀取數據修改命令並執行。同理,用SLAVE STOP SQL_THREAD或SLAVE START SQL_THREAD可掛起或恢復該線程。

中繼日誌文件默認的文件爲hostname-relay-bin.nnn和hostname-relay-bin.index。可用從服務器的--relay-log和--relay-log-index選項修改。在從服務器中還有一個relay-log.info中繼信息文件,可用--relay-log-info-file啓動選項修改文件名。

Chapter 5. 數據庫安全

 

安全是一個過程,而不是一個方法,它貫穿在咱們使用和維護MySQL數據庫的過程當中。這不單是系統管理員工做,用戶也要有安全的意識,使安全問題獲得有效控制。MySQL服務器的安全問題可分爲內部安全和外部安全兩部份。內部安全問題大都與系統文件有關,咱們需確保MySQL程序文件和數據文件的安全。外部安全是指經過網絡鏈接到服務器的安全問題,應該只容許合法用戶訪問數據庫,在一些狀況下還可用SSL加密信息傳輸通道。下分別介紹內部安全和外部安全的防範措施。

5.1. 保護MySQL安裝程序文件

 
  • 在重設置文件權限時,請先關閉數據庫服務器。

  • 用如下命令把MySQL安裝程序目錄的屬主和所屬組設置爲MySQL管理員賬號的用戶名和用戶組名。

    % chown -R mysql.mysql /usr/local/mysql
    

    另一種方法是把除數據目錄外的全部目錄屬主設置爲root全部,如:

    % chown -R root.mysql /usr/local/mysql
    % chown -R mysql.mysql /usr/local/mysql/data
    
  • 設置安裝目錄及各有關子目錄的權限,容許管理員進行全部操做,只容許其餘人進行讀和執行訪問,設置命令以下:

    #設置mysql目錄
    % chmod 755 /usr/local/mysql
    or
    % chmod u=rwx,go=rx /usr/local/mysql
    #設置mysql/bin目錄
    % chmod 755 /usr/local/mysql/bin
    or
    % chmod u=rwx,go=rx /usr/local/mysql/bin
    #設置mysql/libexec目錄
    % chmod 700 /usr/local/mysql/libexec
    or
    % chmod u=rwx,go-rwx /usr/local/mysql/libexec
    
  • 把數據目錄及目錄中的全部子目錄和文件設置爲只容許MySQL管理員訪問。

    % chmod -R go-rwx /usr/local/mysql/data
    

    若是數據目錄下有選項文件或套接字文件,並一些客戶需訪問這些文件,則可用如下的權限設置,使客戶在沒有讀權限的前提下使用這些文件:

    % chmod go+x /usr/local/mysql/data
    
  • mysql.sock套接字文件通常放以/tmp目錄下,要確保該目錄設置了粘着位,使自戶只能刪除自已建立的文件,不能刪除其餘用戶建立的文件。/etc/my.cnf中公共選項文件,是對全部用戶可讀的,因此不該把一些敏感信息保存在裏面。.my.cnf是用戶專用選項文件,要確保只有該用戶有權訪問。

  • 這樣設置之後,只有MySQL管理員才能啓動服務器。

5.2. 權限表

 

MySQL服務器經過權限表來控制用戶對數據庫的訪問,權限表存放在mysql數據庫裏,由mysql_install_db腳本初始化。這些權限表分別user,db,table_priv,columns_priv和host。下面分別介紹一下這些表的結構和內容:

  • user權限表:記錄容許鏈接到服務器的用戶賬號信息,裏面的權限是全局級的。

  • db權限表:記錄各個賬號在各個數據庫上的操做權限。

  • table_priv權限表:記錄數據表級的操做權限。

  • columns_priv權限表:記錄數據列級的操做權限。

  • host權限表:配合db權限表對給定主機上數據庫級操做權限做更細緻的控制。這個權限表不受GRANT和REVOKE語句的影響。

你們注意到,以上權限沒有限制到數據行級的設置。在MySQL只要實現數據行級控制就要經過編寫程序(使用GET-LOCK()函數)來實現。

MySQL的版本不少,因此權限表的結構在不一樣版本間會有不一樣。若是出現這種狀況,可用mysql_fix_privilege_tables腳原本修正。運行方式以下:

% mysql_fix_privilege_tables rootpassword            #這裏要給出MySQL的root用戶密碼

最好一會兒升級到MySQL 4.0.4版本,由於4.0.2和4.0.3的db表沒有Create_tmp_table_priv和Lock_tables_priv權限。

MySQL的權限表定義了兩部分內容,一個部份定義權限的範圍,即誰(賬戶)能夠從哪裏(客戶端主機)訪問什麼(數據庫、數據表、數據列);另外一部份定義權限,即控制用戶能夠進行的操做。下面是一些經常使用的權限介紹,可直接在GRANT語句中使用。

  • CREATE TEMPORARY TABLES,容許建立臨時表的權限。

  • EXECUTE,容許執行存儲過程的權限,存儲過程在MySQL的當前版本中還沒實現。

  • FILE,容許你經過MySQL服務器去讀寫服務器主機上的文件。但有必定限制,只能訪問對任何用戶可讀的文件,經過服務器寫的文件必須是還沒有存在的,以防止服務器寫的文件覆蓋重要的系統文件。儘管有這些限制,但爲了安全,儘可能不要把該權限授予普通用戶。而且不要以root用戶來運行MySQL服務器,由於root用戶可在系統任何地方建立文件。

  • GRANT OPTION,容許把你自已所擁有的權限再轉授給其餘用戶。

  • LOCK TABLES,能夠使用LOCK TABLES語句來鎖定數據表

  • PROCESS,容許你查看和終止任何客戶線程。SHOW PROCESSLIST語句或mysqladmin processlist命令可查看線程,KILL語句或mysqladmin kill命令可終止線程。在4.0.2版及之後的版本中,PROCESS權限只剩下查看線程的能力,終止線程的能力由SUPER權限控制。

  • RELOAD,容許你進行一些數據庫管理操做,如FLUSH,RESET等。它還容許你執行mysqladmin命令:reload,refresh,flush-hosts,flush-logs,flush-privileges,flush-status,flush-tables和flush-threads。

  • REPLICATION CLIENT,容許查詢鏡像機制中主服務器和從服務器的位置。

  • REPLICATION SLAVE,容許某個客戶鏈接到鏡像機制中的主服務器並請求發送二進制變動日誌。該權限應授予從服務器用來鏈接主服務器的賬號。在4.0.2版這前,從服務器是用FILE權限來鏈接的。

  • SHOW DATABASES,控制用戶執行SHOW DATABASES語句的權限。

  • SUPER,容許終止線程,使用mysqladmin debug命令,使用CHANGE MASTER,PURGE MASTER LOGS以及修改全局級變量的SET語句。SUPER還容許你根據存放在DES密鑰文件裏的密鑰進行DES解密的工做。

user權限表中有一個ssl_type數據列,用來講明鏈接是否使用加密鏈接以及使用哪一種類型的鏈接,它是一個ENUM類型的數據列,可能的取值有:

  • NONE,默認值,表示不需加密鏈接。

  • ANY,表示須要加密鏈接,能夠是任何一種加密鏈接。由GRANT的REQUIRE SSL子句設置。

  • X509,表示須要加密鏈接,並要求客戶提供一份有效的X509證書。由GRANT的REQUIRE X509子句設置。

  • SPECIFIED,表示加密鏈接需知足必定要求,由REQUIRE子句的ISSUER,SUBJECT或CIPHER的值進行設置。只要ssl_type列的值爲SPECIFIED,則MySQL會去檢查ssl_cipher(加密算法)、x509_issuer(證書籤發者)和x509_subject(證書主題)列的值。這幾列的列類型是BLOB類型的。

user權限表裏還有幾列是設置賬戶資源使用狀況的,若是如下數據列中的數全爲零,則表示沒有限制:

  • max_connections,每小時可鏈接服務器的次數。

  • max_questions,每小時可發出查詢命令數。

  • max_updates,每小時能夠發出的數據修改類查詢命令數。

設置權限表應注意的事項:

  • 刪除全部匿名用戶。

  • 查出全部沒有口令用戶,從新設置口令。可用如下命令查詢空口令用戶:

    mysql> SELECT host,user FROM user WHERE password = '';
    
  • 儘可能不要在host中使用通配符。

  • 最好不要用user權限表進行受權,由於該表的權限都是全局級的。

  • 不要把mysql數據庫的權限授予他人,由於該數據庫包含權限表。

  • 使用GRANT OPTION權限時不要濫用。

  • FILE權限可訪問文件系統中的文件,因此受權時也要注意。一個具備FILE權限的用戶執行如下語句就可查看服務器上全體可讀的文件:

    mysql> CREATE TABLE etc_passwd(pwd_entry TEXT);
    mysql> LOAD DATA INFILE '/etc/passwd' INTO TABLE etc_passwd;
    mysql> SELECT * FROM etc_passwd;
    

    若是MySQL服務器數據目錄上的訪問權限設置得很差,就會留下讓具備FILE權限的用戶進入別人數據庫的安全漏洞。因此建議把數據目錄設置成只能由MySQL服務器讀取。下面演示一個利用具備FILE權限的用戶讀取數據目錄中文件權限設置不嚴密的數據庫數據的過程:

    mysql> use test;
    mysql> create table temp(b longblob);
    mysql> show databases                   #顯示數據庫名清單,--skip-show-database可禁止該功能
    mysql> load data infile './db/xxx.frm' into table temp fields escaped by '' lines terminated by '';
    mysql> select * from temp into outfile 'xxx.frm' fields escaped by '' lines terminated by '';
    mysql> delete from temp;
    mysql> load data infile './db/xxx.MYD' into table temp fields escaped by '' lines terminated by '';
    mysql> select * from temp into outfile 'xxx.MYD' fields escaped by '' lines terminated by '';
    mysql> delete from temp;
    mysql> load data infile './db/xxx.MYI' into table temp fields escaped by '' lines terminated by '';
    mysql> select * from temp into outfile 'xxx.MYI' fields escaped by '' lines terminated by '';
    mysql> delete from temp;
    

    這樣,你的數據庫就給人拷貝到本地了。若是服務器是運行在root用戶下,那危害就更大了,由於root可在服務器上作任何的操做。因此儘可能不要用root用戶來運行服務器。

  • 只把PROCESS權限授予可信用戶,該用戶可查詢其餘用戶的線程信息。

  • 不要把RELOAD權限授予無關用戶,由於該權限可發出FLUSH或RESET語句,這些是數據庫管理工具,若是用戶不當使用會使數據庫管理出現問題。

  • ALTER權限也不要授予通常用戶,由於該權限可更改數據表。

GRANT語句對權限表的修改過程:

  • 當你發送一條GRANT語句時,服務器會在user權限表裏建立一個記錄項並把你用戶名、主機名和口令記錄在User、Host和Password列中。若是設置了全局權限,由把該設置記錄在相在的權限列中。

  • 若是在GRANT裏設置了數據庫級權限,你給出的用戶名和主機名就會記錄到db權限表的User和Host列中,數據庫名記錄在Db列中,權限記錄到相關的權限列中。

  • 接着是到數據表和數據列級的權限設置,設置方法和上面的同樣。服務器會把用戶名、主機名、數據庫名以及相應的數據表名和數據列名記錄到數據表中。

刪除用戶權限其實就是把這些權限表中相應的賬號記錄所有刪除便可。

5.3. 創建加密鏈接

 

加密鏈接可提升數據的安全性,但會下降性能。要進行加密鏈接,必須知足如下要求:

  • user權限表裏要有相關的SSL數據列。若是安裝的MySQL服務器是4.0.0版的,user權限表已包含相關的SSL數據列,不然,咱們也可用mysql_fix_privilege_tables腳本升級權限表。

  • 服務器和客戶程序都已經編譯有OpenSSL支持。首先要安裝openssl,在編譯時MySQL服務器時加--with-vio和--with-openssl選項加上openssl支持。可用如下語句查詢服務器是否支持SSL:

    mysql> show variables like 'have_openssl';
    
  • 在啓動服務器時用有關選項指明證書文件和密鑰文件的位置。在創建加密鏈接前,要準備三個文件,一個CA證書,是由可信賴第三方出具的證書,用來驗證客戶端和服務器端提供的證書。CA證書可向商業機構購買,也可自行生成。第二個文件是證書文件,用於在鏈接時向對方證實自已身份的文件。第三個文件是密鑰文件,用來對在加密鏈接上傳輸數據的加密和解密。MySQL服務器端的證書文件和密鑰文件必須首先安裝,在sampdb發行版本的ssl目錄裏有幾個供參考的樣本文件:ca-cert.pem(CA證書),server-cert.pem(服務器證書),server-key.pem(服務器公共密鑰)。把這幾個文件拷貝到服務器的數據目錄中,再在選項文件里加上如下內容:

    [mysqld]
    ssl-ca=/usr/local/mysql/data/ca-cert.pem
    ssl-cert=/usr/local/mysql/data/server-cert.pem
    ssl-key=/usr/local/mysql/data/server-key.pem
    

    重啓服務器,使配置生效。

  • 要想讓某個客戶程序創建加密鏈接,必須在調用這個客戶程序時用有關選項告訴它在哪裏能找到其證書文件和密鑰文件。在sampdb發行版的ssl目錄中提供了client-cert.pem(客戶證書文件),client-key.pem(客戶密鑰文件),CA證書與服務器使用一樣的ca-cert.pem。把他們拷貝到我的目錄下,並在.my.cnf選項文件中指出文件位置,如:

    [mysql]
    ssl-ca=/home/mysql/ca-cert.pem
    ssl-cert=/home/mysql/client-cert.pem
    ssl-key=/home/mysql/client-key.pem
    

    配置完成後,調用mysql程序運行\s或SHOW STATUS LIKE 'SSL%'命令,若是看到SSL:的信息行就說明是加密鏈接了。若是把SSL相關的配置寫進選項文件,則默認是加密鏈接的。也可用mysql程序的--skip-ssl選項取消加密鏈接。若是用命令行方式啓用加密鏈接能夠這樣寫:

    % mysql --ssl-ca=ca-cert.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem
    

可用GRANT語句的REQUIRE SSL選項來強制用戶使用加密鏈接。

使用sampdb發行版的證書能夠創建一個加密鏈接,但因爲該文件已公開,因此安全性很差,咱們能夠在測試成功後自行創建證書或購買商業證書,以提升安全性。如何自行創建SSL證書的文檔在sampdb發行版的ssl/README文件裏有說明。

Chapter 6. 數據庫的備份、維護和修復

 

數據庫在運行中,會由於人爲因素或一些不可抗力因素形成數據損壞。因此爲了保護數據的安全和最小停機時間,咱們需制定詳細的備份/恢復計劃,並按期對計劃的有效性進行測試。本章結合MySQL服務器的運行機制和所提供的工具,介紹如何進行數據庫的備份、維護和修復。

如下是幾點防範的措施:

  • 制定一份數據庫備份/恢復計劃,並對計劃進行仔細測試。

  • 啓動數據庫服務器的二進制變動日誌,該功能的系統開銷很小(約爲1%),咱們沒有理由不這樣作。

  • 按期檢查數據表,防範於未燃。

  • 按期對備份文件進行備份,以防備份文件失效。

  • 把MySQL的數據目錄和備份文件分別放到兩個不一樣的驅動器中,以平衡磁盤I/O和增長數據的安全。

6.1. 檢查/修復數據表

 

對數據表進行維護最好經過發出CHECK TABLE(檢查數據表)或REPAIRE TABLE(修復數據表)命令來作,這樣MySQL服務器自動進行表鎖定以協調數據表中數據的讀寫一致性問題。也可用myisamchk工具來作數據表的維護,但它直接訪問有關的數據表文件,不經過服務器,因此需人爲地協調數據表數據的讀寫一致性問題。使用myisamchk檢查數據表的具體操做步驟以下:

  • 以mysql客戶端程序鏈接服務器,併發出LOCK TABLE命令,以只讀方式鎖住數據表。

    % mysql
    mysql> use db
    mysql> LOCK TABLE table_name READ;     #以只讀方式鎖定表
    mysql> FLUSH TABLE table_name;        #關閉數據表文件,並把內存中的信息寫入磁盤
    
  • 保持上面的狀態不退出,另開一個shell窗口,用如下命令維護(檢查)數據表。

    % myisamchk table_name
    
    [Note]  
    若是不保持上面狀態,退出mysql會話,則表鎖定會自動取消。
  • 維護完成,切換回mysql狀態的shell窗口,發出如下命令解除表鎖定。

    mysql> UNLOCK TABLES;
    

使用myisamchk修復數據表的具體操做步驟以下:

  • 進行修復操做需以讀/寫方式鎖定數據表,命令以下:

    % mysql
    mysql> use db
    mysql> LOCK TABLE table_name WRITE;     #以讀/寫方式鎖定數據表
    mysql> FLUSH TABLE table_name;
    
  • 保持mysql客戶端鏈接狀態,切換到第二個shell窗口,運行修復命令:

    % myisamchk --recover table_name
    
    [Note]  
    運行修復命令前最好先備份一下數據文件。
  • 修復完成後,切換回mysql客戶端鏈接窗口,運行如下命令解除數據表鎖定:

    mysql> FLUSH TABLE table_name;     #使服務器覺察新產生的索引文件
    mysql> UNLOCK TABLE;
    

還可用如下命令鎖定全部表,鎖定後,全部用戶就只能讀不能寫數據,這樣就可以使咱們能安全地拷貝數據文件。

mysql> FLUSH TABLES WITH READ LOCK;
下面是解除鎖語句:
mysql> UNLOCK TABLES;

6.2. 備份數據庫

 

按期的備份可以使咱們數據庫崩潰形成的損失大大下降。在MySQL中進行數據備份的方法有兩種,一種是使用mysqldump程序,一種是使用mysqlhotcopy、cp、tar或cpio等打包程序直接拷貝數據庫文件。mysqldump程序備份數據庫較慢,但它生成的文本文件便於移植。使用mysqlhotcopy等程序備份速度快,由於它直接對系統文件進行操做,需人爲協調數據庫數據的備份先後一致性。

  • 使用mysqldump備份數據庫其實就是把數據庫轉儲成一系列CREATE TABLE和INSERT語句,經過這些語句咱們就可從新生成數據庫。使用mysqldump的方法以下:

    % mysqldump --opt testdb | gzip > /data/backup/testdb.bak
    #--opt選項會對轉儲過程進行優化,生成的備份文件會小一點,後的管道操做會進行數據壓縮
    % mysqldump --opt testdb mytable1,mytable2 | gzip > /data/backup/testdb_mytable.bak
    #可在數據庫後接數據表名,只導出指定的數據表,多個數據表可用逗號分隔
    
    [Note]  
    --opt選項還可激活--add-drop-table選項,它將會在備份文件的每條CREATE TABLE前加上一條DROP TABLE IF EXISTS語句。這可方便進行數據表的更新,而不會發生「數據表已存在」的錯誤。

    用mysqldump命令還可直接把數據庫轉移到另一臺服務器上,不用生成備份文件。重複執行可按期更新遠程數據庫。

    % mysqladmin -h remote_host create testdb
    % mysqldump --opt testdb | mysql -h remote_host testdb
    另外還可經過ssh遠程調用服務器上的程序,如:
    % ssh remote_host mysqladmin create testdb
    % mysqldump --opt testdb | ssh remote_host mysql testdb
    
  • 經過直接拷貝系統文件的方式備份數據庫,在備份時,要確保沒有人對數據庫進行修改操做。要作到這點,最好關閉服務器。若是不能關閉的,要以只讀方試鎖定有關數據表。下面是一些示例:

    % cp -r db /backup/db                 #備份db數據庫到/backup/db目錄
    % cp table_name.* /backup/db          #只備份table_name數據表
    % scp -r db remotehot:/usr/local/mysql/data      #用scp把數據庫直接拷貝到遠程服務器
    
    [Note]  
    在把數據庫直接拷貝到遠程主機時,應注意兩臺機器必須有一樣的硬件結構,或者將拷貝的數據表所有是可移植數據表類型。
  • 使用mysqlhotcopy工具,它是一個Perl DBI腳本,可在不關閉服務器的狀況下備份數據庫,它主要的優勢是:

    • 它直接拷貝文件,因此它比mysqldump快。

    • 可自動完成數據鎖定工做,備份時不用關閉服務器。

    • 能刷新日誌,使備份文件和日誌文件的檢查點能保持同步。

    下面是該工具的使用示例:

    % mysqlhotcopy db  /bakcup/                 #把db數據庫備份到backup/db目錄裏,會自動建立一個db目錄
    
  • 使用BACKUP TABLE語句進行備份,該語句最先出如今MySQL 3.23.25版本中,僅適用於MyISAM數據表。用法以下:

    mysql> BACKUP TABLE mytable TO '/backup/db';         #把mytable數據表備份到/backup/db目錄下
    

    爲了執行該語句,你必須擁有那些表的FILE權限和SELECT權限,備份目錄還必須是服務器可寫的。該語句執行時,會先把內存中的數據寫入磁盤,再把各個數據表的.frm(表結構定義文件)、.MYD(數據)文件從數據目錄拷貝到備份目錄。它不拷貝.MYI(索引)文件,由於它能用另外兩個文件重建。BACKUP TABLE語句備份時,依次鎖定數據表,當同時備份多個數據表時,數據表可能會被修改,因此備份0完成時,備份文件中的數據和現時數據表中的數據可能會有差別,爲了消除該差別,咱們可用只讀方式鎖定數據表,在備份完成後再解鎖。如:

    mysql> LOCK TABLES tb1 READ,tb2 READ;
    mysql> BACKUP TABLE tb1,tb2 TO 'backup/db';
    mysql> UNLOCK TABLES;
    

    使用BACKUP TABLE語句備份的數據表可用RESTORE TABLE從新加載到服務器。

  • InnoDB和BDB數據庫也可用mysqldump和直接拷貝法進行備份。使用直接拷貝法時應注意需把組成InnoDB和BDB數據庫的全部文件都拷貝下來,如InnoDB的.frm文件、日誌文件和表空間配置文件;BDB的數據文件、日誌文件等。

  • 使用鏡像機制進行備份,咱們可用SLAVE STOP語句掛起從服務器的鏡像,在從服務器上經過直接拷貝法或其它工具製做備份。備份完成,用SLAVE START從新啓動鏡像,從服務器從新與主服務器同步,接收備份時主服務器所作的修改。

在MySQL中沒有爲數據庫重命名的命令,但咱們可用mysqldump轉儲數據庫,再建立一個新的空數據庫,把轉儲文件加載到該新數據庫,這樣就完成數據庫重命名的工做。如:

% mysqldump old_db >db.sql          #轉儲db數據庫數據
% mysqladmin create new_db          #新建一個空的數據庫
% mysql new_db < db.sql             #把db數據庫的數據加載到新的數據庫中
% mysqladmin drop old_db            #刪除舊的數據庫

一個更簡單的重命名數據庫的方法是直接修改數據庫目錄名,但該方法不適用於InnoDB和BDB數據庫。注意,在改名後,需在權限表中更新相關數據表信息,需執行如下語句:

mysql> UPDATE db SET db='new_db' WHERE db='old_db';
mysql> UPDATE tables_priv SET db='new_db' WHERE db='old_db';
mysql> UPDATE columns_priv SET db='new_db' WHERE db='old_db';
mysql> UPDATE host SET db='new_db' WHERE db='old_db';

6.3. 使用備份恢復數據

 

恢復過程包括兩個信息源---備份文件和二進制日誌,備份文件可以使用數據恢復到執行備份時的狀態,而二進制日誌可恢復到發生故障時的狀態。下面分別介紹如何利用這兩個文件恢復一個數據庫或恢復單個數據表。

恢復整個數據庫的步驟:

  1. 把需恢復的數據庫的整個目錄的內容拷貝到其它地方,以備用。

  2. 使用最近的備份文件重載數據庫。若是使用mysqldump生成的備份,則可以使用它們做爲mysql的輸入重載;若是是經過拷貝數據庫目錄來備份的,則要關閉數據庫服務器,再把備份從新拷貝到數據目錄,再重啓數據庫服務器。

  3. 經過二進制日誌重作事務,恢復到出錯點的數據。具體操做是這樣的,用mysqlbinlog把日誌轉換成ASCII格式,再把它做爲mysql的輸入,並指定--one-database選項,以便mysql只執行你指定的數據庫恢復。如:

    % ls -t -r -l binlog.[0-9]* | xargs mysqlbinlog | mysql --one-database db_name
    

    但上面命令只適合全部日誌文件名具備相同長度的狀況。不然需用下面的Perl代碼來處理:

    #!/usr/bin/perl -w
    # sort_num.pl
    
    use strict;
    
    my @files = <>;             #read all input file
    @files = sort { my $anum = $1 if $a =~/\.(\d+)$/;         #sort them by numeric extension
                    my $bnum = $1 if $b =~/\.(\d+)$/;
                    $anum <=> $bnum;
                  } @files;
    print @files;              #print them
    exit(0);
    
    以下使用該腳本:
    % ls -l binlog.[0-9]* | sort_num.pl | xargs mysqlbinlog | mysql --one-database db_name
    

    上面討論的是需全部日誌文件的狀況,但多數狀況下咱們只需備份後生成的幾個日誌文件,這時,可用如下命令來重作。

    % mysqlbinlog binlog.1234 | mysql --one-database db_name
    % mysqlbinlog binlog.1235 | mysql --one_database db_name
    ...
    

    若是咱們需恢復因執行DROP DATABASE,DROP TABLE或DELETE語句而損壞的數據庫,就需在日誌文件中刪除該語句,不然重作後結果仍是同樣。因此需把日誌轉換成ASCII格式並保存起來,再用編輯器打開該文件,刪除這些語句後再重作。

    [Note]  
    若是使用文本變動日誌,則不需使用mysqlbinlog程序,由於該日誌文件自己就是ASCII格式。

恢復使用BACKUP TABLE命令備份的數據表可用RESTORE TABLE語句:

備份語句:
mysql> BACKUP TABLE table_name1,table_name2 TO '/backup/table_backup';
恢復語句:
mysql> RESTORE TABLE table_name1,table_name2 FROM '/backup/table_backup';

恢復有外鍵的數據表,可用SET FOREIGN_KEY_CHECK = 0;語句先關閉鍵字檢查,導入表後再重啓它,賦值爲1表示檢查有效。

恢復InnoDB表空間,當服務器重啓時,InnoDB處理程序會執行自動恢復工做,經過選項文件[mysqld]段中的set-variable=innodb_force_recovery=level設置自動恢復的級別,推薦典型的啓動值爲4。若是需從備份文件恢復,則和上面介紹的方法同樣。BDB數據表的恢復也同樣,啓動服務器時它會進行自動恢復。

Chapter 7. MySQL程序介紹

 

安裝完MySQL後,在MySQL的安裝目錄下會生成不少有用的程序,下面對這些程序進行一一介紹。

  • libmysqld----嵌入式MySQL服務器,它不能獨立運行,它是一個函數庫,可嵌入到其它程序中,使程序具備MySQL服務器的功能。

  • myisamchk和isamchk----檢查和修復數據表、分析鍵值的分佈狀況、禁止或啓用數據表索引的工具。

  • myisampack和pack_isam----壓縮數據表並生成只讀數據表。

  • mysql----最經常使用的一個與服務器交互的命令行客戶端程序。

  • mysqlaccess----一個用來測試數據庫訪問權限的腳本。

  • mysqladmin----一個用來執行各類系統維護和管理工做的工具。

  • mysqlbinlog----一個以ASCII格式顯示二進制變動日誌內容的工具。

  • mysqlbug----一個用來生成程序漏洞報告的腳本。

  • mysql_config----當準備編譯基於MySQL的程序時,能夠利用這個工具程序來肯定該程序的編譯選項和標誌。

  • mysqld----MySQL服務器程序,MySQL數據的核心。

  • mysqld_multi----一個用來同時啓動和關閉多個MySQL服務器的腳本。

  • mysql_safe----一個用來啓動和監控MySQL服務器的腳本。

  • mysqldump----一個用來導出數據表內容的工具。

  • mysqlhotcopy----數據庫備份工具。

  • mysqlimport----一個對數據表批量加載數據的工具。

  • mysql_install_db----一個初始化系統權限表和數據目錄的腳本。

  • mysql.server----一個用來啓動和關閉MySQL服務器的腳本。

  • mysqlshow----一個用來顯示數據庫中數據表的工具。

Chapter 8. MySQL How-To

 

8.1. 鏈接數據庫服務器

 

$ ./mysql -h host_name -u user_name -p

  • -h host_name(--host=host_name),鏈接的數據庫主機名,若是在本地主機上則可省略。

  • -u user_name(--user=user_name),數據庫用戶名,在unix系統上,若是系統的登陸名與數據用戶名同樣,則可省略。在windows系統中,可經過設置環境變量USER來給出數據庫用戶名,如set USER=username。

  • -p(--password),提供數據庫用戶密碼,有該選項mysql就會提示你輸入密碼。輸入的密碼以星號顯示,以確保安全。也可直接在-p後寫上密碼(-p和密碼間不能有空格),但這不安全,不推薦。

鏈接成功後,mysql數據庫服務器會顯示一些歡迎信息。接着就可用mysql>use database_name命令打開指定的數據庫。

[Note]  
$ ./mysql -h host_name -u user_name -p database_name命令可直接打開指定數據庫。

8.2. 更新用戶密碼

 

mysql>update user set password=passowrd('your passowrd') where host='%';

刷新權限設置:mysql>flush privileges;

8.3. MySQL讀取配置文件的順序

 

my.cnf是MySQL數據庫的配置文件,它存在多個地方,在/etc目錄,數據目錄和用戶主目錄都有。放在不一樣位置,裏面的選項有不一樣的做用範圍,下面是MySQL讀取配置文件的順序和做用。

mysql 讀取配置文件的順序:
/etc/my.cnf              Global options.
DATADIR/my.cnf           Server-specific options.
defaults-extra-file      The file specified with the --defaults-extra-file option.
~/.my.cnf                User-specific options.

8.4. 重設置MySQL管理員密碼的方法

 

有時咱們會由於設置緣由或時間長了忘記了數據庫管理員的密碼,使得咱們被關在MySQL服務器外。MySQL服務器提供了一種方法可以使咱們在服務器上重設密碼。在windows和linux/unix平臺上操做稍有不一樣,下面分別介紹:

  • Linux/Unix平臺下:

    1. 用 % kill -TERM PID關閉服務器,用-TERM信息可以使服務器在關閉前把內存中的數據寫入磁盤。若是服務器沒有響應,咱們可用% kill -9 PID來強制刪除進程,但不建議這樣作。這時內存中的數據不會寫入磁盤,形成數據不完整。若是你是用mysql_safe腳本啓動MySQL服務器的,這個腳本會監控服務器的運行狀況並在它被終止時重啓服務器,因此如需關閉服務器,要先終止該進程,而後再真正終止mysqld進程。

    2. 使用--skip-grant-tables參數啓動MySQL Server,這時MySQL服務器將不使用權限表對鏈接操做進行驗證。你就可在不提供root密碼的狀況下鏈接上服務器,並得到root的權限。

      % mysqld_safe --skip-grant-tables & 
      
    3. 用如下命令登陸服務器,並重設密碼:

       % mysql -u root         #不用密碼就可鏈接到服務器
      mysql> use mysql
      mysql> set password for 'root'@'localhost' = password('password');
      
      [Note]  
      修改MySQL服務器賬戶密碼有三種方式,你可參考本筆記中數據庫平常管理一章中的相關內容。在這種環境下,使用mysaladmin修改密碼好象不行,仍是提示要輸入密碼。
    4. 關閉服務器,再用正常方式啓動服務器。

  • windows平臺下:

    1. 用管理員賬號登陸服務器,關閉MySQL數據庫服務器。

    2. 使用--skip-grant-tables參數啓動服務器:

      c:\mysql\bin>mysqld-nt --skip-grant-tables 
      
    3. 從新打開一個console窗口,用mysql命令登陸服務器設置root的新密碼:

      c:\mysql\bin>mysql
      mysql> use mysql
      mysql> set password for 'root'@'localhost' = password('password');
      
    4. 關閉服務器,再用正常方式啓動服務器。

8.5. NULL值

 

NULL是空值,表明什麼也沒有。它不能與值進行比較操做和算術操做,也不能和NULL進行比較,由於兩個空值比較是沒有意義的。咱們可用「is NULL」 或 「is not NULL」來判斷是不空值。如:

mysql> select * from test where mytest is NULL;
mysql> select * from test where mytest is not NULL;

在MySQL3.23之後的版本有一個新的比較操做符「<=>」,它可對NULL值進行相等比較。如:

mysql> select * from test where mytest <=> UNLL;
mysql> select * from test where not (mytest <=>);

若是查詢後排序中的數據中包含NULL,則從MySQL4.0.2開始,有NULL值的數據行老是出如今查詢結果的開頭,即便設置的desc參數。4.0.2之前版本,若是設置了asc,則出在查詢結果的開頭,若是設置了desc,則出如今查詢結果的結尾。

8.6. 使用SQL變量

 

MySQL3.23.6之後的版本容許經過查詢結果來設置變量,設置好的變量可在之後使用。變量用@name定義,賦值方式用@name:=value。下面是一個在查詢語句中進行賦值和使用變量的例子:

mysql> select @name:=id from test where mytest="test";
mysql> select * from test where mytest=@name

8.7. 改變默認提示符

 

用mysql登陸進數據庫後,MySQL數據的默認提示符是「mysql」,咱們可設置它根據用戶打開的數據庫名而變化,如:

mysql>prompt \d>\_
none>use test
test>use mysql
mysql>

prompt爲設置命令,\d表明當前數據庫,\_表明一個空格。

8.8. 非優化的全數據表DELETE操做

 

爲了清空數據表,又需知道刪除的行數和保持AUTO_INCREMENT序列的值,需用如下的刪除語句:

# delete from table_name where 1;

8.9. MySQL事務處理示例

 

MYSQL高級特性 -- 事務處理下面以兩個銀行帳戶之間的轉帳爲例子進行演示。要使用MySQL中的事務處理,首先須要建立使用事務表類型(如BDB = Berkeley DB或InnoDB)的表。

CREATE TABLE account (
account_id BIGINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
balance DOUBLE
) TYPE = InnoDB;


要在事務表上使用事務處理,必需要首先關閉自動提交:

SET AUTOCOMMIT = 0;

事務處理以BEGIN命令開始:

BEGIN;

如今mysql客戶處在於服務器相關的事物上下文中。任何對事務表所作的改變在提交以前不會成爲永久性的改變。

UPDATE ACCOUNT SET balance = 50.25 WHERE account_id = 1;
UPDATE ACCOUNT SET balance = 100.25 WHERE account_id = 2;

在作出全部的改變以後,使用COMMIT命令完成事務處理:

COMMIT;

固然,事務處理的真正優勢是在執行第二條語句發生錯誤時體現出來的,若在提交前終止整個事務,能夠進行回滾操做:

ROLLBACK;

下面是另外一個例子,經過MYSQL直接進行數學運算:

SELECT @first := balance FROM account WHERE account_id = 1;
SELECT @second := balance FROM account WHERE account_id = 2;
UPDATE account SET balance = @first - 25.00 WHERE account_id = 1;
UPDATE account SET balance = @second + 25.00 WHERE account_id = 2;

除了COMMIT命令外,下列命令也會自動結束當前事務:

ALTER TABLE
BEGIN
CREATE INDEX
DROP DATABASE
DROP TABLE
LOCK TABLES
RENAME TABLE
TRUNCATE
UNLOCK TABLES
相關文章
相關標籤/搜索