記事一覧

2010年6月29日火曜日

ホスト名が変わったときなどOracle11g Enterprise Managerは面倒な再構成が必要

Oracleの管理ツール:Oracle Enterprise Managerの構成をやってみました。

今まではインストールしてちょっと動きを確認しただけで特に使っていませんでしたので気がつきませんでしたが。。

ホスト名やIPアドレスが変わると面倒なことになるようです。
何とかconfig配下の構成ファイルを書き換えることで起動できるようになるかと思い試行錯誤しましたが。。
結局SSL用のキーファイルの情報を書き換えることができないので、構成ファイルを手(シェル)で修正して対応というのは断念しました。

マニュアルによると以下の通りです。

Using EMCA When Database Host Name or IP Address Changes

When the database host name (including the domain name) or the IP address changes, deconfigure and then reconfigure the Database Console with the repository create command. Run the following command:

emca -deconfig dbcontrol db -repos drop
emca -config dbcontrol db -repos create

or

emca -deconfig dbcontrol db
emca -config dbcontrol db -repos recreate

実際に実行すると以下のようなプロンプトが表示されますので会話形式で値を入力します。

◆構成情報(リポジトリ)の削除

[oracle@ip-10-130-31-53 db_1]$ emca -deconfig dbcontrol db -repos drop
EMCAの開始 2010/06/29 17:41:23
EM Configuration Assistant, リリース11.2.0.0.2 Production
Copyright (c) 2003, 2005, Oracle. All rights reserved.

次の情報を入力してください:
データベースのSID: orcl
リスナーのポート番号: 1521
SYSユーザーのパスワード:
SYSMANユーザーのパスワード:

続行しますか。 [はい(Y)/いいえ(N)]: y

◆構成情報の作成

[oracle@ip-10-130-31-53 db_1]$ emca -config dbcontrol db -repos create
EMCAの開始 2010/06/29 17:46:16
EM Configuration Assistant, リリース11.2.0.0.2 Production
Copyright (c) 2003, 2005, Oracle. All rights reserved.

次の情報を入力してください:
データベースのSID: orcl
リスナーのポート番号: 1521
リスナーORACLE_HOME [ /vol/app/oracle/product/11.2.0/db_1 ]:
SYSユーザーのパスワード:
DBSNMPユーザーのパスワード:
SYSMANユーザーのパスワード:
通知用の電子メール・アドレス (オプション): xxxxx@xxxx
通知用の送信メール(SMTP)サーバー (オプション): localhost
-----------------------------------------------------------------

次の設定が指定されています

データベースのORACLE_HOME ................ /vol/app/oracle/product/11.2.0/db_1

ローカル・ホスト名 ................ hostname
リスナーORACLE_HOME ................ /vol/app/oracle/product/11.2.0/db_1
リスナーのポート番号 ................ 1521
データベースのSID ................ orcl
通知用の電子メール・アドレス ............... xxxxx@xxxx
通知用の送信メール(SMTP)サーバー ............... localhost

-----------------------------------------------------------------
続行しますか。 [はい(Y)/いいえ(N)]: y

上記を実行したことで確かにEMが起動しました。

んんん。使いづらいなぁ。

2010年6月17日木曜日

OracleベースのWebアプリをMySQLベースに移行した(最終回)

今回のエントリーが最終回です。

内容は「Webアプリケーションの改変(基本的にはSQL文)」についてです。
1)日付データの編集は? (to_char <-> date_format)
2)SEQUENCEの移行は? (SEQUENCE <-> auto_increment)
3)where句で使うrownumは? (rownum <-> limit)
4)NVL関数は? (nvl <-> ifnull)
5)CHR関数を使った「改行コード」の変換は?
6)そのまま使えた同一構文の関数
7)Oracle固有の表の外部結合を標準SQL化
8)日付型にNULLを許さないMySQL
9)DUAL表を使ったSQL文は?
10)弊社製品101NEO固有の問題
11)データベース接続について

参照:MySQLのSQLリファレンス
参照:OracleのSQL言語リファレンス

1)日付データの編集は?(to_char <-> date_format)
Oracle
SQL> select to_char(sysdate, 'yyyy/mm/dd hh24:mi:ss') from dual;
TO_CHAR(SYSDATE,'YYYY/MM/DDHH24:MI:SS')
---------------------------------------------------------
2010/06/17 11:18:58

MySQL
mysql> select date_format(now(), '%Y/%m/%d %H:%i:%s');
+-----------------------------------------+
| date_format(now(), '%Y/%m/%d %H:%i:%s') |
+-----------------------------------------+
| 2010/06/17 11:17:56 |
+-----------------------------------------+
Note:MySQLの現在日時は current_timestamp 関数も同義です。

2)SEQUENCEの移行は?(SEQUENCE <-> auto_increment)

カラムの値を自動採番させたい場合、OracleではSEQUENCEオブジェクトを使用しますが、MySQLではカラム属性の auto_increment を使用します。
Oracle
1.SEQUENCEオブジェクトの作成
 create sequence seq_tar_m;
