Hatena::Groupasakura

浅倉卓司@blog風味? このページをアンテナに追加 RSSフィード

Error : RSSが取得できませんでした。

2008-02-29(Fri)

投票とかで使うトリガ

| 20:00 | 投票とかで使うトリガ - 浅倉卓司@blog風味? を含むブックマーク 投票とかで使うトリガ - 浅倉卓司@blog風味? のブックマークコメント

http://asakura.g.hatena.ne.jp/asakura-t/20080227/1204101591

 毎回カウントするトリガ

CREATE TRIGGER _vote_after_insert
  AFTER INSERT ON vote FOR EACH ROW
    REPLACE INTO vote_count
    SET target_id   = NEW.target_id,
        total_count = (SELECT COUNT(*) FROM vote WHERE target_id = NEW.target_id)
//

――は、件数が多くなってくると(InnoDBだとさらに)結構重くなるので、

DELIMITER //
CREATE PROCEDURE `_vote_count_inc`( _target_id int )
BEGIN
  DECLARE _exist int DEFAULT NULL;
  SELECT total_count INTO _exist
    FROM vote_count WHERE target_id = _target_id;
  IF _exist THEN
    UPDATE vote_count
    SET total_count = total_count + 1
    WHERE target_id = _target_id
    ;
  ELSE
    INSERT INTO vote_count
    SET target_id = _target_id,
        total_count = ( SELECT COUNT(*) FROM vote WHERE target_id = _target_id )
    ;
  END IF;
END
//
CREATE TRIGGER _vote_after_insert
  AFTER INSERT ON vote FOR EACH ROW
  CALL _vote_count_inc( NEW.target_id )
//

――にしたほうがよさげ。

 件数が少ないときはSELECT COUNT(*)してもあまり気にならなかったけど、件数が増えると格段に重くなります……。

トラックバック - http://asakura.g.hatena.ne.jp/asakura-t/20080229

2008-02-27(Wed)

久々にトリガとかストアドプロシージャとか書いたよ。

| 17:39 | 久々にトリガとかストアドプロシージャとか書いたよ。 - 浅倉卓司@blog風味? を含むブックマーク 久々にトリガとかストアドプロシージャとか書いたよ。 - 浅倉卓司@blog風味? のブックマークコメント

 そういやMySQLは5.0からトリガとかストアドとか使えるようになったんだよね、ということで久々にそういうのを書いてみた。

DELIMITER //
CREATE TABLE `vote` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `target_id` int(10) unsigned NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `target_id` (`target_id`)
)
//

CREATE TABLE `vote_count` (
  `target_id` int(10) unsigned NOT NULL,
  `total_count` int(10) unsigned NOT NULL,
  PRIMARY KEY  (`target_id`)
)
//

CREATE TRIGGER _vote_after_insert
  AFTER INSERT ON vote FOR EACH ROW
    REPLACE INTO vote_count
    SET target_id   = NEW.target_id,
        total_count = (SELECT COUNT(*) FROM vote WHERE target_id = NEW.target_id)
//

 このほうが2回SQLを発行するより確実で速い。


 UPDATEやDELETEに対応させるなら、

DELIMITER //
CREATE PROCEDURE `_update_vote_count`( _target_id int )
BEGIN
  REPLACE INTO vote_count
  SET target_id = _target_id,
      total_count = (SELECT COUNT(*) FROM vote WHERE target_id = _target_id);
END
//
CREATE TRIGGER _vote_after_insert
  AFTER INSERT ON vote FOR EACH ROW
  CALL _update_vote_count( NEW.target_id )
//
CREATE TRIGGER _vote_after_delete
  AFTER DELETE ON vote FOR EACH ROW
  CALL _update_vote_count( OLD.target_id )
//
CREATE TRIGGER _vote_after_update
  AFTER UPDATE ON vote FOR EACH ROW
  BEGIN
    CALL _update_vote_count( OLD.target_id );
    CALL _update_vote_count( NEW.target_id );
  END
//

――とかすればいい。

 ただ、毎回 SELECT COUNT(*) されるのでちょっと重い。


 いちおう

DELIMITER //
CREATE PROCEDURE `_vote_count_inc`( _target_id int )
BEGIN
  DECLARE _exist int DEFAULT NULL;
  SELECT total_count INTO _exist
    FROM vote_count WHERE target_id = _target_id;
  IF _exist THEN
    UPDATE vote_count
    SET total_count = total_count + 1
    WHERE target_id = _target_id
    ;
  ELSE
    INSERT INTO vote_count
    SET target_id = _target_id,
        total_count = ( SELECT COUNT(*) FROM vote WHERE target_id = _target_id )
    ;
  END IF;
