ラベル DB の投稿を表示しています。 すべての投稿を表示
ラベル DB の投稿を表示しています。 すべての投稿を表示

2012年12月25日火曜日

MySQL SELECT OUTFILE Errcode: 13


Ubuntu ServerでMySQL検索結果をファイルで出力する時書き込み権限エラーが発生。

mysql> SELECT * FROM T_BABUKUMA INTO OUTFILE "/root/babukuma.csv" CHARACTER SET 'utf8' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"';
ERROR 1 (HY000): Can't create/write to file '/root/babukuma.csv' (Errcode: 13)

権限の解決方法は調べてみたら色々あるが、難しいからやめた。

一応rootで入ってディレクトリ指定をしなければ、「/var/lib/mysql/db名」ディレクトリに出力は可能なので、出力結果が欲しいだけならこれでいいかと。

mysql> SELECT * FROM T_BABUKUMA INTO OUTFILE "babukuma.csv" CHARACTER SET 'sjis' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"';
Query OK, 346 rows affected (0.00 sec)

# ls /var/lib/mysql/babukuma/babukuma.csv
babukuma.csv

2012年11月14日水曜日

WebSQL

原本はこちら

1. WebSQL

HTML5の標準仕様から外されていつなくなるかわからないが、
まだ、色んなブラウザでサポートしているのでまとめてみる。
ここではSafari向けのWebSQL。他のブラウザは知らん。


Creating and Opening a Database