2.INSERT
 insert into TAR_M
  values(seq_tar_m.nextval, 'Oracleの自動採番');
3.現在の採番値の確認
 select seq_tar_m.currval from dual;
MySQL
1.自動採番属性付きのカラム定義
 create table TAR_M (tar_id int(10) auto_increment
          , subject varchar(100));
2.INSERT
 insert into TAR_M (subject) values('Oracleの自動採番');
3.現在の採番済み最大値の確認
 select last_insert_id() from TAR_M;
Note:auto_increment 指定している tar_id の指定は不要です。

3)where句で使うrownumは?(rownum <-> limit)

検索条件にHitしたデータのうち10件だけ表示したいというようなクエリはMySQLの場合 limit 節を使用します。
Oracle
SQL> select t.* from
2 (select STATUS_ID, STATUS_NAME from TAR_STATUS_M order by STATUS_ID) t
3 where rownum < 6;

STATUS_ID STATUS_NAME
---------- --------------------------------------------------
1 ->未着手
2 ->検討中
5 ->連絡1回
6 ->連絡2回
7 ->緊急

MySQL
mysql> select t.* from
-> (select STATUS_ID, STATUS_NAME from TAR_STATUS_M order by STATUS_ID) t
-> limit 5;
+-----------+--------------+
| STATUS_ID | STATUS_NAME |
+-----------+--------------+
| 1 | ->未着手 |
| 2 | ->検討中 |
| 5 | ->連絡1回 |
| 6 | ->連絡2回 |
| 7 | ->緊急 |
+-----------+--------------+
MySQLのSELECT文のlimit節は引数が1つのときは取得する件数ですが以下のように「オフセット,取得件数」という指定ができます。
オフセットは0から始まります。
MySQL
mysql> select t.* from (select STATUS_ID, STATUS_NAME from TAR_STATUS_M order by status_id) t limit 0,4;
+-----------+--------------+
| STATUS_ID | STATUS_NAME |
+-----------+--------------+
| 1 | ->未着手  |
| 2 | ->検討中  |
| 5 | ->連絡1回  |
| 6 | ->連絡2回   |
+-----------+--------------+

4)NVL関数は? (nvl <-> ifnull)

OracleのNVL関数はIFNULL関数にそのまま置き換えればOKです。
Oracle
SQL> select nvl(null, 'TRUE') from dual;
NVL(
----
TRUE

MySQL
mysql> select ifnull(null, 'TRUE');
+----------------------+
| ifnull(null, 'TRUE') |
+----------------------+
| TRUE |
+----------------------+

5)CHR関数を使った「改行コード」の変換は?

クエリで取得するデータの文字列操作にCHR関数で「改行コード」を出力している箇所があったのでその部分を変換しました。
改行コードの扱いはOracleが特殊でMySQLは一般的ですね。

CR(キャリッジリターン):CHR(13) <-> '\r'
LF(ラインフィード)  :CHR(10) <-> '\n'
Oracle
select replace(h.his_report,chr(13)||chr(10), chr(10)) from TAR_HISTORY h;
MySQL
select replace(h.his_report,'\r\n', '\n') from TAR_HISTORY h;

6)そのまま使えた同一構文の関数
mod関数:mod(n,m)
case関数:case when [condition] then result else result end
replace関数:replace(a, 'AA', 'aa')

7)Oracle固有の表の外部結合を標準SQL化

Oracleの外部結合はwhere句の結合条件で以下のように指定することが可能です。

select p.name, i.ip_address
from pc p, iptbls i where p.key = i.key(+);

ただし、上記のSQL構文はOracle固有ですので標準的なSQL構文に変更しました。

select p.name, i.ip_address
from pc p left join iptbls i on where p.key = i.key;

内部結合は、そのままMySQLでも動作しますが、標準化として INNER JOIN に変更しました。
昔の書き方のほうが見た目はシンプルですが、わかりやすさはSQL標準の書き方ですね。

8)日付型にNULLを許さないMySQL

Oracleは日付型のデータにNULLを格納できるのですがMySQLはエラーになりますので'0000-00-00'セットします。
MySQLは格納する日付型のチェックはかなり緩いようです。詳しくはマニュアルを参照してください。

9)DUAL表を使ったSQL文は?

以下の通りシンプルです。

select 'xxxxxx' from dual; <-> select 'xxxxxx';

10)弊社製品101NEO固有の問題
現象
配列にセットした要素のデータ型が数値と文字列型が混在している場合にその配列内の日本語が文字化けした。

解決方法
クエリで値を取得する際に数値を文字列にcastしてした
SQL例:select cast(ifnull(VERSION,'-') as char) from PRODUCT_M;
以上 上記で説明したSQL文の変換をプログラム全体にわたり行ってWebアプリの移行は終了です。

11)データベース接続について

移行したWebアプリケーションは弊社の101NEOというスクリプト言語で記述されたServletアプリケーションですのでデータベースアクセスはJDBCドライバを介して行います。