END
//
CREATE TRIGGER _vote_after_insert
  AFTER INSERT ON vote FOR EACH ROW
  CALL _vote_count_inc( NEW.target_id )
//

――みたいにすればいいんだけど、vote_countを他で更新されると整合性がとれないという欠点もある。


 こういう場合、一般的にはどうしてるんでしょ。

トラックバック - http://asakura.g.hatena.ne.jp/asakura-t/20080227

2008-02-25(Mon)

utf8文字列とファイル名、の続き

| 13:41 |  utf8文字列とファイル名、の続き - 浅倉卓司@blog風味? を含むブックマーク  utf8文字列とファイル名、の続き - 浅倉卓司@blog風味? のブックマークコメント

こと Latin-1 の範囲(U+0000 ~ U+00FF)に収まる Character で構成される文字列に限っていえば,同じ文字列を内部 Latin-1 でも 内部 UTF-8 でも表象できます。

このとき,eq オペレータで比較すると,(内部表象はどうであれ)等価な文字列かどうかを比較することができます。

#!/usr/bin/perl

use strict;
use warnings;

my $str1 = "H\x{e9}llo";
my $str2 = $str1;
utf8::upgrade($str2);

# Now, $str1 is internally represented in Latin-1 encoding
#      $str2 is internally represented in UTF-8   encoding

# $str1: {utf8=0}[H][\xe9]     [e][l][l][o]
# $str2: {utf8=1}[H][\xc3,\xa9][e][l][l][o]

# 内的エンコーディングが違うだけで両者の意味するものは同じ

print $str1 eq $str2 ? 1:0, "\n";
# => 1
UTF8 フラグあれこれ - Unicode 文字列の透過性 (1)

 これは知らなかった。

 ということは、

#!/usr/bin/perl

use strict;
use warnings;

my $str1 = "H\x{e9}llo";
my $str2 = $str1;
utf8::upgrade($str2);

sub append_file {
  my $filename = shift;
  open my $fh, '>>', $filename;
  print $fh "$filename\n";
}

append_file( $latin1 );
append_file( $utf8 );

――とすればファイルが1つだけ作られるのかな? と思って実行してみたら、ファイルが複数に*1

 うーむ。過去のテストからすると妥当ではあるんだけど。

 

 やっぱりutf8フラグ付きの文字列でファイル名に関する操作するときはwarning等を出すべきじゃないのかなぁ、とか思った。

(printする時にlatin-1の範囲だとwarning出さないみたいだし。これでハマる事ってないんじゃろか)

*1:Perl5.8.6にて確認。5.10は未確認。

トラックバック - http://asakura.g.hatena.ne.jp/asakura-t/20080225

2008-02-23(Sat)

世の中もっと非同期になればいいのに

| 13:13 | 世の中もっと非同期になればいいのに - 浅倉卓司@blog風味? を含むブックマーク 世の中もっと非同期になればいいのに - 浅倉卓司@blog風味? のブックマークコメント

 濱野さんの使っている「同期性」という言葉は、どちらかといえば「同時期性」と言うべきものであって、「同期」ではないように思います(少なくとも濱野さんの「同期的」の定義と、他で述べている「同期的」は定義が違っているように思います)。

 もし「同期性」ではなく「同時期性」が大事だというのであれば僕もそう思いますし、特に反論はありません。


 ところで、僕が「同期/非同期」に拘っていたのは、単に「非同期で済むことに同期を強要されるのがイヤ」だし、「非同期化すればもっと効率が上がって世の中もっとよくなるのにね」というポリシーゆえです。

 これは僕が1990年代からパソコン通信をやってたり、あるいはメイルゲームをやってたりして非同期な生活に慣れていて、同期的である必要はないのを実感しているためです。

 非同期的な感覚というのはあまり一般的でないらしく――身の回りで起こる事象は(ネット以外は)同期的ですから――「非同期がいいよ!」と言っても理解してもらえないんですよね。

 でもネットの普及でようやく「非同期のよさ」が広がりかけていて喜んでいたわけですよ。そこに「同期が重要」みたいな主張をされると僕にとっては都合が悪いのです(笑)。

 そこで「本当に同期が重要なの? 重要なのは別の事じゃないの?」と疑問を呈したわけなのです。

2004 | 01 | 02 | 03 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2005 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2006 | 01 | 02 | 03 | 04 | 05 | 06 | 08 | 09 | 10 | 11 | 12 |
2007 | 02 | 03 | 04 | 05 | 06 | 07 | 10 | 11 | 12 |
2008 | 02 | 03 | 04 | 06 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2012 | 02 | 03 | 04 | 05 | 07 | 08 | 10 | 11 | 12 |
2013 | 01 | 05 | 07 |
2014 | 01 | 02 |
2016 | 01 |
2017 | 01 | 05 |