var db = openDatabase(dbName, version, displayName, maxSize);

  1. dbName : db名(例:'babukumaDb')
  2. version : dbのバージョン(例:'1')
  3. displayName : 表示名(例:'Babukuma's Database')
  4. maxSize : 最大格納サイズ(単位bytes)(例:65536)

    var dbName = 'babukumaDB';
    var displayName = "babukuma's database";
    var maxSize = 1024 * 1024 * 4;
    var version = '1';
    var db;

    try {
      db = openDatabase(dbName, version, displayName, maxSize);
    } catch(e) {
      if (e === 2) {
        alert("Invalid database version.");
      } else {
        alert("Unknown error " + e);
      }
    }


Executing a Query


executeSql(sqlStatement, arguments, callback, errorCallback);

  1. sqlStatement : SQL
  2. arguments : 引数
  3. callback : 成功時のコールバック
  4. errorCallback : エラーじのコールバック

    // 成功時コールバック
    function nullDataHandler(transaction, results) {}
    
    // エラー時コールバック
    function errorHandler(transaction, error) {
      alert('Error was ' + error.message + ' (Code ' + error.code + ')');
    }

    db.transaction(function(transaction) {
      transaction.executeSql('CREATE TABLE T_TEST ID INT PRIMARY KEY, NAME TEXT', [], nullDataHandler, errorHandler);
      transaction.executeSql('INSERT INTO T_TEST VALUES (?, ?)', [1, 'BABUKUMA'], nullDataHandler, errorHandler);
    });


Handling Result Data

    // クエリ実行成功時コールバック
    function dataHandler(transaction, results) {
      var size = results.length;
      for(var i = 0 ; i < size ; i++) {
        row = results.rows.item(i);
        console.log("ID=%d, NAME=%s", row.ID, row.NAME);
      }
    }
    
    // エラー時コールバック
    function errorHandler(transaction, error) {
      alert('Error was ' + error.message + ' (Code ' + error.code + ')');
    }

    db.transaction(function(transaction) {
      transaction.executeSql('SELECT * FROM T_TEST WHERE ID > ?', [1], dataHandler, errorHandler);
    });


Migration


changeVersion(oldVersion, newVersion, migrationHandler, errorHandler, successHandler);

  1. oldVersion : 以前のバージョン
  2. newVersion : 新バージョン
  3. migrationHandler : マイグレーション用関数
  4. errorHandler : エラー時コールバック
  5. successHandler : 成功時コールバック

    var dbName = 'babukumaDB';
    var displayName = "babukuma's database";
    var maxSize = 1024 * 1024 * 4;
    var DB_VERSION = '4';
    var db;

    // 成功時コールバック
    var successHandler = function() {
      alert('マイグレーション成功!');
    };

    // エラー時コールバック
    function errorHandler(transaction, error) {
      alert('Error was ' + error.message + ' (Code ' + error.code + ')');
    }

    // 初期化
    var initDB = function(transaction) {
      transaction.executeSql('CREATE TABLE ......', [], nullDataHandler, errorHandler);
    };

    // Version 1 -> Version 2
    var migration_1_2 = function(transaction) {
      transaction.executeSql('ALTER TABLE ......', [], nullDataHandler, errorHandler);
    };

    // Version 2 -> Version 3
    var migration_2_3 = function(transaction) {
      transaction.executeSql('ALTER TABLE ......', [], nullDataHandler, errorHandler);
    };

    // Version 3 -> Version 4
    var migration_3_4 = function(transaction) {
      transaction.executeSql('ALTER TABLE ......', [], nullDataHandler, errorHandler);
    };

    try {
      db = openDatabase(dbName, '', displayName, maxSize); // versionを指定しないのが重要

      if (db.version !== DB_VERSION) {
        if (db.version === '') {
          db.changeVersion('', '1', initDB, errorHandler, function() {
            db.changeVersion('1', '2', migration_1_2, errorHandler, function() {
              db.changeVersion('2', '3', migration_2_3, errorHandler, function() {
                db.changeVersion('3', '4', migration_3_4, errorHandler, successHandler);
              });
            });
          });
        } else if (db.version === '1') {
          db.changeVersion('1', '2', migration_1_2, errorHandler, function() {
            db.changeVersion('2', '3', migration_2_3, errorHandler, function() {
              db.changeVersion('3', '4', migration_3_4, errorHandler, successHandler);
            });
          });
        } else if (db.version === '2') {
          db.changeVersion('2', '3', migration_2_3, errorHandler, function() {
            db.changeVersion('3', '4', migration_3_4, errorHandler, successHandler);
          });
        } else if (db.version === '3') {
          db.changeVersion('3', '4', migration_3_4, errorHandler, successHandler);
        }
      }

    } catch(e) {
      if (e === 2) {
        alert("Invalid database version.");
      } else {
        alert("Unknown error " + e);
      }
    }

2011年12月12日月曜日

Cassandraの障害時対応方法を考えてみた。


Cassandraはマスタ・スレーブ関係がなく、各ノードが同一の機能をもっているDBで、単一障害点がない。
だが、アプリケーション側では接続しているノードが死んだらアウトじゃないかな?



どうすればいいのかな?
たぶん、この問題を対応してくれるライブラリがあると思うけど、
自分で実装するなら?どうする?

複数のノードに接続すればいいんじゃないかな?
接続プールみたいなものを作って、複数のノードに接続させれば、
一部死んでも通信は出来るんじゃないのか?


実際に運用している方はどうしているのかな?

2010年5月18日火曜日

[SQLite] not implemented by SQLite JDBC driver

SQLiteをJavaで使う時、
「REAL」タイプをjava側のBigDecimalにマッピングするのはできないらしい。

「not implemented by SQLite JDBC driver」というエラーが発生する。

調べてみると、ResultSetの「getBigDecimal()」と「getBLOB()」も使えないようだ。

2010年4月10日土曜日

SQLiteとH2の性能比較

H2とSQLite3の性能比較が知りたくて調べてみたが
古い記事しかなかったので簡単に性能比較してみた。

SQLiteバージョン : 3.6.23
H2バージョン : 1.2.132

テスト言語はJava(プロジェクトがJavaベースなので)
SQLiteのJDBCドライバは「SQLiteJDBC」を使用した。

SQLiteJDBC : http://www.zentus.com/sqlitejdbc/

テスト環境1


- CPU : 2.53 GHz Intel Core 2 Duo
- Memory : 4GB
- OS : Mac OS X 10.6.3
区分SQLiteH2 EmbeddedH2 In-memory
Insert (100万件)0.5 秒0.9 秒0.9 秒
Select (100万件)0.002 秒0.015 秒0.07 秒
File size2,048 bytes14,336 bytes-


テスト環境2


- CPU : 2.53 GHz Intel Core 2 Duo
- Memory : 4GB
- OS : Mac OS X 10.6.3
区分SQLiteH2 EmbeddedH2 In-memory
Insert (100万件)0.5 秒1.3 秒1.5 秒
Select (100万件)0.004 秒0.09 秒0.095 秒
File size2,048 bytes14,336 bytes-


簡単なテストだが全板的にSQLiteの勝ち。
特に瀬能が低いマシンではもっとH2よりパフォーマンスがいいらしい。
でもH2は今まで「In-memory」方式が「組込み」より早いと思ったのが大間違いだったのがショックだ。


下はテストで使用したソース

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

public class SqlitePerformance {
private static final int ROW_COUNT = 1000000;
private static final int MAX = 100;

/**
* SQLite3 Embedded
*
* @author babukuma
* @since 2010/04/09
* @param args
*/
public static void main(String[] args) throws Exception {
System.out.println("SQLite TEST [" + ROW_COUNT + "件]");
Class.forName("org.sqlite.JDBC");
Connection conn = DriverManager
.getConnection("jdbc:sqlite:babukuma.sqllite.db");

Statement stat = conn.createStatement();
stat.executeUpdate("drop table if exists babukuma;");
stat
.executeUpdate("create table babukuma (id integer primary key, value integer);");

conn.setAutoCommit(false);
System.out.print("Insert Test : ");
long startTime = System.currentTimeMillis();

PreparedStatement prep = conn
.prepareStatement("insert into babukuma values (?, ?);");

for (int i = 0; i < ROW_COUNT; i++) {
prep.setInt(1, i);
prep.setInt(2, i);
prep.addBatch();

if (i > 0 && (i % MAX) == 0 && i == ROW_COUNT - 1) {
prep.executeBatch();
prep.clearBatch();
}
}

conn.commit();

long endTime = System.currentTimeMillis();
System.out.println(((endTime - startTime) / 1000.) + "秒");

System.out.print("Select Test : ");
startTime = System.currentTimeMillis();
ResultSet rs = stat.executeQuery("select * from babukuma;");
while (rs.next()) {
rs.getInt("id");
rs.getInt("value");
// System.out.println("id = " + rs.getInt("id"));
// System.out.println("value = " + rs.getString("value"));
}
rs.close();
endTime = System.currentTimeMillis();
System.out.println(((endTime - startTime) / 1000.) + "秒");

conn.close();
}
}


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

import org.h2.jdbcx.JdbcConnectionPool;

public class H2Performance {
private static final int ROW_COUNT = 1000000;
private static final int MAX = 100;

/**
* H2 Embedded
*
* @author babukuma
* @since 2010/04/09
* @param args
*/
public static void main(String[] args) throws Exception {
System.out.println("H2 TEST [" + ROW_COUNT + "件]");
JdbcConnectionPool cp = JdbcConnectionPool.create(
"jdbc:h2:babukuma.h2", "", "");
Connection conn = cp.getConnection();

Statement stat = conn.createStatement();
stat.executeUpdate("drop table if exists babukuma;");
stat
.executeUpdate("create table babukuma (id int primary key, value int);");

conn.setAutoCommit(false);
System.out.print("Insert Test : ");
long startTime = System.currentTimeMillis();

PreparedStatement prep = conn
.prepareStatement("insert into babukuma values (?, ?);");

for (int i = 0; i < ROW_COUNT; i++) {
prep.setInt(1, i);
prep.setInt(2, i);
prep.addBatch();

if (i > 0 && (i % MAX) == 0 && i == ROW_COUNT - 1) {
prep.executeBatch();
prep.clearBatch();
}
}

conn.commit();

long endTime = System.currentTimeMillis();
System.out.println(((endTime - startTime) / 1000.) + "秒");

System.out.print("Select Test : ");
startTime = System.currentTimeMillis();
ResultSet rs = stat.executeQuery("select * from babukuma;");
while (rs.next()) {
rs.getInt("id");
rs.getInt("value");
// System.out.println("id = " + rs.getInt("id"));
// System.out.println("value = " + rs.getString("value"));
}
rs.close();
endTime = System.currentTimeMillis();
System.out.println(((endTime - startTime) / 1000.) + "秒");

conn.close();
}
}


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

import org.h2.jdbcx.JdbcConnectionPool;

public class H2InMemoryPerformance {
private static final int ROW_COUNT = 1000000;
private static final int MAX = 100;

/**
* H2 In memory
*
* @author babukuma
* @since 2010/04/09
* @param args
*/
public static void main(String[] args) throws Exception {
System.out.println("H2 In Memory TEST [" + ROW_COUNT + "件]");
JdbcConnectionPool cp = JdbcConnectionPool
.create("jdbc:h2:mem:", "", "");
Connection conn = cp.getConnection();

Statement stat = conn.createStatement();
stat.executeUpdate("drop table if exists babukuma;");
stat
.executeUpdate("create table babukuma (id int primary key, value int);");

conn.setAutoCommit(false);
System.out.print("Insert Test : ");
long startTime = System.currentTimeMillis();

PreparedStatement prep = conn
.prepareStatement("insert into babukuma values (?, ?);");

for (int i = 0; i < ROW_COUNT; i++) {
prep.setInt(1, i);
prep.setInt(2, i);
prep.addBatch();

if (i > 0 && (i % MAX) == 0 && i == ROW_COUNT - 1) {
prep.executeBatch();
prep.clearBatch();
}
}

conn.commit();

long endTime = System.currentTimeMillis();
System.out.println(((endTime - startTime) / 1000.) + "秒");

System.out.print("Select Test : ");
startTime = System.currentTimeMillis();
ResultSet rs = stat.executeQuery("select * from babukuma;");
while (rs.next()) {
rs.getInt("id");
rs.getInt("value");
// System.out.println("id = " + rs.getInt("id"));
// System.out.println("value = " + rs.getString("value"));
}
rs.close();
endTime = System.currentTimeMillis();
System.out.println(((endTime - startTime) / 1000.) + "秒");

conn.close();
}
}

2010年4月9日金曜日

SQLite과 H2의 성능비교

궁금해서 임베디드 DB인 H2와 SQLite3를 비교해보았다.

SQLite 버젼 : 3.6.23
H2 버젼 : 1.2.132

둘다 사용할 프로젝트가 Java인 관계로 언어는 Java로.
SQLite는 JDBC드라이버인 SQLiteJDBC를 사용하였다.

SQLiteJDBC : http://www.zentus.com/sqlitejdbc/

테스트 환경 1


- CPU : 2.53 GHz Intel Core 2 Duo
- Memory : 4GB
- OS : Mac OS X 10.6.3
구분SQLiteH2 EmbeddedH2 In-memory
Insert (100만건)0.5 초0.9 초0.9 초
Select (100만건)0.002 초0.015 초0.07 초
File size2,048 bytes14,336 bytes-


테스트 환경 2


- CPU : 2.53 GHz Intel Core 2 Duo
- Memory : 4GB
- OS : Mac OS X 10.6.3
구분SQLiteH2 EmbeddedH2 In-memory
Insert (100만건)0.5 초1.3 초1.5 초
Select (100만건)0.004 초0.09 초0.095 초
File size2,048 bytes14,336 bytes-


비록 간단한 테스트이지만 대략적으로 SQLite가 우세한 듯 보인다.
특히 성능이 낮은 머신에서 H2와의 성능차이가 뚜렷하다.
그리고 H2는 여지껏 「In-memory」방식이 「임베디드」방식보다 성능이 더 좋을 줄 알았는데,
전혀 생각과 틀려 충격이었다.


테스트용 소스는 아래와 같다.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

public class SqlitePerformance {
private static final int ROW_COUNT = 1000000;
private static final int MAX = 100;

/**
* SQLite3 Embedded
*
* @author babukuma
* @since 2010/04/09
* @param args
*/
public static void main(String[] args) throws Exception {
System.out.println("SQLite TEST [" + ROW_COUNT + "件]");
Class.forName("org.sqlite.JDBC");
Connection conn = DriverManager
.getConnection("jdbc:sqlite:babukuma.sqllite.db");

Statement stat = conn.createStatement();
stat.executeUpdate("drop table if exists babukuma;");
stat
.executeUpdate("create table babukuma (id integer primary key, value integer);");

conn.setAutoCommit(false);
System.out.print("Insert Test : ");
long startTime = System.currentTimeMillis();

PreparedStatement prep = conn
.prepareStatement("insert into babukuma values (?, ?);");

for (int i = 0; i < ROW_COUNT; i++) {
prep.setInt(1, i);
prep.setInt(2, i);
prep.addBatch();

if (i > 0 && (i % MAX) == 0 && i == ROW_COUNT - 1) {
prep.executeBatch();
prep.clearBatch();
}
}

conn.commit();

long endTime = System.currentTimeMillis();
System.out.println(((endTime - startTime) / 1000.) + "秒");

System.out.print("Select Test : ");
startTime = System.currentTimeMillis();
ResultSet rs = stat.executeQuery("select * from babukuma;");
while (rs.next()) {
rs.getInt("id");
rs.getInt("value");
// System.out.println("id = " + rs.getInt("id"));
// System.out.println("value = " + rs.getString("value"));
}
rs.close();
endTime = System.currentTimeMillis();
System.out.println(((endTime - startTime) / 1000.) + "秒");

conn.close();
}
}


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

import org.h2.jdbcx.JdbcConnectionPool;

public class H2Performance {
private static final int ROW_COUNT = 1000000;
private static final int MAX = 100;

/**
* H2 Embedded
*
* @author babukuma
* @since 2010/04/09
* @param args
*/
public static void main(String[] args) throws Exception {
System.out.println("H2 TEST [" + ROW_COUNT + "件]");
JdbcConnectionPool cp = JdbcConnectionPool.create(
"jdbc:h2:babukuma.h2", "", "");
Connection conn = cp.getConnection();

Statement stat = conn.createStatement();
stat.executeUpdate("drop table if exists babukuma;");
stat
.executeUpdate("create table babukuma (id int primary key, value int);");

conn.setAutoCommit(false);
System.out.print("Insert Test : ");
long startTime = System.currentTimeMillis();

PreparedStatement prep = conn
.prepareStatement("insert into babukuma values (?, ?);");

for (int i = 0; i < ROW_COUNT; i++) {
prep.setInt(1, i);
prep.setInt(2, i);
prep.addBatch();

if (i > 0 && (i % MAX) == 0 && i == ROW_COUNT - 1) {
prep.executeBatch();
prep.clearBatch();
}
}

conn.commit();

long endTime = System.currentTimeMillis();
System.out.println(((endTime - startTime) / 1000.) + "秒");

System.out.print("Select Test : ");
startTime = System.currentTimeMillis();
ResultSet rs = stat.executeQuery("select * from babukuma;");
while (rs.next()) {
rs.getInt("id");
rs.getInt("value");
// System.out.println("id = " + rs.getInt("id"));
// System.out.println("value = " + rs.getString("value"));
}
rs.close();
endTime = System.currentTimeMillis();
System.out.println(((endTime - startTime) / 1000.) + "秒");

conn.close();
}
}


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

import org.h2.jdbcx.JdbcConnectionPool;

public class H2InMemoryPerformance {
private static final int ROW_COUNT = 1000000;
private static final int MAX = 100;

/**
* H2 In memory
*
* @author babukuma
* @since 2010/04/09
* @param args
*/
public static void main(String[] args) throws Exception {
System.out.println("H2 In Memory TEST [" + ROW_COUNT + "件]");
JdbcConnectionPool cp = JdbcConnectionPool
.create("jdbc:h2:mem:", "", "");
Connection conn = cp.getConnection();

Statement stat = conn.createStatement();
stat.executeUpdate("drop table if exists babukuma;");
stat
.executeUpdate("create table babukuma (id int primary key, value int);");

conn.setAutoCommit(false);
System.out.print("Insert Test : ");
long startTime = System.currentTimeMillis();

PreparedStatement prep = conn
.prepareStatement("insert into babukuma values (?, ?);");

for (int i = 0; i < ROW_COUNT; i++) {
prep.setInt(1, i);
prep.setInt(2, i);
prep.addBatch();

if (i > 0 && (i % MAX) == 0 && i == ROW_COUNT - 1) {
prep.executeBatch();
prep.clearBatch();
}
}

conn.commit();

long endTime = System.currentTimeMillis();
System.out.println(((endTime - startTime) / 1000.) + "秒");

System.out.print("Select Test : ");
startTime = System.currentTimeMillis();
ResultSet rs = stat.executeQuery("select * from babukuma;");
while (rs.next()) {
rs.getInt("id");
rs.getInt("value");
// System.out.println("id = " + rs.getInt("id"));
// System.out.println("value = " + rs.getString("value"));
}
rs.close();
endTime = System.currentTimeMillis();
System.out.println(((endTime - startTime) / 1000.) + "秒");

conn.close();
}
}

2010年2月15日月曜日

[Oracle] ORA-12162

接続時のエラー
ORA-12162: TNS:net service name is incorrectly specified

確認
- tnsnames.oraが正しいのか
- 環境変数:ORACLE_SIDはエクスポートされているのか

僕の場合はORACLE_SIDがエクスポートされてなかったのでエクスポートしたら直った。
ありがとうkiku3kiku3kiku3

2010年2月5日金曜日

Mac OS XにMySQLをインストールしてみる

環境
OS : Mac OS X 10.6.2
MySQL : 5.1.43

1. MySQLダウンロード
  - http://dev.mysql.com/downloads/mysql/ からダウンロード
  - mysql-5.1.43-osx10.6-x86_64.dmg

2. インストール
  - ダウンロードしたファイルをダブルクリック実行


  - 「mysql-XXXXXX.pkg」(ここでは「mysql-5.1.43-osx10.6-x86_64.pkg」)を実行

  - MySQL.prefPane設置(ダブルクリックで。。)



3. MySQLサーバ起動と停止
  - コマンドでもできるけど、システム環境設定画面から起動と停止ができる。



4. MySQLアンインストール
  - MySQL.prefPaneを削除


  - mysqlインストール先を削除
    デフォールトなら「/usr/local/mysql-5.1.43-osx10.6-x86_64」と「/usr/local/mysql」を削除すればいい。

Mac OS X에 MySQL 설치

환경
OS : Mac OS X 10.6.2
MySQL : 5.1.43

1. MySQL 다운로드
  - http://dev.mysql.com/downloads/mysql/ 에서 다운로드
  - mysql-5.1.43-osx10.6-x86_64.dmg

2. 인스톨
  - 다운로드한 파일을 실행


  - 「mysql-XXXXXX.pkg」(여기서는 「mysql-5.1.43-osx10.6-x86_64.pkg」)을 실행

  - MySQL.prefPane을 설치(더블클릭으로.)



3. MySQL서버 시작과 정지
  - 콘솔창에서 커맨드로도 가능하지만 시스템환경설정화면에서 간단하게 조작가능.



4. MySQL언인스톨
  - MySQL.prefPane제거


  - mysql이 설치된 디렉토리를 삭제
    디폴트면 「/usr/local/mysql-5.1.43-osx10.6-x86_64」와 「/usr/local/mysql」를 삭제하면 된다.

2009年10月2日金曜日

いつも忘れてしまうOracle起動方法

oracleユーザで入って、


$ cd $ORACLE_HOME/bin
$ sqlplus /nolog
SQL> connect / as sysdba
SQL> startup
ORACLE instance started.

Total System Global Area 536870912 bytes
Fixed Size 1220460 bytes
Variable Size 155189396 bytes
Database Buffers 373293056 bytes
Redo Buffers 7168000 bytes
?????????????????
?????????????????
SQL> select status from v$instance;

STATUS
------------
OPEN

SQL> exit

$ ./lsnrctl start
$ ./lsnrctl status <確認

2009年6月7日日曜日

マテリアライズド・ビュー

(・(工)・)
Oraclenのマテリアライズド・ビューは確かに実体を持つビューの為、高速参照ができるけど。
対象のテーブルが更新するときコミットのタイミングが遅くなる気がする。

集計テーブルを使用する場合考えるのはなにがあるんだろう。。

1。バッチは?
バッチで物理的な集計テーブルを作れば、参照は一番早いと思うけど、
リアルタイム性がないのが短所がある。

2。トリガー
トリガーも物理的な集計テーブルが作れるから、参照は早いけど、
DBの負荷が高くなる。

3。マテリアライズド・ビュー
確かにマテリアライズドビューは結合した結果よりは早い。
物理的な集計テーブルよりはちょっと遅いけど、
参照するときの速度と負荷は大したものではなさそう。
まあ。。使えるね。。

4。アプリのトリガー
DBのトリガーみたいなものをアプリ側で用意するのは?
コントロールが難しいとは思うけど、
コントロールができるとしたらこっちのほうが現実的には良いのでは?(´`;) ?

もっとテストしてみよう。(・(工)・)