具体的な作業は以下の通りです。

  • MySQL用のJDBCドライバの取得と配置
  • WebアプリケーションのJDBC接続構成ファイルの変更

◆MySQL用のJDBCドライバの取得と配置
以下のドライバーをsourceforgeサイトよりダウンロードしwarファイルを構成します。

mysql-connector-java-5.1.12-bin.jar

◆WebアプリケーションのJDBC接続構成ファイルの変更
101NEOアプリケーションのアプリケーション仕様定義書(構成ファイル)のDB接続識別子の記述をMySQL用に変更。

例)
db = org.gjt.mm.mysql.Driver,jdbc:mysql://localhost/helpdesk,helpdeskadmin,PASSWORD

(終わりに)
いかがでしたでしょうか。3回にわたって実際に弊社がプロジェクトで利用している課題管理サイト(インシデント管理)をOracleからMySQLへデータベース移行した内容を掲載しました。
実行結果がそまま張り付けてあったりとやや見栄え的に残念なところも多々ありますが。。ご容赦ください。

ご質問歓迎しますのでまずは twitter まで!(^^)/~

My Twitter account : tnikaido


(おわり)

2010年6月16日水曜日

OracleベースのWebアプリをMySQLベースに移行した(2)

昨日のエントリーに引き続き。。

今回は「データベースのデータ移行」について記載します。

1)データベース作成
2)ユーザの作成および権限付与
3)OracleのデータをCSVファイルへ出力
4)テーブル作成
5)CSVファイルをMySQLへロード

1)データベース作成

データベースの作成は mysqladmin のコマンドにもありますが mysql コマンドで実行します。

以下の例では文字コードセットを指定して作成していますが、指定しない場合は、my.cnf のシステム変数の設定値で決まります。
今回は my.cnf に utf8 をデフォルトして指定しているのでコマンド実行時に指定しなくても同じことですが、明示的に指定したスクリプトを残すほうがわかりやすいですね。

[root@ip-10-130-6-146 ~]# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 5.0.45 Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> create database helpdesk default character set utf8;
Query OK, 1 row affected (0.00 sec)

これで helpdesk という枠ができました。
create database は、create schema も同義。

Oracleのcreate database文は、実行可能なOracleデータベースのインストールのような位置づけです。
データベースのメタ情報を管理するシステム表領域やユーザ用の表領域、一時表領域やパッケージなどが作成されます。
そのデータベースの中にユーザを作成するとユーザ用のスキーマという枠が同時に作成されます。
このスキーマとMySQLのcreate database コマンドがほぼ同義ですね。

2)ユーザの作成および権限付与

データベースの枠ができたので次にその枠を使うユーザを作成して権限を付与します。
権限はとりあえず必要最低限で以下のようにしました。
ユーザの作成と権限付与は grant で同時に行えます。

mysql> grant select,insert,update,delete,create,drop,alter on helpdesk.*
-> to helpdeskadmin@localhost identified by 'helpdeskadmin';

Query OK, 0 rows affected (0.00 sec)

#Oracle風にするならデータベース名(スキーマ名)とユーザ名を合わせる感じですので helpdeskadmin は helpdesk ですね。

メモ:すべての権限を付与するコマンド
mysql> grant all PRIVILEGES ON helpdesk.* to helpdeskadmin@localhost;

メモ:権限変更が反映されるタイミング
権限(権限テーブル)はメモリにキャッシュされるので変更したら以下コマンドの実行してリロードさせましょうという記事も見かけますが grant や revoke で変更した権限情報は、変更直後にサーバーが自動的にリロードするようです。手動リロードが必要なのは権限テーブルを直接DMLで書き換えた場合だけですね。

mysql> flush privileges;


◆権限の確認

mysql> use information_schema
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> desc SCHEMA_PRIVILEGES;
+----------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+-------+
| GRANTEE | varchar(81) | NO | | | |
| TABLE_CATALOG | varchar(512) | YES | | NULL | |
| TABLE_SCHEMA | varchar(64) | NO | | | |
| PRIVILEGE_TYPE | varchar(64) | NO | | | |
| IS_GRANTABLE | varchar(3) | NO | | | |
+----------------+--------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

mysql> select * from SCHEMA_PRIVILEGES where TABLE_SCHEMA = 'helpdesk';
+-----------------------------+---------------+--------------+----------------+--------------+
| GRANTEE | TABLE_CATALOG | TABLE_SCHEMA | PRIVILEGE_TYPE | IS_GRANTABLE |
+-----------------------------+---------------+--------------+----------------+--------------+
| 'helpdeskadmin'@'localhost' | NULL | helpdesk | SELECT | NO |
| 'helpdeskadmin'@'localhost' | NULL | helpdesk | INSERT | NO |
| 'helpdeskadmin'@'localhost' | NULL | helpdesk | UPDATE | NO |
| 'helpdeskadmin'@'localhost' | NULL | helpdesk | DELETE | NO |
| 'helpdeskadmin'@'localhost' | NULL | helpdesk | CREATE | NO |
| 'helpdeskadmin'@'localhost' | NULL | helpdesk | DROP | NO |
| 'helpdeskadmin'@'localhost' | NULL | helpdesk | ALTER | NO |
+-----------------------------+---------------+--------------+----------------+--------------+
7 rows in set (0.00 sec)


