PostgreSQL 8.0 がリリースされた。今回は Windows ネイティブ版も公式リリースとなった。Windows で無料の DB といえば FireBird や MySQL だったが、より柔軟なライセンスの Postgres が選択肢に入ることになる。
http://www.postgresql.org/about/news.277
本家。
日本 PostgreSQL ユーザ会 PostgreSQL 8.0 Press Kit
http://www.postgresql.jp/ug/press-release/2005-01.html
PostgreSQL 8.0正式リリース,ロールフォワードやWindows上のネイティブ動作など実現 : IT Pro ニュース
http://itpro.nikkeibp.co.jp/free/ITPro/NEWS/20050119/154938/
PostgreSQL 8.0がリリース - Windowsに正式対応 (MYCOM PC WEB)
http://pcweb.mycom.co.jp/news/2005/01/19/013.html
スラッシュドット ジャパン | PostgreSQL 8.0 リリース
http://slashdot.jp/article.pl?sid=05/01/19/0641233&topic ...
各地の FTP ミラーや BitTorrent から入手できるが、今日リリースされたばかりなのでミラー待ちだったり混雑していたりする。幸いなことに RingServer にはもうミラーされていたのでそこからダウンロードした。SourceForge にもある。
RingServer の PosgreSQL ミラー
http://www.t.ring.gr.jp/archives/misc/db/postgresql/
http://www.t.ring.gr.jp/archives/misc/db/postgresql/source/v ...
http://www.t.ring.gr.jp/archives/misc/db/postgresql/binary/v ...
SourceForge.net: Project Info - PostgreSQL Database Server
http://sourceforge.net/projects/pgsql/
追記。1月20日の朝に見たら PostgreSQL 日本ユーザ会からもダウンロードできるようになっていた。
PostgreSQL ダウンロード情報
http://www.postgresql.jp/PostgreSQL/download.html
ダウンロードした zip を展開して postgresql-8.0.msi を実行すると、GUI のインストーラが起動する。
最初の画面で詳細なインストールログを出力するかどうかのチェックボックスがあったので、迷わずオンにした。
基本的には Next を連打してればインストールが進むという、実に Windows らしい作りだ。
おおっ、デフォルトで .NET 用のドライバ(データプロバイダ?)もインストールされるんだ。こりゃ楽だ。
他にも JDBC と ODBC と OLEDB のドライバやプロバイダがデフォルトでインストールされる。
日本語に超訳すると以下のような感じか。
アカウントの生成機能を使うのは問題ないが、パスワードは自動生成に頼らない方がいい。自動生成は強固なパスワードを生成してはくれるのだが、'Xnd|)p_O|IL!_?=>BZwRF).voXxaIyP' なんてパスワードが設定されるし、生成されたパスワードはメッセージダイアログで表示されるのでコピー & ペーストすることが困難。パスワードはあらかじめ十分強固なものを決めておく方がいい。
ちなみに、指定したパスワードが弱そうな場合は以下のよう警告される。
前置きが長くなったが、Service configuration 画面での設定項目をメモ。
まず、Windows のサービスとして動かしたいので、Install as a service のチェックボックスはオン。
今回はデフォルトの postgres のままとし、インストーラにサービス起動用アカウントを作ってもらうことにした。
項目を入力して次に進もうとすると、以下の確認が来た。develop\postgres というアカウントは存在しないみたいだけど、作る? という内容。もちろん作ってもらった。
初期化したいので、Initialize database cluster のチェックボックスはオン。
Port number はデフォルトの 5432。
Locale と Encoding の設定はちょっと迷った。でも、この設定については過去に Postgres のメーリングリストの記事をメモした覚えがある。ChangeLog メモを検索、と。あった。2002-09-12 の「PostgreSQL7.3 以降の configure オプション」だ。この知識は 8.0 でも有効なのかな? そういえば Unicode が見あたらないけど、例によって ClientEncoding で対処するんだろうか? とりあえずメモに従って Locale は C 、Encoding は EUC_JP を選択した。
あとは、Postgres スーパーユーザのユーザ名とパスワードの入力欄。Postgres スーパーユーザアカウントはサービス起動アカウントとは別物。以下の注意書きにもあるように、セキュリティ的な理由からサービス起動アカウントとスーパーユーザアカウントのパスワードは同じものを使わないこと。
DBSize と pgAdmin Support には最初からチェックが付いている。いくつか興味を引かれるものはあるけど、まずはとりあえずデフォルトのままインストールしてみる。
上記メッセージが出たらインストール準備完了。Next を押してあとはインストールが終わるのを待つだけ。
ちなみに、Subscribe to pgsql-announce のボタンははクリックすると Posgres のアナウンス用メーリングリストの購読申し込み画面 http://mail.postgresql.org/mj/mj_wwwusr?domain=postgresql.or ... をブラウザで開きにいく。とりあえず不要なので購読はしない。
- Windows 版 PosgreSQL 8.0 リリースノートやプレスリリース、ニュース
PostgreSQL: News: PostgreSQL 8.0.0 Releasedhttp://www.postgresql.org/about/news.277
本家。
日本 PostgreSQL ユーザ会 PostgreSQL 8.0 Press Kit
http://www.postgresql.jp/ug/press-release/2005-01.html
PostgreSQL 8.0正式リリース,ロールフォワードやWindows上のネイティブ動作など実現 : IT Pro ニュース
http://itpro.nikkeibp.co.jp/free/ITPro/NEWS/20050119/154938/
PostgreSQL 8.0がリリース - Windowsに正式対応 (MYCOM PC WEB)
http://pcweb.mycom.co.jp/news/2005/01/19/013.html
スラッシュドット ジャパン | PostgreSQL 8.0 リリース
http://slashdot.jp/article.pl?sid=05/01/19/0641233&topic ...
- Windows 版 PosgreSQL 8.0 ダウンロード
Windows 版 PosgreSQL 8.0 のファイルは zip アーカイブでサイズは約17MB。各地の FTP ミラーや BitTorrent から入手できるが、今日リリースされたばかりなのでミラー待ちだったり混雑していたりする。幸いなことに RingServer にはもうミラーされていたのでそこからダウンロードした。SourceForge にもある。
RingServer の PosgreSQL ミラー
http://www.t.ring.gr.jp/archives/misc/db/postgresql/
http://www.t.ring.gr.jp/archives/misc/db/postgresql/source/v ...
http://www.t.ring.gr.jp/archives/misc/db/postgresql/binary/v ...
SourceForge.net: Project Info - PostgreSQL Database Server
http://sourceforge.net/projects/pgsql/
追記。1月20日の朝に見たら PostgreSQL 日本ユーザ会からもダウンロードできるようになっていた。
PostgreSQL ダウンロード情報
http://www.postgresql.jp/PostgreSQL/download.html
- Windows 版 PosgreSQL 8.0 インストール
Windows2000 Professonal SP4 に Windows 版 PosgreSQL 8.0 をインストールする。ダウンロードした zip を展開して postgresql-8.0.msi を実行すると、GUI のインストーラが起動する。
最初の画面で詳細なインストールログを出力するかどうかのチェックボックスがあったので、迷わずオンにした。
□ Write detailed installation log to postgresql-8.0.log in the current directoryインストール先のディレクトリは C:\Program Files\PostgreSQL\8.0\ を選択。
基本的には Next を連打してればインストールが進むという、実に Windows らしい作りだ。
- インストールするコンポーネントの選択
インストールするコンポーネントの選択画面。私はデフォルトのまま、とくに何も変更はしなかった。おおっ、デフォルトで .NET 用のドライバ(データプロバイダ?)もインストールされるんだ。こりゃ楽だ。
The PostgreSQL .NET Driver.
This feature requires 3244KB on your hard drive.
他にも JDBC と ODBC と OLEDB のドライバやプロバイダがデフォルトでインストールされる。
- Service configuration 画面での入力項目
Service configuration 画面には、下の方に注意書きがある。The service account is the account that runs the PostgreSQL database server. It must NOT be a member of the local administrators group. If you have not already created an account, the installer can do so for you. Enter an account name and a password, or leave the password blank to have one auto-generated.
日本語に超訳すると以下のような感じか。
サービスアカウントは postgres の データベースサーバを実行するアカウントです。サービスアカウントはローカルの Administrators グループのメンバを指定してはいけません。もしアカウントを作っていないなら、インストーラはアカウントを作成することができます。アカウント名とパスワードを入力してください。パスワード欄を空欄にしておくとパスワードを自動生成します。
アカウントの生成機能を使うのは問題ないが、パスワードは自動生成に頼らない方がいい。自動生成は強固なパスワードを生成してはくれるのだが、'Xnd|)p_O|IL!_?=>BZwRF).voXxaIyP' なんてパスワードが設定されるし、生成されたパスワードはメッセージダイアログで表示されるのでコピー & ペーストすることが困難。パスワードはあらかじめ十分強固なものを決めておく方がいい。
ちなみに、指定したパスワードが弱そうな場合は以下のよう警告される。
The password you specified appears weak. Would you like the installer to replace it with a random password?「指定されたパスワードは弱いようです。ランダムなパスワードで置き換えますか?」といった内容だ。実に至れり尽くせりだ。
前置きが長くなったが、Service configuration 画面での設定項目をメモ。
まず、Windows のサービスとして動かしたいので、Install as a service のチェックボックスはオン。
Service nameService name は Windows サービスとして登録するときのサービス名。デフォルトの PostgreSQL Database Server 8.0 のままにした。
Account nameAccount name はサービスを起動するアカウント名。注意書きにもあったように、Administrators グループのメンバーを起動アカウントとして使うことはセキュリティ的にやってはいけないこと。起動アカウントがなければインストーラがアカウントを作ってくれる。
今回はデフォルトの postgres のままとし、インストーラにサービス起動用アカウントを作ってもらうことにした。
Account domainAccount domain はサービス起動アカウントが属する Windows ドメイン。私が属するデフォルトの develop のままにした。
Account passwordAccount password はサービス起動用アカウントのパスワード。私はあらかじめ決めておいた十分な長さとランダムネスを持つ文字列を指定した。
Verify passwordVerify password はパスワードの確認用入力欄。
項目を入力して次に進もうとすると、以下の確認が来た。develop\postgres というアカウントは存在しないみたいだけど、作る? という内容。もちろん作ってもらった。
User 'develop\postgres' was not found. Would you like the account to be created for you?
- Initialize database cluster データベースクラスタの初期化
要するに Unix 版でもおなじみの initdb 周りの設定。初期化したいので、Initialize database cluster のチェックボックスはオン。
Port number はデフォルトの 5432。
Locale と Encoding の設定はちょっと迷った。でも、この設定については過去に Postgres のメーリングリストの記事をメモした覚えがある。ChangeLog メモを検索、と。あった。2002-09-12 の「PostgreSQL7.3 以降の configure オプション」だ。この知識は 8.0 でも有効なのかな? そういえば Unicode が見あたらないけど、例によって ClientEncoding で対処するんだろうか? とりあえずメモに従って Locale は C 、Encoding は EUC_JP を選択した。
□ Accept connections on all addreses, not just localhost上記は接続許可の設定。localhost 以外からの接続は必要ないのでチェックはオフのまま。
あとは、Postgres スーパーユーザのユーザ名とパスワードの入力欄。Postgres スーパーユーザアカウントはサービス起動アカウントとは別物。以下の注意書きにもあるように、セキュリティ的な理由からサービス起動アカウントとスーパーユーザアカウントのパスワードは同じものを使わないこと。
This is the internal database username, and not the service account. For security reasons, the password should NOT be the same as the service account.
- Select procedural languages to enable in the default database ストアドや拡張用言語の選択
ストアドや拡張を書くときに使える言語を選択できる。私の環境では以下の三つが選択可能になっている。PL/pgsql だけかと思ったら、Perl も使えるようだ。ちょっと意外。私のマシンには ActivePerl が入ってるから? それとも常に有効なのかな?Select procedural languages to enable in the default database
□ PL/pgsql
□ PL/perl
□ PL/perl (untrusted)
- Enable contrib modules その他寄贈されたモジュール
その他寄贈されたモジュール群をインストールするかどうか選択する。Enable contrib modules
Contrib modules provide additional, often specialised, functionality. Select those you wish to install in the default template database. All files will be installed so modules may be added later simply by executing the appropriate SQL script.
□ B-Tree GiST
□ Chkpass
□ Cube
□ DBlink
□ DBsize
□ Earth Distance
□ Fuzzy String Match
□ Integer Aggregator
□ Integer Array
□ ISBN and ISSN
□ Large Objects (lo)
□ L-Tree
□ Misc. Utilities
□ No Update
□ Trigram Matching
□ pgAdmin Support
□ Crypto. Functions
□ PGStatTuple
□ R-Tree GiST
□ SEG
□ AutoInc
□ Insert Username
□ ModDateTime
□ RefInt
□ Time Travel
□ String IO
□ Table Functions
□ TSearch2
□ User Lock
Deprecated modules:
□ Full Text Index
□ TSearch
DBSize と pgAdmin Support には最初からチェックが付いている。いくつか興味を引かれるものはあるけど、まずはとりあえずデフォルトのままインストールしてみる。
- PostgreSQL is now ready to be installed インストール準備完了
PostgreSQL is now ready to be installed. Click Next to complete the installation.
上記メッセージが出たらインストール準備完了。Next を押してあとはインストールが終わるのを待つだけ。
- Installation complete! インストール完了
以下のメッセージが出たら無事インストール完了。Installation complete!
Congratulations, PostgreSQL has been successfully installed on your system.
We recommend that you subscribe to the pgsql-announce mailinglist to receive information about new releases and bugfixes.
Click the finish button to exit from the installer.
ちなみに、Subscribe to pgsql-announce のボタンははクリックすると Posgres のアナウンス用メーリングリストの購読申し込み画面 http://mail.postgresql.org/mj/mj_wwwusr?domain=postgresql.or ... をブラウザで開きにいく。とりあえず不要なので購読はしない。
- タスクマネージャを見るといくつか postgres 関連のプロセスが動いている
タスクマネージャを見てみると、postmaster.exe と postgres.exe と pg_ctl.exe が動作中。- PostgreSQL 8.0 のインストールは実に簡単
うーん、実に簡単だったなあ。ねむくなってきたので今日はここまで。次は pgAdmin を使ってみたり、.NET 用のドライバを使って C# から接続してみたりするとしよう。* ナチュラルキーよりサロゲートキー
この記事の直リンクURL: Permlink | この記事が属するカテゴリ: [SQL] [Postgres] [MS SQL Server]
RDBMS における主キーや参照整合性制約の外部キーは、ナチュラルキーよりもサロゲートキーを使う方がより変更に強くなる。
要するに、顧客コードとは別にシステムで振り出す ID を格納するカラムを作れということ。参照整合性制約を作成するときにも、サロゲートキーの方を使う。
Web+DB Press の Vol.21 に詳しく書いてある。
顧客コードのフォーマットは変わるかもしれないから。変わってしまった場合、DB の再設計が必要だったり、データの整合性が失われたり、過去のデータとの比較ができなくなったりする。
それ以後、顧客コードなどがあってもシステム側で振り出すユニークな ID を格納するカラムを使うようになった。
- ナチュラルキー
顧客コードなどの、ビジネスにおいて自然に発生するキー。自然キーともいう。- サロゲートキー
レコードを一意に特定するためにシステムが振り出すキー。アイデンティファイア (Identifier) ともいう。Postgres だったらシリアル型、MS SQL Server だったら IDENTITY を使うのが簡単。要するに、顧客コードとは別にシステムで振り出す ID を格納するカラムを作れということ。参照整合性制約を作成するときにも、サロゲートキーの方を使う。
- なぜサロゲートキーを使う方が良いのか
Web+DB Press の Vol.21 に詳しく書いてある。
顧客コードのフォーマットは変わるかもしれないから。変わってしまった場合、DB の再設計が必要だったり、データの整合性が失われたり、過去のデータとの比較ができなくなったりする。
- システム側で振り出したキーを使えと教えられたなあ
そういえば DB 設計をし始めた頃、「システム側で必ずキーを振り出せ」と尊敬する先輩から教えられたなあ。そのときはサロゲートキーという言葉ではなく、「システム側で振り出すキー」という表現だったけど。それ以後、顧客コードなどがあってもシステム側で振り出すユニークな ID を格納するカラムを使うようになった。
- 参考
このメモは L'eclat des jours(2005-01-07) http://arton.no-ip.info/diary/20050107.html#p01 に触発されて書いた。* DATETIME型/TIMESTAMP型の展開と WHERE句の範囲指定
この記事の直リンクURL: Permlink | この記事が属するカテゴリ: [SQL] [MS SQL Server] [Postgres]
時刻の扱いは データベースエンジンによって異なるので、クエリを作成する前に仕様や挙動を確認しておきたい。
たとえば、 time_column < '2004-08-27' のとき、'2004-08-27' は いつの時点を指すのか。2004-08-27 00:00:00 なのか、 2004-08-27 **:**:** 、つまりランダムなのか。いつもは時分秒まで指定していたので、省略して表記した場合はどうなるか調べておこう。
http://www.microsoft.com/japan/msdn/library/ja/acdata/ac_8_c ...
要するに SQL Server2000 では、00:00:00 になるってことか。
日本PostgreSQLユーザー会: PostgreSQL 7.2.X 付属ドキュメント
http://www.postgresql.jp/document/pg721doc/
7.4 系列の文書も見てみたが、やはり明確な記述は見つけられなかった。
日本PostgreSQLユーザ会: PostgreSQL 7.4.X 付属ドキュメント
http://www.postgresql.jp/document/pg743doc/
まあ、この後やってみればわかるだろう。たぶん SQL Server2000 と同じ結果になると思うけど。
PostgreSQL 7.2.1 用。
結論から言うと、SQL Server2000 と PostgreSQL 7.2 ともに 'YYYY-MM-DD' は 'YYYY-MM-DD 00:00:00:000' に展開される。以下、サンプル。
PostgreSQL 7.2.1 でも SQL Server2000 でも同じ結果になった。以下、Postgres の出力結果。
さっきのテーブルを DROP して CREATE しなおし、8レコード分のテストデータを INSERT する。
INSERT が終わったら SELECT してみる。今度は SQL Server2000 での出力。
予想通り、2004-08-26 は 2004-08-26 00:00:00 に展開された。
イコールを付ければ8/26のレコードもヒット。
Postgres でも同じように動作した。
たとえば、 time_column < '2004-08-27' のとき、'2004-08-27' は いつの時点を指すのか。2004-08-27 00:00:00 なのか、 2004-08-27 **:**:** 、つまりランダムなのか。いつもは時分秒まで指定していたので、省略して表記した場合はどうなるか調べておこう。
- SQL Server2000 の場合
日付時刻データの使用http://www.microsoft.com/japan/msdn/library/ja/acdata/ac_8_c ...
時刻だけまたは日付だけを個別に格納するデータ型はありません。datetime 型または smalldatetime 型の値を設定する場合、時刻だけを指定すると、日付のデフォルト "January 1, 1900" が使用されます。日付だけを指定すると、時刻のデフォルト "12:00AM (深夜)" が使用されます。
要するに SQL Server2000 では、00:00:00 になるってことか。
- PostgreSQL 7.2.1 の場合。
ドキュメントは見つけられなかった。日本PostgreSQLユーザー会: PostgreSQL 7.2.X 付属ドキュメント
http://www.postgresql.jp/document/pg721doc/
7.4 系列の文書も見てみたが、やはり明確な記述は見つけられなかった。
日本PostgreSQLユーザ会: PostgreSQL 7.4.X 付属ドキュメント
http://www.postgresql.jp/document/pg743doc/
まあ、この後やってみればわかるだろう。たぶん SQL Server2000 と同じ結果になると思うけど。
- CREATE TABLE
SQL Server2000 用。CREATE TABLE time_where_test (utime datetime);
PostgreSQL 7.2.1 用。
CREATE TABLE time_where_test (utime timestamp);
- INSERT 時の展開
まずは INSERT のテスト。結論から言うと、SQL Server2000 と PostgreSQL 7.2 ともに 'YYYY-MM-DD' は 'YYYY-MM-DD 00:00:00:000' に展開される。以下、サンプル。
PostgreSQL 7.2.1 でも SQL Server2000 でも同じ結果になった。以下、Postgres の出力結果。
hiroaki=> INSERT INTO time_where_test VALUES ('2004-06-18');
INSERT 93862442 1
hiroaki=> SELECT * FROM time_where_test;
utime
---------------------
2004-06-18 00:00:00
(1 row)
- SELECT 時の展開
今度は SELECT 時のテスト。おそらく INSERT 時と同じように展開されるだろうけど、念のため。さっきのテーブルを DROP して CREATE しなおし、8レコード分のテストデータを INSERT する。
INSERT INTO time_where_test VALUES ('2004-08-09 02:00:00');
INSERT INTO time_where_test VALUES ('2004-08-20 03:00:00');
INSERT INTO time_where_test VALUES ('2004-08-26 00:00:00');
INSERT INTO time_where_test VALUES ('2004-08-26 04:00:00');
INSERT INTO time_where_test VALUES ('2004-08-26 23:59:59');
INSERT INTO time_where_test VALUES ('2004-08-27 00:00:00');
INSERT INTO time_where_test VALUES ('2004-08-27 09:00:00');
INSERT INTO time_where_test VALUES ('2004-08-27 23:59:59');
INSERT が終わったら SELECT してみる。今度は SQL Server2000 での出力。
SELECT * FROM time_where_test WHERE utime < '2004-08-26' ORDER BY utime;
utime
------------------------------------------------------
2004-08-09 02:00:00.000
2004-08-20 03:00:00.000
(2 件処理されました)
予想通り、2004-08-26 は 2004-08-26 00:00:00 に展開された。
イコールを付ければ8/26のレコードもヒット。
SELECT * FROM time_where_test WHERE utime <= '2004-08-26' ORDER BY utime;
utime
------------------------------------------------------
2004-08-09 02:00:00.000
2004-08-20 03:00:00.000
2004-08-26 00:00:00.000
(3 件処理されました)
Postgres でも同じように動作した。
確かに PostgreSQL 7.5 の変更点は大物揃いだ。PosgreSQL 7.2 に匹敵する、大幅なレベルアップだ。ちなみに Postgres 7.2 では、運用しながら vacuum できる concurrent vacuum とTOAST による 1レコード 8KB 制限の撤廃が行われた
postgres 7.2 でWAL (Write Ahead Log) には対応してたが、undo ができなかった。7.5 では PITR (ポイント・イン・タイム・リカバリ) に対応するので undo が可能になる。そして、とうとう Postgres が Windows に対応。cygwin や PowerGres を使わなくても動くようになれば、MySQL 対抗の選択肢が一つ増える。Nested Transaction 対応はあまり使わないから気にならないけど。
[pgsql-jp: 33761] Re: シーラカンス本第4版
http://ml.postgresql.jp/pipermail/pgsql-jp/2004-July/017321. ...
[pgsql-jp: 33872] Fw: [ANNOUNCE] PostgreSQL 8.0.0 Officially Goes Beta
http://ml.postgresql.jp/pipermail/pgsql-jp/2004-August/01743 ...
postgres 7.2 でWAL (Write Ahead Log) には対応してたが、undo ができなかった。7.5 では PITR (ポイント・イン・タイム・リカバリ) に対応するので undo が可能になる。そして、とうとう Postgres が Windows に対応。cygwin や PowerGres を使わなくても動くようになれば、MySQL 対抗の選択肢が一つ増える。Nested Transaction 対応はあまり使わないから気にならないけど。
[pgsql-jp: 33761] Re: シーラカンス本第4版
http://ml.postgresql.jp/pipermail/pgsql-jp/2004-July/017321. ...
> >>ずっと将来構想に入っている WAL からの復元機能と合わせて、期待ですね。
> >
> > これが次の7.5(8/1からベータテスト開始予定)にほぼ間違いなく入りそうです.
> >
>
> 情報ありがとうございます。
> この機能が最も導入時に問題視されているので
> 大変な貴重な情報です。
> 楽しみに待っております!
> 7.5はいつ頃リリースされそうでしょうか?
早ければ年内という話もありますが,個人的には結構今回はベータが長引くの
ではないかと思っています.というのも,PITR以外にも,
NT(Nested Transaction)
table space
Win32ネィティブ対応
といった大物が7.5には含まれており,しかもその変更がデータベースエンジ
ンの心臓部に渡っているからです.
# 後,あんまり表には出ない改良点ですが,background writer processとか,
# ARCによるバッファ管理とかも,実際にはかなりクリティカルな変更です.
- 2004/08/12 追記
7.5 は 8.0.0 となった模様。[pgsql-jp: 33872] Fw: [ANNOUNCE] PostgreSQL 8.0.0 Officially Goes Beta
http://ml.postgresql.jp/pipermail/pgsql-jp/2004-August/01743 ...
夜間バッチ用の Perl スクリプトがうまく動かず、意図した結果にならないという相談を受けた。
テーブルのデータを洗い替えするため、TRUNCATE した後に CSV から読み込んだデータを INSERT していくという Perl スクリプトにおいて、洗い替えがなされないという症状だ。DB は Postgres。 バージョンは未確認だが、7.1 または 7.0 系列だったはず。DB 接続には Pg モジュールを使用。
スクリプトを見たところ、どうも TRUNCATE がうまくいってないような感じがした。スクリプトでは TRUNCATE を実行したときの結果をチェックしていないので、成功しても失敗してもその後の CSV からの INSERT を実行してしまうようだ。Google で TRUNCATE エラー postgres を検索すると、Postgres のメーリングリストの記事がヒット。
[pgsql-jp 21028] TRUNCATE 実行権を与える方法
http://ml.postgresql.jp/pgsql-jp-old/pgsql-jp/2001May/msg000 ...
権限の問題の可能性あり。
psql で試してみた。GRANT ALL してもらってるテーブルに対して TRUNCATE を発行する。
PostgreSQL 7.1.3 ドキュメント(日本語版 1.6) には所有権が必要っていう記述はなかった。
http://osb.sra.co.jp/PostgreSQL/Manual/PostgreSQL-7.1-ja/sql ...
最新の 7.4.2 のドキュメントには参照整合性制約についての記述はあったが、権限についての記述はない。
PostgreSQL 7.4.2 リファレンス TRUNCATE
http://www.postgresql.jp/document/pg742doc/html/sql-truncate ...
テーブルのデータを洗い替えするため、TRUNCATE した後に CSV から読み込んだデータを INSERT していくという Perl スクリプトにおいて、洗い替えがなされないという症状だ。DB は Postgres。 バージョンは未確認だが、7.1 または 7.0 系列だったはず。DB 接続には Pg モジュールを使用。
スクリプトを見たところ、どうも TRUNCATE がうまくいってないような感じがした。スクリプトでは TRUNCATE を実行したときの結果をチェックしていないので、成功しても失敗してもその後の CSV からの INSERT を実行してしまうようだ。Google で TRUNCATE エラー postgres を検索すると、Postgres のメーリングリストの記事がヒット。
[pgsql-jp 21028] TRUNCATE 実行権を与える方法
http://ml.postgresql.jp/pgsql-jp-old/pgsql-jp/2001May/msg000 ...
標題の件ですが、TRUNCATEを実行する権限を
テーブル所有者以外に与える方法はないでしょうか。
GRANT ALL ON [テーブル名] TO [与えたいユーザー ]
ではTRUNCATE実行時に"所有権がない"旨のエラーがでます。
現在はやむを得ずDELETE文を使用していますが
ロールバックが必要になる処理ではないので、
可能であればTRUNCATEを使いたいと思っています。
PostgreSQL 7.0.3 on Vine LINUX 2.1.5
権限の問題の可能性あり。
psql で試してみた。GRANT ALL してもらってるテーブルに対して TRUNCATE を発行する。
hiroaki=> TRUNCATE TABLE the_world;あ、やっぱりダメだ。
ERROR: you do not own class "the_world"
hiroaki=> DELETE FROM the_world ;DELETE は問題なくできる。
DELETE 5
PostgreSQL 7.1.3 ドキュメント(日本語版 1.6) には所有権が必要っていう記述はなかった。
http://osb.sra.co.jp/PostgreSQL/Manual/PostgreSQL-7.1-ja/sql ...
最新の 7.4.2 のドキュメントには参照整合性制約についての記述はあったが、権限についての記述はない。
PostgreSQL 7.4.2 リファレンス TRUNCATE
http://www.postgresql.jp/document/pg742doc/html/sql-truncate ...
Postgres の入門書である「シーラカンス本」の改訂第4版。ターゲットとなるバージョンは 7.4.2。
amazon にはまだ登録されていないけど、bk1 にはすでにデータがあった。
http://www.bk1.co.jp/cgi-bin/srch/srch_result_book.cgi?aid=p ...
未だに7.2 系列の Postgres を使ったシステムも動いてるけど、安定しすぎちゃってまったく手がかからない。激しいトランザクションがある訳でもないし、データの増加は月あたり10万件くらいしかないからかな。セキュリティホールとか致命的なデータ破壊エラーが無いのであればバージョンアップする理由もない。
[pgsql-jp: 33045] シーラカンス本第4版
http://ml.postgresql.jp/pipermail/pgsql-jp/2004-May/008187.h ...
PostgreSQL 7.4.2対応ですので,7.4の機能についてあれこれ書いた結果,特
に3章が膨らんでしまいました.また,5章もチューニングなどで量が増えてし
まいました.そこで第4章のサンプルをダイエットしました.取り上げた言語
はPHPとPerlのみ,どちらもシンプルな共通のデータベースを使ったWenアプリ
ケーションです.PHPの方は,PHP+PEAR+Smartyという今流行のコンビ.Perlの
方は,DBI+DBD-PgにHTML::Templateを組み合わせています.この結果は,トー
タルでなんとか418ページに収まりました.
発売は6/28です.それと,なんと今回シーラカンスのフィギュアが限定でおま
けについています:-)企画的には大変だったと思いますが,ご尽力いただいた
技術評論社の関係の方々に感謝しています.
フィギュアのもらい方:-)その他詳細については,
http://www2b.biglobe.ne.jp/~caco/fourth_edition/index.html
「改訂第4版・PostgreSQL 完全攻略ガイド」サポートページ
http://www2b.biglobe.ne.jp/~caco/fourth_edition/
以下から予約や購入をすると,限定シーラカンスフィギュアがもらえる特典が付いていますまるでダイドー の MIU の「深海生物コレクション」みたいなフィギュアだ。フィギュアプレゼント対象店に bk1 も入ってるみたいだし、次に Postgres を使ったシステムを作るときに買おう。
Ruby で DB を扱う必要が出てきたので環境整備。本当を MySQL を使いたいのだが、サーバに MySQL が入っていない。使い慣れた PostgreSQL でもいいかな、と思ったので Postgres 環境を整備。
Google で ruby postgres を検索したらヒット。
Postgres(Ruby PostgreSQL 拡張モジュール)
http://www.postgresql.jp/interfaces/ruby/index-ja.html
テストデータを100件 INSERT。100 回 psql を呼んでるので遅いけど気にしない。
SELECT 文を投げて、レコードの件数をカウント。この程度ならワンライナーで書いた方が早い。
よしよし、ばっちり接続できてるね。
- Postgres 接続用ライブラリはいずこに?
/usr/local/lib/ruby を探してみたが、postgres 関連のライブラリは無いようだ。Google で ruby postgres を検索したらヒット。
Postgres(Ruby PostgreSQL 拡張モジュール)
http://www.postgresql.jp/interfaces/ruby/index-ja.html
- インストール
ruby-postgres-0.7.1.tar.gz をダウンロードして、展開。ruby extconf.rb --with-pgsql-include-dir=/usr/local/pgsql/include --with-pgsql-lib-dir=/usr/local/pgsql/libで configure。あとは make して make install でインストール完了。実に簡単。
- ruby から接続できるかテスト
テストテーブルを作成。$ psql -c 'create table test1 (num int);'
テストデータを100件 INSERT。100 回 psql を呼んでるので遅いけど気にしない。
$ for i in `seq 1 100`; do psql -c "INSERT INTO test1 (num) VALUES ($i);"; done
SELECT 文を投げて、レコードの件数をカウント。この程度ならワンライナーで書いた方が早い。
$ ruby -e 'require "postgres"; conn = PGconn.connect("localhost", 5432, "", "", "hiroaki"); res = conn.exec("select * from test1;"); p res.num_tuples;'
100
よしよし、ばっちり接続できてるね。
- 今回作業した環境
$ ruby -v
ruby 1.8.1 (2003-12-25) [i586-linux]
$ psql -V
psql (PostgreSQL) 7.2.1
Postgres は MVCC というシステムを採用している。
MVCC は多版方式 (多版型同時実行制御 (Multiversion Concurrency Control) MVCC) の頭文字。
MVCC の特徴は、トランザクションはスナップショットを参照する、という点だ。
Chapter 9. 同時実行制御 PostgreSQL 7.3.4 ユーザガイド
http://www.postgresql.jp/document/pg734doc/user/mvcc.html
9.4. アプリケーションレベルでのデータの一貫性チェック PostgreSQL 7.3.4 ユーザガイド
http://www.postgresql.jp/document/pg734doc/user/applevel-con ...
T1: BEGIN TRANSACTION;
T1: SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
T2: BEGIN TRANSACTION;
T2: SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-- まず T1 が一行 INSERT し、行数を取得する。
T1: INSERT INTO test (time_str) VALUES (CURRENT_TIMESTAMP);
T1: SELECT count(*) FROM test;
-- 次に、T2 が全行を削除してしまう。
-- SELIALIZABLE なので、MVCC を採用していないシステムでは、
-- ここで T2 が待たされるが、Postgres では待ちが発生しない。
T2: DELETE FROM test;
-- T2 の count の結果は当然 0 になる。
T2: SELECT count(*) FROM test;
-- T1、T2ともに問題なく COMMIT できてしまう。
T1: COMMIT;
T2: COMMIT;
さて、トランザクションが終わったあとに count はいくつになるだろうか?
T2 が DELETE で全行を削除したので、答えは0と思うかもしれないが、正解は1だ。
T2 が DELETE によって削除したのは、テーブルの全行であるが、
そのテーブルの内容は T2 のトランザクションが開始した時点のものである。
そのため、トランザクション開始後に T1 によって INSERT された行は削除されない。
結果、1行だけ残る。
MVCC を採用していないデータベースでは、SERIALIZABLE であれば 0 行となるだろう。
「これでは SERIALIZABLE の意味がない」と思うかもしれないが、
SERIALIZABLE の仕様としてはこれで正しいようだ。
もちろん、同じ行を同時に更新や削除しようとした場合には、
SERIALIZABLE を維持できなくなるため、
MVCC の優れた同時実行性を使いたくない場合は、明示的にテーブルをロックする必要がある。
MS のセミナーの講師が言っていたが、次期 SQL Server の Yukon では、MVCC を採用する予定だそうだ。
MVCC は多版方式 (多版型同時実行制御 (Multiversion Concurrency Control) MVCC) の頭文字。
MVCC の特徴は、トランザクションはスナップショットを参照する、という点だ。
Chapter 9. 同時実行制御 PostgreSQL 7.3.4 ユーザガイド
http://www.postgresql.jp/document/pg734doc/user/mvcc.html
9.4. アプリケーションレベルでのデータの一貫性チェック PostgreSQL 7.3.4 ユーザガイド
http://www.postgresql.jp/document/pg734doc/user/applevel-con ...
- 実験
-- まず2つのトランザクションを SERIALIZABLE で開始する。T1: BEGIN TRANSACTION;
T1: SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
T2: BEGIN TRANSACTION;
T2: SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-- まず T1 が一行 INSERT し、行数を取得する。
T1: INSERT INTO test (time_str) VALUES (CURRENT_TIMESTAMP);
T1: SELECT count(*) FROM test;
-- 次に、T2 が全行を削除してしまう。
-- SELIALIZABLE なので、MVCC を採用していないシステムでは、
-- ここで T2 が待たされるが、Postgres では待ちが発生しない。
T2: DELETE FROM test;
-- T2 の count の結果は当然 0 になる。
T2: SELECT count(*) FROM test;
-- T1、T2ともに問題なく COMMIT できてしまう。
T1: COMMIT;
T2: COMMIT;
さて、トランザクションが終わったあとに count はいくつになるだろうか?
T2 が DELETE で全行を削除したので、答えは0と思うかもしれないが、正解は1だ。
T2 が DELETE によって削除したのは、テーブルの全行であるが、
そのテーブルの内容は T2 のトランザクションが開始した時点のものである。
そのため、トランザクション開始後に T1 によって INSERT された行は削除されない。
結果、1行だけ残る。
MVCC を採用していないデータベースでは、SERIALIZABLE であれば 0 行となるだろう。
「これでは SERIALIZABLE の意味がない」と思うかもしれないが、
SERIALIZABLE の仕様としてはこれで正しいようだ。
もちろん、同じ行を同時に更新や削除しようとした場合には、
SERIALIZABLE を維持できなくなるため、
ERROR: Can't serialize access due to concurrent updateのエラーとなる。ちなみに、最近のバージョンの Postgres、少なくとも Postgres 8.0 では "could not serialize access due to concurrent update" にメッセージが変更されたようだ。
MVCC の優れた同時実行性を使いたくない場合は、明示的にテーブルをロックする必要がある。
MS のセミナーの講師が言っていたが、次期 SQL Server の Yukon では、MVCC を採用する予定だそうだ。
[pgsql-jp: 31147] Re: MAX関数が遅い。
http://ml.postgresql.jp/pipermail/pgsql-jp/2003-September/00 ...
max() はシーケンシャルスキャンになってしまうが、ORDER BY と LIMIT を使うことで
インデックススキャンできる。
http://ml.postgresql.jp/pipermail/pgsql-jp/2003-September/00 ...
max() はシーケンシャルスキャンになってしまうが、ORDER BY と LIMIT を使うことで
インデックススキャンできる。
select mas_no from g_master order by mas_no desc offset 0 limit 1;
Limit (cost=0.00..3.24 rows=1 width=4)
-> Index Scan Backward using g_master_pkey on g_master (cost=0.00..166442.75 rows=51427 width=4)
.Net で postgres を使うためのライブラリ。
The npgsql Project -- .Net Data Provider for PostgreSQL
http://gborg.postgresql.org/project/npgsql/projdisplay.php
LGPL の模様。
PostgreSQLDirect .NET Data Provider
http://crlab.com/pgsqlnet/
商用製品で、standard 版が99ドル。
The npgsql Project -- .Net Data Provider for PostgreSQL
http://gborg.postgresql.org/project/npgsql/projdisplay.php
LGPL の模様。
PostgreSQLDirect .NET Data Provider
http://crlab.com/pgsqlnet/
商用製品で、standard 版が99ドル。
* SQL の COALESCE
この記事の直リンクURL: Permlink | この記事が属するカテゴリ: [SQL] [Postgres] [MS SQL Server]
COALESCE() は、引数のうち NULL でないものを返す。CASE や NULLIF を使っても同じことができるけど、こっちの方が簡潔。可変長の複数の引数を指定できて便利。
http://www.postgresql.jp/document/pg734doc/user/functions-co ...
COALESCE
http://www.microsoft.com/japan/msdn/library/ja/tsqlref/ts_ca ...
COALESCE の発音は「こぅあれす」なんだけど、「す」のところが SCE になっていることが覚えられない原因だと思う。最初は「こぉりーす」と誤読していたこともスペルミスの原因かも。
coalesce goo 英和辞典
http://dictionary.goo.ne.jp/search.php?MT=coalesce&kind= ...
- COALESCE リファレンス
PostgreSQL 7.3.4 ユーザガイド Chapter 6. 関数と演算子 条件式http://www.postgresql.jp/document/pg734doc/user/functions-co ...
6.12.2. COALESCE
COALESCE(value [, ...])
COALESCE 関数は、NULL でない自身の最初の引数を返します。 データを表示の目的で取り出す際、NULL 値の代わりにデフォルト値を使う場合、時として便利なことがあります。 その例です。
SELECT COALESCE(description, short_description, '(none)') ...
COALESCE
http://www.microsoft.com/japan/msdn/library/ja/tsqlref/ts_ca ...
- COALESCE のスペルが覚えられない
ところで、私は COALESCE のスペルがなぜか覚えられないため、この記事を書いた。COLESE とか COALESE とか COLESCE などと書いてしまい、文法エラーになることが多かった。最近では MS SQL Server 付属のクエリアナライザで SQL を書くようになり、キーワード色づけの恩恵を受けるようになったため間違いが減ったけど。それでも時々忘れることがあって、そのときはクエリアナライザの顔色を伺いながらタイプしている。キーワードに色が付いたら正解スペル、色が付かなかったら間違いスペルだ。まさに顔色を伺ってる感じだ。COALESCE の発音は「こぅあれす」なんだけど、「す」のところが SCE になっていることが覚えられない原因だと思う。最初は「こぉりーす」と誤読していたこともスペルミスの原因かも。
coalesce goo 英和辞典
http://dictionary.goo.ne.jp/search.php?MT=coalesce&kind= ...
特集:第1回 PostgreSQLで学ぶSQLデータベースの操作
http://www.itmedia.co.jp/enterprise/0307/18/epn20.html
Tomcat(JSP)との連携も解説する予定だそうな。
http://www.itmedia.co.jp/enterprise/0307/18/epn20.html
Tomcat(JSP)との連携も解説する予定だそうな。
【連載 】PostgreSQL パフォーマンスチューニング
https://www.stackasterisk.jp/tech/dataBase/postgresTuning01_ ...
https://www.stackasterisk.jp/tech/dataBase/postgresTuning01_ ...
ftp://ftp.sra.co.jp/pub/cmd/postgres/pgpool/
[pgsql-jp: 30256] PostgreSQL用コネクションプールサーバ pgpool
http://ml.postgresql.jp/pipermail/pgsql-jp/2003-June/005398. ...
pgpool page
http://www2b.biglobe.ne.jp/~caco/pgpool/
[pgsql-jp: 30256] PostgreSQL用コネクションプールサーバ pgpool
http://ml.postgresql.jp/pipermail/pgsql-jp/2003-June/005398. ...
pgpool page
http://www2b.biglobe.ne.jp/~caco/pgpool/
PostgreSQL 7.3.2 付属ドキュメント
http://www.postgresql.jp/document/pg732doc/
[pgsql-jp: 29996] 7.3.2 ドキュメント より。
http://www.postgresql.jp/document/pg732doc/
[pgsql-jp: 29996] 7.3.2 ドキュメント より。
vacuumdb に --analyze オプションを付けると analyze しかやってくれないという説をどこかで読んだ気がするので調査。
http://www.postgresql.jp/document/pg721doc/reference/app-vac ... の
使用例に以下のような記述があったので、少なくとも 7.2.1 ではそんなことはないらしい。
http://www.postgresql.jp/document/pg721doc/reference/app-vac ... の
使用例に以下のような記述があったので、少なくとも 7.2.1 ではそんなことはないらしい。
bigdbというデータベースの掃除とオブティマイザ用の解析を行なう場合には下記のコマンドを実行します。
$ vacuumdb --analyze bigdb
postgres の pg_dump のデータが溜まりすぎて、DAT にバックアップできなくなっていた。
2002-09-11 に書いた Postgres バックアップスクリプトに n 日以前のファイルを消すという処理を追加し、以下のようにした。また、バックアップ対象 DB を psql -l から取得するようにした。
pg_dumpall を使っていないのは、ラージオブジェクトを扱うためと、データベース毎にバックアップファイルを分けたかったから。
動作を確認した環境は PostgreSQL 7.2.1 + TurboLinux 6.5 Server だ。凝ったことはしていないので、バージョンが異なっても動くはずだ。cron に仕込んで夜間バッチなどで動かすときは、postgres 関連コマンドやディレクトリへのパスを設定するのを忘れずに。以下のスクリプトでは、 # Setting の部分で 環境変数を設定している。
私はこのスクリプトを postgres スーパーユーザの crontab に仕込んで毎日実行している。postgres スーパーユーザ以外で動かすこともできるとは思うが、データベースにアクセスするためにパスワードを要求されたりするかもしれず、いろいろ手間がかかりそうな予感。管理者権限を使いたくないという意見もあるかもしれないが、バックアップというのは本来管理者やオペレータが行う作業だし、素直に postgres スーパーユーザで実行してしまった方が楽だ。
「一般ユーザとして全部のデータベースをバックアップする」という状況ってあまり考えられない。どうしても管理者権限を使いたくないなら、以下のオプションを使ってできるんじゃないかと思う。試してないけど。
2002-09-11 に書いた Postgres バックアップスクリプトに n 日以前のファイルを消すという処理を追加し、以下のようにした。また、バックアップ対象 DB を psql -l から取得するようにした。
pg_dumpall を使っていないのは、ラージオブジェクトを扱うためと、データベース毎にバックアップファイルを分けたかったから。
動作を確認した環境は PostgreSQL 7.2.1 + TurboLinux 6.5 Server だ。凝ったことはしていないので、バージョンが異なっても動くはずだ。cron に仕込んで夜間バッチなどで動かすときは、postgres 関連コマンドやディレクトリへのパスを設定するのを忘れずに。以下のスクリプトでは、 # Setting の部分で 環境変数を設定している。
#/bin/sh
# PostgreSQL database backup script
# Version 1.1 [Apr. 17, 2002] Add routine: deleting exipired files.
# Version 1.0 [Sep. 10, 2002] First release.
# Saito Hiroaki <example@example.com>
# * Feature
# Dump to DATABASE_NAME_YYMMDD.pgdmp.
# Delete expired pgdmp file.
# Output log.
# Setting
PATH="$PATH":/usr/local/pgsql/bin
PG=/usr/local/pgsql
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH":$PG/lib
export PGLIB=$PG/lib
export PGDATA=$PG/data
# Get all DB name
TARGET_DB=`psql -l -P format=unaligned -P fieldsep=, -P tuples_only |perl -F, -lane "if (@F[0] ne 'template0') {print @F[0]}"`
DIR=/home/postgres
LOG=$DIR/pgdump.log
BACKUPDIR=$DIR/dbbackup
EXPIRE_DAY=90
# Main routine
echo "pg_dump start." `date` >>$LOG
date=`date +%Y%m%d`
for db_name in $TARGET_DB
do
DUMP_FILE_PATH=$BACKUPDIR/${db_name}_${date}.pgdmp
/usr/local/pgsql/bin/pg_dump $db_name -b -o -Fc > $DUMP_FILE_PATH 2>>$LOG
echo "Database $db_name backup complete." `date` >>$LOG
done
echo "pg_dump complete." `date` >>$LOG
echo "Delete expired pgdmp file start." `date` >>$LOG
find $BACKUPDIR -type f -daystart -mtime +$EXPIRE_DAY |xargs /bin/rm -f
echo "Delete expired pgdmp file complete." `date` >>$LOG
私はこのスクリプトを postgres スーパーユーザの crontab に仕込んで毎日実行している。postgres スーパーユーザ以外で動かすこともできるとは思うが、データベースにアクセスするためにパスワードを要求されたりするかもしれず、いろいろ手間がかかりそうな予感。管理者権限を使いたくないという意見もあるかもしれないが、バックアップというのは本来管理者やオペレータが行う作業だし、素直に postgres スーパーユーザで実行してしまった方が楽だ。
「一般ユーザとして全部のデータベースをバックアップする」という状況ってあまり考えられない。どうしても管理者権限を使いたくないなら、以下のオプションを使ってできるんじゃないかと思う。試してないけど。
-U, --username=NAME connect as specified database user
-W, --password force password prompt (should happen automatically)
2003-04-14 の ChangeLog について調査。
[pgsql-jp 23148] Re: VARCHAR(n)のn
http://ml.postgresql.jp/pgsql-jp-old/pgsql-jp/2001Sep/msg001 ...
http://ml.postgresql.jp/pgsql-jp-old/pgsql-jp/2001Sep/msg001 ...
http://www.postgresql.jp/document/pg721doc/user/datatype-cha ...
あ、Postgres については調べられたけど、MS SQL Server については調べてないな・・・。
- VARCHAR(n) の文字数とは、SQL92 の定義に則れば、
「処理系の定義する特定の文字集合」 の文字数である。- しかし、7.2 未満の Postgres は上記仕様を満たしていなかった。
7.2 からは上記の仕様に準拠するようになった。[pgsql-jp 23148] Re: VARCHAR(n)のn
http://ml.postgresql.jp/pgsql-jp-old/pgsql-jp/2001Sep/msg001 ...
もともとPostgreSQLのマルチバイト実装におい
ては,『処理系の定義する特定の文字集合』とは,データベースごとに決まる
エンコーディングです.日本のユーザならたいていEUC_JPでしょう.
- VARCHAR(n) の文字数とは直接の関係はないが、知っておくべき情報もいくつかあった。
- CHAR 型 はスペースでパディングされるために結構コストが高い。
[pgsql-jp 23075] Re: INSERT するときのサイズチェックhttp://ml.postgresql.jp/pgsql-jp-old/pgsql-jp/2001Sep/msg001 ...
char型の場合、たとえばCHAR(10)で確保した列に100万行を挿入す
れば、その列にどんな長さの文字列を挿入しようとも、きっちり10
バイト×行数(この場合には1000万バイト)の領域が必要になりま
す。しかし、varchar型やtext型の場合には、実際に挿入した文字列
の長さ+4バイトしか使いません。ですから、長さがまちまちである
文字列を保持するのであれば、varchar型やtext型の方がリーズナブ
ルなわけです。
- CAHR と VARCHAR の違いと文字列長超過時のエラー
PostgreSQL 7.2.3 ユーザガイド Chapter 3. データ型http://www.postgresql.jp/document/pg721doc/user/datatype-cha ...
SQL は 2 つの主要な文字データ型を定義しています。
character(n) と character varying(n) で、n は正の整数です。
これらのデータ型は 2 つとも長さにして n 文字分の文字列を保存できます。
超過している文字がすべてスペースの場合(この時は長さの限界で切り捨てられます)を除いて、
上限を越えた文字列をこの種の列に保存しようとするとエラーになります。
(この一風変わった例外は SQL 標準で要求されています。)
もし宣言された上限よりも文字列が短いときは character の値はスペースでパッドされ、
character varying の値は単により短く保存されます。
Note: PostgreSQL 7.2 以前では上限を越えた文字列は黙って切り捨てられエラーとはなりません。
あ、Postgres については調べられたけど、MS SQL Server については調べてないな・・・。
perl の join() のような処理をしてくれるストアドプロシージャを PL/PGSQL で作ってみた。ただ、カラム名をハードコーディングしなければならず、あまり使い勝手が良くない。ということで、以下のような質問を投げてみた。
PostgreSQL 2テーブル目
http://pc2.2ch.net/test/read.cgi/php/1047317680/56
PostgreSQL 2テーブル目
http://pc2.2ch.net/test/read.cgi/php/1047317680/56
PL/PGSQL で Perl の join 関数みたいなストアドを作りたいんだけど、
なんかもっとスマートな方法無いでしょうか?
結果レコードのカラム名を変数で指定できると嬉しいんだけど、
Postgres 7.2.1 では変数展開してくれませんでした。
-- SQL の結果レコードに指定した文字列を挟んで連結して返す
-- 引数1: 実行する SQL 文
-- 引数2: 挟み込む文字列
DROP FUNCTION join_str(TEXT, TEXT);
CREATE FUNCTION join_str(TEXT, TEXT) RETURNS TEXT AS '
declare
delimiter alias for $1;
sql alias for $2;
str text;
rec record;
is_first bool;
begin
is_first = true;
str := '''';
FOR rec IN EXECUTE sql LOOP
IF is_first THEN
str := rec.serialnum; -- カラム名を指定
is_first := false;
ELSE
str := str || delimiter || rec.serialnum; -- カラム名を指定
END IF;
END LOOP;
return str;
end;
' LANGUAGE 'plpgsql';
改訂第3版 PC UNIXユーザのためのPostgreSQL完全攻略ガイド、いわゆるシーラカンス本第3版 の35ページのコラム「1つのマシンで複数の PostgreSQL インストレーションを管理する方法」に書いてあった石井さんのやり方。この方法を使えば、異なるバージョンの postgres を同時起動したり、同じバージョンの複数の postgres を同時起動することができる。
ポイントは、ソースコード展開ディレクトリ、インストールディレクトリ、postmaster の待ち受けポートをすべて別にすること。インストールディレクトリや待ち受けポートは環境変数で指定できるの。この機能を利用して、異なる内容の .bashrc を用意しておいて必要に応じて source コマンドで環境変数を変えることで、異なる postgres を共存できるようにインストールし同時に起動することができる。
ちなみに、Postgres ではテーブルの集合をデータベースと呼び、データベースの集合をデータベースクラスタ、データベースインストレーション、インストレーションなどと呼ぶ。ちなみに MS SQL Server ではインスタンスと呼んでいた。
http://ml.postgresql.jp/pgsql-jp-old/pgsql-jp/2001Jun/msg000 ...
ポイントは、ソースコード展開ディレクトリ、インストールディレクトリ、postmaster の待ち受けポートをすべて別にすること。インストールディレクトリや待ち受けポートは環境変数で指定できるの。この機能を利用して、異なる内容の .bashrc を用意しておいて必要に応じて source コマンドで環境変数を変えることで、異なる postgres を共存できるようにインストールし同時に起動することができる。
PG=`pwd`
export PGPORT=10732
export PGLIB=$PG/lib
export PGDATA=$PG/data
export LD_LIBRARY_PATH=$PG/lib
PATH="$PG/bin":$PATH
ちなみに、Postgres ではテーブルの集合をデータベースと呼び、データベースの集合をデータベースクラスタ、データベースインストレーション、インストレーションなどと呼ぶ。ちなみに MS SQL Server ではインスタンスと呼んでいた。
- 参考
[pgsql-jp 21676] 異なるversion のPostgreSQL の使用http://ml.postgresql.jp/pgsql-jp-old/pgsql-jp/2001Jun/msg000 ...
- 誕生日からの経過日数を表示する。
SELECT date_trunc('day', CURRENT_TIMESTAMP - '1977-11-07');・・・。2002-12-03 で既に書いてた・・・。
テーブルを csv で出力する。psql の機能を使う。
もしくは、シェルから psql のオプションを利用してクエリを送って実行する。
下記の例では指定していないが、カラム名を出力させたくなければ -t オプションを加えれば良い。
- SQL の結果を出力したいとき
\pset format unaligned -- 出力形式を指定
\pset fieldsep ',' -- フィールドのセパレータにカンマ区切りを指定
\o psql_out.csv -- 出力ファイルを指定
ここに SQL を書く
もしくは、シェルから psql のオプションを利用してクエリを送って実行する。
下記の例では指定していないが、カラム名を出力させたくなければ -t オプションを加えれば良い。
$ psql -c 'SELECT user_id, user_name FROM users ORDER BY user_id;' -A -F,
- テーブルをまるごと出力したいとき。
SQL で SELECT * FROM TABLE_NAME をやってもいいけど、以下のようなやり方もある。COPY system_name TO '/tmp/system_name_tabale.txt' DELIMITERS ',';
- 参考
psql (PostgreSQL) 7.2.1 のヘルプ。$ psql --help
This is psql, the PostgreSQL interactive terminal.
Usage:
psql [options] [dbname [username]]
Options:
-a Echo all input from script
-A Unaligned table output mode (-P format=unaligned)
-c COMMAND Run only single command (SQL or internal) and exit
-d DBNAME Specify database name to connect to (default: tka)
-e Echo commands sent to server
-E Display queries that internal commands generate
-f FILENAME Execute commands from file, then exit
-F STRING Set field separator (default: "|") (-P fieldsep=)
-h HOSTNAME Specify database server host (default: local socket)
-H HTML table output mode (-P format=html)
-l List available databases, then exit
-n Disable enhanced command line editing (readline)
-o FILENAME Send query results to file (or |pipe)
-p PORT Specify database server port (default: 5432)
-P VAR[=ARG] Set printing option 'VAR' to 'ARG' (see \pset command)
-q Run quietly (no messages, only query output)
-R STRING Set record separator (default: newline) (-P recordsep=)
-s Single step mode (confirm each query)
-S Single line mode (end of line terminates SQL command)
-t Print rows only (-P tuples_only)
-T TEXT Set HTML table tag attributes (width, border) (-P tableattr=)
-U NAME Specify database user name (default: tka)
-v NAME=VALUE Set psql variable 'NAME' to 'VALUE'
-V Show version information and exit
-W Prompt for password (should happen automatically)
-x Turn on expanded table output (-P expanded)
-X Do not read startup file (~/.psqlrc)
For more information, type "\?" (for internal commands) or "\help"
(for SQL commands) from within psql, or consult the psql section in
the PostgreSQL documentation.
Report bugs to <pgsql-bugs@postgresql.org>.
- fnumber を使ってカラム名を添字に変換する
print $result->getvalue(0, $result->fnumber('serialnum'));
- 無名ハッシュの配列にマッピングする。
my @sql_result = get_sql_result($result);
print $sql_result[0]->{'ao_cd'};
# SQL の実行結果を結果をハッシュの配列にして返す
sub get_sql_result($) {
my $result = $_[0];
my $record_nums = $result->ntuples;
my $field_nums = $result->nfields;
my @result_records = ();
for (my $i = 0; $i < $record_nums; $i++) {
my $buf = {};
for (my $j = 0; $j < $field_nums; $j++) {
my $field_name = $result->fname($j);
$buf->{"$field_name"} = $result->getvalue($i, $j);
}
push(@result_records, $buf);
}
return @result_records;
}
「nか月前の月の1日から」という日時範囲指定 SQL。Postgres 提供の関数 date_trunc を使う。
# SELECT date_trunc('month', CURRENT_TIMESTAMP + '-2 month');
date_trunc
------------------------
2002-10-01 00:00:00+09
(1 row)
n 日前の日付を求める SQL。
例) 2002年12月3日の7日前を求める。
00:00:00 になるのか、SELECT した時刻になるのかは、実装依存?
それとも、SQL の規格で決まってるのかな?
例) 2002年12月3日の7日前を求める。
# SELECT to_date(now() + '-7day', 'YYYY-MM-DD');時刻の部分はどうなるかは、試してみる必要あり。
to_date
------------
2002-11-26
(1 row)
00:00:00 になるのか、SELECT した時刻になるのかは、実装依存?
それとも、SQL の規格で決まってるのかな?
postgres 7.3 からは、timestamp 型のタイムゾーンの扱いが変わるようだ。
[pgsql-jp: 28083] Re: timestamp型の
http://ml.postgresql.jp/pipermail/pgsql-jp/2002-November/003 ...
[pgsql-jp: 28083] Re: timestamp型の
http://ml.postgresql.jp/pipermail/pgsql-jp/2002-November/003 ...
> pg_dump dbname > db.out でバックアップファイルを作成
>
> db.outをviにて置き換え。
> :%s/timestamp wuthout time zone/timestamp(0) with time zone/g
参考までにもう一つ。
7.2では単にtimestampといえ(記述すれ)ばtimestamp with time zone
でしたが、7.3からはtimestamp without time zoneになります。これから
はwith/withoutを明記しないと混乱してしまうでしょうね。
PostgreSQL7.3 以降の configure オプションについて、
Postgres Users ML に開発者から投稿があった。いろいろ変わってるようだ。
[pgsql-jp: 27406] Re: ソースからインストールするのに必要なオプションを教えて下さい。
http://ml.postgresql.jp/pipermail/pgsql-jp/2002-September/00 ...
結論。initdb --encoding=EUC_JP --no-locale を実行すればいい。
Postgres Users ML に開発者から投稿があった。いろいろ変わってるようだ。
[pgsql-jp: 27406] Re: ソースからインストールするのに必要なオプションを教えて下さい。
http://ml.postgresql.jp/pipermail/pgsql-jp/2002-September/00 ...
> これら、PostgreSQLを利用したいという人の目的の多くはこれなんじゃないか?と
> 思ってます。
> インストール時のオプションはこれだけで良かったです。
>
> ./configure --enable-multibyte=EUC_JP
--enable-syslog も付けておけば,障害が発生したときにログが取れるように
なります,というか実運用ではログの取得は必須です.
ちなみに,7.3では --enable-multibyte --enable-syslog もデフォルトでオ
ンになっているので,
/configure
だけでOKです.ただし,デフォルトエンコーディングが SQL_ASCII になって
しまうので,initdb のときに EUC_JP を指定しておくか,createdb で
EUC_JP を指定しなければなりません.それから, --enable-locale までデフォ
ルトでオンになってしまったので,initdb のときに --no-locale を付けて
locale が効かないようにしなければならなくなりました.
結論。initdb --encoding=EUC_JP --no-locale を実行すればいい。
- 2003-04-17 追記
このスクリプトの改訂版を 2003-04-17 Postgres: Postgres バックアップスクリプト version 1.1 に書いた。pg_dump を使ってデータベース毎にバックアップを取るシェルスクリプト。
要するに pg_dump を シェルの for 文で回してデータベースの個数分作成しているだけ。
バックアップファイルは YYYYMMDD.pgdmp という名前で作成される。
- Postgres 自動バックアップスクリプトの使い方
TARGET_DB に取得したいデータベース名スペースで区切って記述する。ログの出力先や pg_dump コマンドのパスを各自の環境に合わせて修正する。
- スクリプト
#/bin/sh
# PostgreSQL database backup script
# Version 1.0
# Sep. 10, 2002
# Saito Hiroaki
# Dump to DATABASE_NAME_YYMMDD.pgdmp.
# Output log.
# Setting
TARGET_DB='account audit' # List target database name.
DIR=/home/postgres
LOG=$DIR/pgdump.log
BACKUPDIR=$DIR/dbbackup
# Main routine
echo "pg_dump start." `date` >>$LOG
date=`date +%Y%m%d`
for db_name in $TARGET_DB
do
DUMP_FILE_PATH=$BACKUPDIR/${db_name}_${date}.pgdmp
/usr/local/pgsql/bin/pg_dump $db_name -b -o -Fc > $DUMP_FILE_PATH 2>>$LOG
echo "Database $db_name backup complete." `date` >>$LOG
done
echo "pg_dump complete." `date` >>$LOG
- ユーザ postgres のホームディレクトリ
私の環境では、ユーザ postgres のホームディレクトリは、/home/postgres ではなくて/var/lib/pgsql だ。pgd.sh は /home/postgres/pgd.sh に置いたけど。- 上記スクリプトを、夜間バッチとして cron で毎日実行することにした。
0 6 * * * nice -19 /home/postgres/pgd.sh
PostgresSQL のバックアップとリストア方法
-o オブジェクトIDもバックアップする
-Fc ダンプフォーマットを指定する。c はカスタムフォーマット。圧縮も行われる。
2002-09-11 Postgres バックアップスクリプト
- pg_dump でバックアップ
pg_dump コマンドで、ラージオブジェクトを含めてデータベースをバックアップできる。$ pg_dump account -b -o -Fc > account_all_dump_data_20020806.pgdmp
$ pg_dump audit -b -o -Fc > audit_all_dump_data_20020806.pgdmp
- pg_dump コマンドのオプションの意味
-b ラージオブジェクトをバックアップする-o オブジェクトIDもバックアップする
-Fc ダンプフォーマットを指定する。c はカスタムフォーマット。圧縮も行われる。
- pg_restore でリストア
再構築 (リストア) には pg_resotre コマンドを使う。-d でリストア先のデータベース名を指定する。$ pg_restore -d account ./account_all_dump_data_20020806
$ pg_restore -d audit ./audit_all_dump_data_20020806.pgdmp
- 関連記事
2003-04-17 Postgres バックアップスクリプト version 1.12002-09-11 Postgres バックアップスクリプト
Linux マシンである sonic と pro で pgbench をとってみた。10回くらいやって、一番よかった値。
sonic のマシンスペック
pro のマシンスペック
- sonic で pgbench
[postgres@pro pgbench]$ pgbench postgres
starting vacuum...end.
transaction type: TPC-B (sort of)
scaling factor: 1
number of clients: 1
number of transactions per client: 10
number of transactions actually processed: 10/10
tps = 9.607025(including connections establishing)
tps = 11.733426(excluding connections establishing)
sonic のマシンスペック
OS: TurboLinux Server 6.5
CPU: Pentium 133MHz
Memory: 64MB
HDD: 4.3GB
NIC: Intel i82557
- pro で pgbench
つづいて pro。やっぱ倍くらい違うな。[postgres@pro pgbench]$ pgbench postgres
starting vacuum...end.
transaction type: TPC-B (sort of)
scaling factor: 1
number of clients: 1
number of transactions per client: 10
number of transactions actually processed: 10/10
tps = 20.484373(including connections establishing)
tps = 23.593809(excluding connections establishing)
pro のマシンスペック
OS: TurboLinux Server 6.5
CPU: MMX Pentium 200MHz
Memory: 128MB
HDD: 8.4GB
NIC: 3COM 3C905B