MySQL
MySQL Workbench http://dev.mysql.com/downloads/
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.13</version>
</dependency>
★カラム型とJDBCアクセスの対照表
★コマンド
CentOSの場合
yum install -y mysql mysql-server
/etc/init.d/mysqld start
Ubuntuの場合
sudo apt-get install mysql-server
mysql --version
mysql -p
mysql -u root -p
mysql -u root -pxxx
mysql -h xxx.xxx.xxx.xxx -u root -pxxx
exit / quit
★セキュリティ設定
Step1:パスワード設定
方法1
mysqladmin -u root password xxx パスワード変更(未設定の場合)
mysqladmin -u root -pxxx password yyy パスワード変更
方法2
mysql -u root -pxxx
select user, host, password from mysql.user;
use mysql
set password for root@localhost=password('xxx');
あるいは
update user set password=password('xxx') where user='root@localhost';
Step2:空のユーザを削除
delete from mysql.user where user='';
★DBのバックアップ
Export:
mysqldump -u root -pxxx DB名 > /home/bak/TEST20120101.dump.sql
mysqldump -u root -pxxx DB名 Table名 > /home/bak/TEST20120101.dump.sql
★データ型
数値 int, double
文字列 char, varchar, text
日付 date, datetime
その他 enum
id int not null auto_increment primary key,
name varchar(255),
email varchar(255) unique,
password char(32),
score double,
sex enum('male', 'female') default 'male',
memo text,
created datetime,
key score (score)
★サンプル
mydb.sql
drop database if exists mydb;
create database mydb;
use mydb;
drop table if exists test;
CREATE TABLE test (
id INT(3) AUTO_INCREMENT NOT NULL PRIMARY KEY,
name CHAR(10) NOT NULL,
address VARCHAR(50) DEFAULT 'Tokyo',
birthday DATE
);
INSERT INTO test (name,address,birthday) VALUES
('Andy','Tokyo','1980-01-01'),
('Andy','Tokyo','1980-01-01'),
('Andy','Tokyo','1980-01-01');
★データの出力・入力
出力
SELECT * FROM テーブル名 INTO OUTFILE '/tmp/data.txt'
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"';
入力
LOAD DATA LOCAL INFILE '/tmp/data.txt' INTO TABLE テーブル名
FIELDS TERMINATED BY ',' IGNORE 1 LINES;
LOAD DATA INFILE '/tmp/data.txt' INTO TABLE テーブル名
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\n';
※デフォルトはtabで区切り、nullは\n
ファイル内容
1,Tom,Osaka,1981-10-09
2,Mike,Fukuoka,1982-02-23
主キーはauto_incrementする場合
,Tom,Osaka,1981-10-09
,Mike,Fukuoka,1982-02-23
★エンジンについて
show engines;
show table status;
show innodb status;
エンジンタイプ
・MyISAM
特徴:全文検索(FullTextーIndex)
得意:COUNT() 、INSERT
・InnoDB
特徴:より多いメモリ・ディスクが必要、トランザクションと外部キーがOK、ビッグデータに向け
得意:主キー検索、UPDATE
★便利なSQL
・年齢の計算
SELECT DATE_FORMAT(FROM_DAYS(TO_DAYS(now()) - TO_DAYS(@birthday)), '%Y') + 0;
・時間差の計算
SELECT UNIX_TIMESTAMP(@datetime1) - UNIX_TIMESTAMP(@datetime2);
単位:秒
引数:datatime型で‘yyyy-mm-dd hh:mm:ss’
・重複回数=Nのデータを検索
SELECT xxx FROM table GROUP BY xxx HAVING COUNT(*) = N;
・データベース容量の確認
SELECT
table_schema AS 'DB Name',
Round( Sum( data_length + index_length ) / 1024 / 1024, 3 ) AS 'DB Size (MB)',
Round( Sum( data_free ) / 1024 / 1024, 3 ) AS 'Free Space (MB)'
FROM information_schema.tables
GROUP BY table_schema ;
★重要なログ
※/etc/my.cnfに設定
Error Log
log_error=/var/log/mysql/mysqld.log
General Query Log
general_log=ON
general_log_file=/var/log/mysql/general.log
Slow Query Log (> long_query_time)
slow_query_log=ON
slow_query_log_file=/var/log/mysql/mysql-slowquery.log
★エラーの解決方法
Error Code: 1093
You can't specify target table 'xxx' for update in FROM clause
INSERT INTO xxx ( type, code ) VALUES (
'A', (
SELECT IFNULL( MAX( code ) + 1, 10001 )
FROM xxx WHERE type='A' )
);
解決方法:サブクエリの場合、tempテーブルを利用
INSERT INTO xxx ( type, code ) VALUES (
'A', (
SELECT IFNULL( max_code + 1, 10001 )
FROM ( SELECT MAX( code ) max_code FROM xxx WHERE type='A' ) temp )
);
Error Code: 1148
The used command is not allowed with this MySQL version
解決方法:
1:/etc/mysql/my.cnfを編集
[mysql]
local-infile = 1
[client]
loose-local-infile = 1
2:再起動
sudo service mysql restart
Error Code: 1175
You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
解決方法:
SET SQL_SAFE_UPDATES = 0;
UPDATE xxx SET ....
Warning: mysqldump: unknown variable 'loose-local-infile=1'
解決方法:
mysqldump --no-defaults -u root -p1234 your_db your_table > /path/to/dump.sql
★SQLの実行時間のみを調べる
cat test.sql | mysql -vvv -u<xxx> -p<xxx> -h <endpoint> <DB> | tail -n 3 | head -n 1
echo "SELECT..." | mysql -vvv -u<xxx> -p<xxx> -h <endpoint> <DB> | tail -n 3 | head -n 1
mysql -vvv -u<xxx> -p<xxx> -h <endpoint> <DB> < ./test.sql | tail -n 3 | head -n 1
★データクリア
mysql -Nse 'show tables' -u<xxx> -p<xxx> -h <endpoint> <DB> | while read table; do mysql -e "truncate table $table" -u<xxx> -p<xxx> -h <endpoint> <DB>; done
mysqldump -u root -pxxx -d -add-drop-table -default-character-set=utf8 DB名 >/home/bak/schema.sql
mysqldump -u root -pxxx -t -add-drop-table -default-character-set=utf8 DB名 >/home/bak/data.sql
オプション:--no-data, --skip-set-charsetなど
Import:
mysql -u root -pxxx DB名 < /home/bak/TEST20120101.dump.sql
あるいは
use DB名
source /home/bak/TEST20120101.dump.sql
ダンプファイル内の件数確認
cat data.dump | grep "INSERT INTO" | sed -e 's/),(/\n/g' | wc -l
ls *.dump | while read file; do cat $file | grep "INSERT INTO" | sed -e 's/),(/\n/g' | wc -l; done
★基本操作
show databases;
use DB名;
show tables; または show tables from database_name;
selet * from テーブル名;
show index from テーブル名; = show keys from テーブル名;
create database DB名;
drop database DB名;
create table テーブル名(...)
describe テーブル名; = desc テーブル名;
drop table テーブル名;
delete table テーブル名;
TRUNCATE TABLE テーブル名;
show status;
show status like "Connections";
show status like "Uptime";
show status like "Slow_queries";
show status like 'Handler_read%'; インデックス状況
SELECT SYSDATE(), SLEEP(2), SYSDATE();
select * from test \G 縦表示
select * from test limit 3, 2;
select * from test order by rand() limit 1;
SELECT * FROM table LIMIT 取得件数 OFFSET 開始位置
SELECT * FROM table LIMIT 開始位置, 取得件数
show columns from table_name from database_name;
または show columns from database_name.table_name;
show grants for user_name;
show privileges;
show logs;
show warnings; -- 最後に実行されたSQLが対象
show errors; -- 最後に実行されたSQLが対象
-- ユーザーを設定
grant select on DB名.* to 'ユーザ名'@'ホスト名' identified by 'パスワード';
-- すべてホスト
grant select,insert,update,delete on *.* to 'andy'@'%' identified by 'xxx';
grant all on mydb.* to 'andy'@'localhost' identified by 'xxx';
-- パスワードなし
grant select,insert,update,delete on mydb.* to 'andy'@'localhost' identified by '';
-- AWS RDS
grant all on `%`.* to 'ユーザ名'@'%' identified by 'パスワード';
-- MySQL
grant all on *.* to 'ユーザ名'@'%' identified by 'パスワード';
SELECT @@autocommit;
SET AUTOCOMMIT=0;
★DB作成サンプル
CREATE DATABASE xxx DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
CREATE USER 'xxx'@'localhost' IDENTIFIED BY 'xxx';
CREATE USER 'xxx'@'%' IDENTIFIED BY 'xxx';
GRANT ALTER, CREATE, DELETE, DROP, INDEX, INSERT, SELECT, UPDATE ON xxx.* TO 'xxx'@'localhost';
GRANT ALTER, CREATE, DELETE, DROP, INDEX, INSERT, SELECT, UPDATE ON xxx.* TO 'xxx'@'%';
★テーブル変更操作
テーブル名の変更
ALTER TABLE 旧テーブル名 RENAME 新テーブル名;
カラムの名前
ALTER TABLE テーブル名 CHANGE 旧カラム名 新カラム名 varchar(200);
alter table test add xxx varchar(255) after name;
alter table test drop xxx;
alter table test add index xxx (name);
alter table test drop index xxx;
★文字コード
CREATE DATABASE DB名 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
ALTER DATABASE DB名 DEFAULT CHARACTER SET 'utf8';
CREATE TABLE テーブル名(...)ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE テーブル名 CHARACTER SET 'utf8';
show variables like 'char%';
set character_set_database =utf8;
★実行されたSQL文のログ
set global general_log=1;
show variables like 'general_log%';
★Query cacheのクリア
show status like 'Qcache%';
reset query cache;
| Qcache_free_blocks
| Qcache_free_memory
| Qcache_hits
| Qcache_inserts
| Qcache_lowmem_prunes メモリ不足の時
| Qcache_not_cached Cache不可、QUERY_CACHE_TYPEにより
| Qcache_queries_in_cache ※0になること
| Qcache_total_blocks
★lockの確認とプロセスの削除(例:実行中のSQL)
SHOW PROCESSLIST;
SHOW FULL PROCESSLIST;
SHOW FULL PROCESSLIST \G; 垂直表示
KILL <プロセスId>;
★NOT FOUNDに関する注意点
MySQL 5.5以前
・カーソルがデータセットの最後に達した時
MySQL 5.6以降
・カーソルがデータセットの最後に達した時
・SELECT...INTOで行が取得されない時
DELIMITER //
DROP PROCEDURE IF EXISTS myProcedure//
CREATE PROCEDURE `myProcedure` (IN fromId INT, IN toId INT)
BEGIN
DECLARE organizationId INT;
DECLARE userName VARCHAR(255);
DECLARE exitFlag INT DEFAULT FALSE;
DECLARE organizationCursor CURSOR FOR
SELECT id FROM organization WHERE id >= fromId AND id <= toId;
DECLARE EXIT HANDLER FOR NOT FOUND SET exitFlag = TRUE;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
SELECT 'EXCEPTION!!!';
ROLLBACK;
END;
DECLARE CONTINUE HANDLER FOR SQLWARNING
BEGIN
SELECT 'WARNING!!!';
ROLLBACK;
END;
SELECT concat('INPUT: fromId is ', fromId);
SELECT concat('INPUT: toId is ', toId);
IF fromId > toId THEN
SELECT 'fromId MUST be less than toId!!!';
SET exitFlag = TRUE;
END IF;
OPEN organizationCursor;
WHILE exitFlag DO
FETCH organizationCursor INTO organizationId;
SELECT u.name INTO userName
FROM user u
JOIN organization o ON u.id = o.user_id
WHERE o.id = organizationId;
END WHILE;
CLOSE organizationCursor;
END//
DELIMITER ;
※他サイトを参照