3)OracleのデータをCSVファイルへ出力

OracleのユーティリティSQL*Plusを使ってデータベースからCSVファイルを簡単に生成します。
※弊社提供のOracle専用ユーティリティ101will Free Editionをぜひご利用ください!

101will Free Editionでは以下のようなSQL文とSQLを実行する親シェルを自動生成することができます。

Oracleのhelpdeskスキーマ内にあるuser_mテーブルのデータをcsvファイルに抜き出すプログラム一式

すべての移行対象テーブルのCSVファイルを生成します。

4)テーブル作成

◆OracleとMySQLのデータ型マッピング

Oracleのデータ型をMySQLのデータ型に合わせてCREATE TABLE文をカスタマイズします。

メモ:データ型マッピングの詳細は、Oracle社のマニュアル:表2-4 Oracle SQL Developerで使用されるデフォルトのデータ型マッピングを参照

上記のマニュアルを参照しながら以下のようにDDLを変換します。
基本的な型は問題なく変換できます。
OracleのVARCHAR2は最大長4000バイトですがMySQL(ver5.0.34)のVARCHARは65,532バイトなのでスカラー型でもそこそこ大きなテキストを扱えるのでちょっといいなと思いました。

・MySQLのDDL例)

CREATE TABLE NEWS_M (
ID INT NOT NULL COMMENT "ニュースID",
REG_DATE DATETIME COMMENT "登録日",
NEWS VARCHAR(4000) COMMENT "ニュース内容",
PRIMARY KEY (ID)
)
COMMENT = "ニュースマスタ"
ENGINE = INNODB;

・OracleのDDL例)

CREATE TABLE "NEWS_M" (
NEWS_ID NUMBER(8) NOT NULL,
REG_DATE DATE,
NEWS_DETAIL VARCHAR2(4000),
STATUS VARCHAR2(10),
CONSTRAINT "NEWS_M_PK" PRIMARY KEY (NEWS_ID)
);
COMMENT ON TABLE "NEWS_M" IS 'ニュースマスタ';
COMMENT ON COLUMN "NEWS_M"."NEWS_ID" IS 'ニュースID';
COMMENT ON COLUMN "NEWS_M"."REG_DATE" IS '登録日';
COMMENT ON COLUMN "NEWS_M"."NEWS_DETAIL" IS 'ニュース内容';
COMMENT ON COLUMN "NEWS_M"."STATUS" IS 'ステータス';

◆テーブル作成スクリプトの作成

※変換したDDLスクリプトを cre_tables.sql に保存して実行しましょう。

# mysql -u helpdeskadmin -pPASSWORDTEXT helpdesk

mysql> source cre_tables.sql

◆作成したテーブルの確認

mysql> use information_schema
mysql> select TABLE_NAME, TABLE_TYPE, ENGINE, TABLE_COMMENT
-> from tables where TABLE_SCHEMA='helpdesk';
+--------------+------------+--------+---------------------------------------------
| TABLE_NAME | TABLE_TYPE | ENGINE | TABLE_COMMENT
+--------------+------------+--------+---------------------------------------------
| APSERVER_M | BASE TABLE | InnoDB | TPBコンポーネント; InnoDB free: 3072 kB
| COMPONENT_M | BASE TABLE | InnoDB | チーム内分類マスタ; InnoDB free: 3072 kB
| CUSTOMER_M | BASE TABLE | InnoDB | 顧客マスタ; InnoDB free: 3072 kB
| DB_M | BASE TABLE | InnoDB | ファンクション; InnoDB free: 3072 kB
| DOCTYPE_M | BASE TABLE | InnoDB | ドキュメントタイプ; InnoDB free: 3072 kB
| DOC_M | BASE TABLE | InnoDB | 技術資料; InnoDB free: 3072 kB
| FAQ_M | BASE TABLE | InnoDB | FAQテーブル; InnoDB free: 3072 kB
| IPTBLS | BASE TABLE | InnoDB | IPTBLS; InnoDB free: 3072 kB
| NEWS_M | BASE TABLE | InnoDB | ニュースマスタ; InnoDB free: 3072 kB
| OS_M | BASE TABLE | InnoDB | 新課題分類; InnoDB free: 3072 kB
| PRODUCT_M | BASE TABLE | InnoDB | チームマスタ; InnoDB free: 3072 kB
| ROLE_M | BASE TABLE | InnoDB | ロールマスタ; InnoDB free: 3072 kB
| SUP_LEVEL_M | BASE TABLE | InnoDB | サポートレベルマスタ; InnoDB free: 3072 kB
| SUP_TYPE_M | BASE TABLE | InnoDB | サポートタイプマスタ; InnoDB free: 3072 kB
| TAR_HISTORY | BASE TABLE | InnoDB | 問合せ履歴; InnoDB free: 3072 kB
| TAR_M | BASE TABLE | InnoDB | TAR_M; InnoDB free: 3072 kB
| TAR_STATUS_M | BASE TABLE | InnoDB | ステータスマスタ; InnoDB free: 3072 kB
| USER_M | BASE TABLE | InnoDB | ユーザーマスタ; InnoDB free: 3072 kB
+--------------+------------+--------+----------------------------------------------
18 rows in set (0.01 sec)


5)CSVファイルをMySQLへロード

OracleのSQL*LoaderのようなMySQLのユーティリティは mysqlimport です。

Oracleのsqlldrコマンドを実行するようにmysqlimportを実行します。

コマンド構文)
# mysqlimport -d -i --fields-terminated-by=, --fields-optionally-enclosed-by=\" -u root -pPASSWORDTEXT helpdesk /home/tnikaido/will/csvunloader/csv/USER_M.csv

上記コマンドの指定内容は以下の通りです。

ファイル形式:フィールドの区切り文字は「,」でデータに「,」を含む場合は「"」で囲う。
実行ユーザ:root
パスワード:PASSWORDTEXT
ロード先データベース:helpdesk
ロード先テーブル:USER_M
ロードするCSVファイル:/home/tnikaido/will/csvunloader/csv/USER_M.csv
※CSVファイル名は「テーブル名.csv」でなければいけないという規約があります。
※フルパスで指定しないとデフォルトのディレクトリは datadir(/etc/my.cnf)
 /var/lib/mysql/helpdesk/をみます。
実行オプション:-d 既存データを削除後にロード
        -i キーの重複エラーを無視して後続データのロードを行う

実行例)

[tnikaido@ip-10-130-6-146 csv]$ mysqlimport -d -i --fields-terminated-by=, --fields-optionally-enclosed-by=\" -u root -p helpdesk /home/tnikaido/will/csvunloader/csv/USER_M.csv
Enter password:
helpdesk.USER_M: Records: 2 Deleted: 0 Skipped: 0 Warnings: 0
[tnikaido@ip-10-130-6-146 csv]$

mysql> select USER_ID, NAME from USER_M;
+----------+--------------+
| USER_ID | NAME |
+----------+--------------+
| helpdesk | 二階堂隆 |
| test | テスト |
+----------+--------------+
2 rows in set (0.00 sec)

mysql>

生成したCSVファイルを任意のフォルダに作成して awk コマンドでmysqlimport実行コマンドを生成すると便利です。

% ls | grep csv| awk '{print "mysqlimport -d -i --fields-terminated-by=, --fields-optionally-enclosed-by=\\\" -u root -pPASSWORDtext helpdesk /home/tnikaido/will/csvunloader/csv/" $1}'

次回はアプリケーションの移行(ほとんどSQLの書き換え)についてエントリーします。

(おわり)

2010年6月11日金曜日

OracleベースのWebアプリをMySQLベースに移行した(1)

6月初めごろから始めたOracleベースのWebアプリケーションのMySQL化が完了しました。
BLOGへのエントリーがタイムリーでないのが、いまいちですが。。

基本的な作業タスクは以下の通りです。


・MySQL環境の構築
・データベースの移行(OracleからMySQLへ)
・Webアプリケーションの改変(基本的にはSQL文)


MySQLもRailsのチュートリアルで使用する程度で簡単にしか触ったことがなかったので本当にリアルに使っているWebアプリケーションが簡単に移行できるかは全くわかりませんでした。

実際にやってみると予想以上に簡単に移行できました。

工数的には4人日程度です。

アプリケーション規模は以下の通り

・テーブル数:18テーブル
・画面数:30画面
・CSV出力アプリ:1本

アプリケーションの概要はユーザマニュアル/管理者マニュアルを参照してください。

MySQLは、日本語情報もそこそこ多く、移行対象のWebアプリが使っているOracleの機能は、MySQLにも存在することが比較的簡単に知ることができて、実際に使ってみてもとても簡単でした。

ただし、日本語マニュアルに記載がないものがあるので、最新の英語マニュアルもチェックすると良いと思います。

この移行作業について何回かに分けてBLOGで紹介したいと思います。

#どこから記載するのがいいのかもいろいろ迷ったのですがMySQLはインストールされている状態で移行用のデータベース作成するMySQLシステムの設定から紹介したいと思います。

MySQL環境の構築


◆移行作業に必要な基本知識

・MySQLサービスの起動/停止は?(@Oracle:インスタンス起動とデータベースopen)

 mysqld スクリプトを使用します。

 起動・停止の例)
 # /etc/init.d/mysqld start
 # /etc/init.d/mysqld stop

 MySQLの推奨では、MySQL のサービスが障害で停止してしまっても自動的に再起動する mysqld_safe というスクリプトを使ってデータベースを起動させますが、更新系のアプリケーションで利用する場合は、自動的に再起動はしたくないので使いませんでした。参照系DBには良いかもしれませんね。

 # /usr/bin/mysqld_safe &
 
・利用するコマンドラインツールは?(@Oracle:sqlplus、sqlldr)

 mysqladmin、mysql、mysqlimport コマンドを利用します。

 インストール直後には root ユーザのパスワード設定で mysqladmin コマンドを使用します。

 # /usr/bin/mysqladmin -u root password 'new-password'

 rootパスワードを変更した後、mysql コマンドでログインしデータベース、ユーザ、権限付与、テーブル作成などを行い、mysqlimport でCSVデータをロードします。

・データベースのメタデータ情報はどうやって知るの?(@Oracle:ディクショナリビュー、DBA_xxx)

 MySQLには、information_schema データベースがあります。
 
 Oracleのメタ情報は、ディクショナリビュー(DBA_xxxx、ALL_xxx、USER_xxx)で確認しますが、

 MySQLのメタ情報は、information_schema で確認することができます。
 MySQLメタ情報は、Oracleのディクショナリビューのように膨大な情報ではないために把握するのは簡単ですね。
 information_schemaが保持しているテーブルは以下の通りです。
 それぞれのテーブル構造の確認もOracleでやるように mysql> desc table_name; で出来るんですね。

mysql> use information_schema
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+---------------------------------------+
| Tables_in_information_schema |
+---------------------------------------+
| CHARACTER_SETS |
| COLLATIONS |
| COLLATION_CHARACTER_SET_APPLICABILITY |
| COLUMNS |
| COLUMN_PRIVILEGES |
| KEY_COLUMN_USAGE |
| PROFILING |
| ROUTINES |
| SCHEMATA |
| SCHEMA_PRIVILEGES |
| STATISTICS |
| TABLES |
| TABLE_CONSTRAINTS |
| TABLE_PRIVILEGES |
| TRIGGERS |
| USER_PRIVILEGES |
| VIEWS |
+---------------------------------------+
17 rows in set (0.00 sec)

mysql> desc tables;
+-----------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+-------+
| TABLE_CATALOG | varchar(512) | YES | | NULL | |
| TABLE_SCHEMA | varchar(64) | NO | | | |
| TABLE_NAME | varchar(64) | NO | | | |
| TABLE_TYPE | varchar(64) | NO | | | |
| ENGINE | varchar(64) | YES | | NULL | |
| VERSION | bigint(21) | YES | | NULL | |
| ROW_FORMAT | varchar(10) | YES | | NULL | |
| TABLE_ROWS | bigint(21) | YES | | NULL | |
| AVG_ROW_LENGTH | bigint(21) | YES | | NULL | |
| DATA_LENGTH | bigint(21) | YES | | NULL | |
| MAX_DATA_LENGTH | bigint(21) | YES | | NULL | |
| INDEX_LENGTH | bigint(21) | YES | | NULL | |
| DATA_FREE | bigint(21) | YES | | NULL | |
| AUTO_INCREMENT | bigint(21) | YES | | NULL | |
| CREATE_TIME | datetime | YES | | NULL | |
| UPDATE_TIME | datetime | YES | | NULL | |
| CHECK_TIME | datetime | YES | | NULL | |
| TABLE_COLLATION | varchar(64) | YES | | NULL | |
| CHECKSUM | bigint(21) | YES | | NULL | |
| CREATE_OPTIONS | varchar(255) | YES | | NULL | |
| TABLE_COMMENT | varchar(80) | NO | | | |
+-----------------+--------------+------+-----+---------+-------+
21 rows in set (0.00 sec)

mysql>


・データベースの初期化パラメータは?(@Oracle:初期化パラメータ(init.ora)、環境変数)

 /etc/my.cnf に設定します。

 Oracleの場合は、環境変数および初期化パラメータによってデータベースの初期化が行われます。
 同様にMySQLでは my.cnf という構成ファイルにパラメータを設定してシステムの初期化を行います。
 今回は以下のような最低限必要そうな設定をしました。

 1)サーバーの文字コードセットのデフォルト設定(character-set-server)

  Oracleの場合はデータベースの文字コードはcreate databaseで設定します。データベース作成後にalter database文で変更することも9iまでは可能だったと思いますが、現在では文が廃止されて専用のコマンドDatabase Character Set Scanner(CSSCAN)を使って検証し、CSALTERというPL/SQLのスクリプトで変更(またはexp/impなど)するなど実際の文字コードの変換は非常に面倒です。

  ただしMySQLの場合は、文字コードは大変柔軟に設定できるのですね。
  以下の順で設定が有効になります。
  カラム属性 > テーブル属性 > データベース属性 > my.cnf(character-set-server)

 2)照合順序の指定(collation-server)

  照合順序の指定とマニュアルにあるが日本語の場合にどうなるのかいまいちよくわかりません。
  サーバーの文字コードをutf8にすると照合順序のデフォルトは
  utf8_general_ciになるようです。
  blogなどを見てみるとカタカナとひらがなを同一視するような記述もありますね。

 3)ストレージエンジンの設定(default-storage-engine)

  ストレージエンジンとはI/Oの実装部分の仕様です。
  MySQLには複数のストレージエンジンがありますが、デフォルトはMyISAMというISAMファイルです。
  Oracleから移行するデータベースにはACID特性をサポートしたINNODBを指定します。
  INNODBは行レベルロックもサポートする仕様です。
  人によっては完全にサポートされていないという話も聞きますが。。何か情報があれば教えてください。

 4)クライアントからの接続セッションの初期設定(init_connect)

  Oracleでは初期化パラメータやalter sessionで接続しているクライアントのセッション構成を変更することが可能ですが、MySQLにもSETコマンドが存在します。このSETコマンドを init_connect 変数に記述することですべてのクライアントのセッションに適用することができます。
  ※ただし init_connect 変数への記述は、SUPER権限をもつユーザ(root)には適用されません。ここで指定したコマンドがエラーになりSUPERユーザの接続の妨害を防ぐためだそうです。

  このパラメータには、以下のコマンドを設定しました。

  ・クライアントの文字コードセットの指定
  ・トランザクションのコミット属性(autocommitをfalseへ)

   MySQLのコミット属性のデフォルト autocommit です。
   デフォルトではmysqlコマンドで発行するSQLもすべて1文ずつコミットされてしまいます。
   Oracleと同様の動きを期待する場合は、上記のパラメータでautocommitを無効にします。

MySQLのシステム変数の詳細は以下のマニュアルを参考にしてください。

参考:MySQLのシステム変数の詳細日本語マニュアル

********* /etc/my.cnf の内容 ************
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql

default-character-set = utf8
character-set-server = utf8
collation-server = utf8_general_ci
init_connect='SET autocommit=0; SET NAMES utf8'
default-storage-engine = INNODB

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
****************************************

※上記の1)-5)で説明したパラメータ以外はデフォルトで指定されています。
 datadir はMySQLにデータベースを作成した際に物理ファイルを配置するルートディレクトリを指定します。このディレクトリ配下にデータベース名のディレクトリが作成されてテーブルごとにテーブル名.frmというファイルが作成されます。


**** MySQLデータベースの物理ファイル例 ****
[root@ip-10-130-6-146 ~]# ls -al /var/lib/mysql/helpdesk
合計 256
drwx------ 2 mysql mysql 4096 2010-06-07 13:17 .
drwxr-xr-x 5 mysql mysql 4096 2010-06-15 13:38 ..
-rw-rw---- 1 mysql mysql 8726 2010-06-01 13:54 APSERVER_M.frm
-rw-rw---- 1 mysql mysql 8694 2010-06-01 13:03 COMPONENT_M.frm
-rw-rw---- 1 mysql mysql 8768 2010-06-01 13:03 CUSTOMER_M.frm
-rw-rw---- 1 mysql mysql 8696 2010-06-01 13:03 DB_M.frm
-rw-rw---- 1 mysql mysql 8626 2010-06-01 13:03 DOCTYPE_M.frm
-rw-rw---- 1 mysql mysql 13023 2010-06-03 10:40 DOC_M.frm
-rw-rw---- 1 mysql mysql 8965 2010-06-03 10:42 FAQ_M.frm
-rw-rw---- 1 mysql mysql 8558 2010-06-01 13:03 IPTBLS.frm
-rw-rw---- 1 mysql mysql 16857 2010-06-03 10:57 NEWS_M.frm
-rw-rw---- 1 mysql mysql 8675 2010-06-01 13:03 OS_M.frm
-rw-rw---- 1 mysql mysql 21019 2010-06-01 13:03 PRODUCT_M.frm
-rw-rw---- 1 mysql mysql 8629 2010-06-01 13:03 ROLE_M.frm
-rw-rw---- 1 mysql mysql 8633 2010-06-01 13:03 SUP_LEVEL_M.frm
-rw-rw---- 1 mysql mysql 8629 2010-06-01 13:03 SUP_TYPE_M.frm
-rw-rw---- 1 mysql mysql 9016 2010-06-03 10:56 TAR_HISTORY.frm
-rw-rw---- 1 mysql mysql 9825 2010-06-07 13:17 TAR_M.frm
-rw-rw---- 1 mysql mysql 8808 2010-06-01 13:03 TAR_STATUS_M.frm
-rw-rw---- 1 mysql mysql 13356 2010-06-01 13:03 USER_M.frm
-rw-rw---- 1 mysql mysql 61 2010-05-28 18:12 db.opt
[root@ip-10-130-6-146 ~]#
******************************

・設定したシステム変数の確認

my.cnf の指定が終わったらmysqlを再起動してシステム変数を確認してみましょう。

 show variables;


**** SUPER権限を持つ root ユーザで確認した例)****
[root@ip-10-130-6-146 ~]# mysql -u root -p
Enter password:

mysql> show variables like 'character_set%'; show variables like 'init_con%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

+---------------+----------------------------------+
| Variable_name | Value |
+---------------+----------------------------------+
| init_connect | SET autocommit=0; SET NAMES utf8 |
+---------------+----------------------------------+
1 row in set (0.00 sec)
***************************************************

root ユーザはSUPER権限を保有するので init_connect に指定した文字コードの設定が無効になっているのがわかります。
一般ユーザでmysqlにログインして同様のコマンドを実行すると以下のようにクライアントの文字コードの設定もutf8になっているのがわかります。

***************************************************
mysql> show variables like 'character_set%'; show variables like 'init_con%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

+---------------+----------------------------------+
| Variable_name | Value |
+---------------+----------------------------------+
| init_connect | SET autocommit=0; SET NAMES utf8 |
+---------------+----------------------------------+
1 row in set (0.00 sec)

mysql>
***************************************************


以上でやっとOracleのデータベースをMySQLデータベースに移行する環境が整いました。
次回は、テーブルの移行とデータのローディングについてエントリーしたいと思います。

Amazon Web Services Console が S3 をサポート

Amazonは着実にサービスをリリースしますね。
Googleも着実にサービスをリリースしてきていますがAmazonのほうが企業システム寄りの機能を地道にリリースしてきているように思います。

今回はAmazonが提供しているシステム管理者用のWeb ConsolでS3(ストレージサービス:99.999999999% availability)を管理できるというお知らせが届きました。



早速画面を見てみました。



ストレージなのでフォルダやファイル管理ですが直感的に操作することができて良いと思います。
もちろんすべてのリージョンをサポートしていますのでSingaporeに置いているファイルも管理できます。
ダウンロードが1ファイルづつしかまだ実行できないようなのは、改善してほしいですね。
(ファイルを選択して右クリックして表示されたメニューにDownloadがあります)

WindowsにインストールするようなCloudBerry Explorer for Amazon S3など便利なツールもfree版でありますが、AWS ConsolでS3をサポートしたことでWebブラウザがあればどこからでもAmazonのサービスを1つのコンソールから操作することができるのは大変便利ですね。

継続的にEnhanceされてくることは確実ですので期待したいと思います。

Microsoft Office 2010 優待アップグレード申し込みしてみた

最近PCを変えたので2007のpower pointを購入した。せっかくなのでMicrosoft Office 2010 優待アップグレード キャンペーンにのってみたのですが。。この手続きみなさんはどう思いますか?

1)購入確認の必読ページへ
2)Windows Live ID必須のためユーザ登録
3)ユーザ登録すると確認メールを受信するので受信のURLをクリック
4)Upgradeオンライン登録
 4-1)製品のプロダクトIDの入力必須のためパワポ起動、メニューから4階層クリックしてやっとプロダクトID表示
 4-2)上記の1)のページのリンクにある「購入証明申請書」をダウンロード&印刷
 4-3)製品購入時の領収書原本!を申請書に張り付け
   Amazon.comで購入したのだがすでに領収書は破棄しているためメールの購入確認を張り付けてみる
   これで駄目とか言われたら呆れるが。。
 4-3)購入パッケージの箱に入っているチケットみたいなものを切り取り上記4-2の申請書に張り付ける
 
 ※ここまでほんとに買ったのか?的な扱いをするMSさんをユーザはどう思うのだろうか?
  正直にいえば私は全く好きになれない。むしろ代替えが出たら即やめる!

 4-4)当オンライン登録サイトで送付先など個人情報入力
    Live ID作ったのにそのIDの入力と決済情報だけでいけるかと思いきや、住所とか普通に入力を
    要求される。Live IDは何のために作らせたの??
    決済情報の入力は、カード番号とカード有効期限、セキュリティコードのみ、カード登録氏名の入力もなしでやや不安。

 4-5)上記4-4で指定したmailアドレスに確認メールが届く。
    gmailのアドレスを受信アドレスにしていたらこのメールが迷惑メールに振り分けられる(笑)
    迷惑メールを解除して受信トレイで表示させると以下のように激しい警告(笑)



    これはMSからのメールだからというわけでもないだろうに。。アプリのつくりが悪いのか。。
    届いたメール本文に記載されているURLをクリックしなければ申請登録できないのだが
    gmail画面上では警告が出ているのでURLは無効になってクリックできない。
    ということでコピペで該当URLのページを表示。

 4-6)上記ページに申請書の記載に必要な「オーダーID」が表示される。
 4-7)上記の「オーダーID」を「購入証明申請書」に記入して郵送必須。
   さらにここでも個人情報を要求される。
   Live ID登録時、オンライン申請登録時、購入証明申請書 と何度も個人情報の入力を要求される。
   またキャンペーン対象商品が何かも上記の申請書のチェックボックスにチェックをするようになっている。
   オンラインでも登録している情報のはずであるが。。
    
以上 でやっと申請ができる。

情報の取り方も無駄が多くキャンペーンに準備したそれぞれのマテリアル(申請書やWebページ)間で
全く整合性が取れていないこの業務プロセンスは本当にセンスがない。
これは大企業病なのだろうかと思った。

あまりの面倒くささに若干いかりつつもblogネタとなった(笑)

MSさん関係者が見て改善の気づきになれば幸いです。それとも余計なお世話ですか。