最近なにかとバタバタしているシステム担当のGucciです。
StudioAKでは自社のWebサービスなるものがいくつかあります。
実は去年から開発中のサービスがありまして、StudioAKととあるプランで契約してくれているクライアントさんを紹介するポータルサイトを構築中です。
まぁなかなか進まなくて困っているのですが、頑張って作りますよぉぉ
そのWebサイトがリリースされるまでの間、実験的にTwitterを使ってBotシステムを開発してすでにこっそり公開しています。
Botというと事前に指定した内容を定期的にTwitterにつぶやくわけなのですが、
今回はクライアントさんが書いたブログを毎朝ある時間にRSSを取得してきて、開発中のシステムDBにINSERTしてそこから最近いくつかをランダムでTwitterにつぶやくというBotシステムを作っています。
開発にはPHPとMySQLを使っています
TwitterのBotシステム自体は別の機会に作り方をまた公開しようと思います。
で、今回はなにを書くかといいますと、
毎日Cronを使って定期的にRSS情報を取得してPHP=>MySQLの順で情報を格納しているのですが、
RSSというのがこれがまたやっかいなものでクライアントさんはアメブロユーザーが多いのでアメブロのRSSを取得してDBに格納する際に、RSSには最近の10件の記事が載っています。
これを別途に管理しているクライアント情報からBlogを行っているユーザー分だけ回して取得するのですが、なにも考えずにやるとどんどんDBにINSERTされていくわけです。
そうすると同じ記事が何個も何個もDBに入ってしまい、毎日取得するとなるとちょっと困ったことになります。
理想としては
既に取得済みのデータは「DBに格納しない」か「なにかをUPDATEする」ようにし、
新規のデータのみを「INSERTしたい」と思うようになるわけですよ。
当然最初に考えるのはPHPでDBに書き込む前にDBの中身をSELECTしてTRUEならUPDATEみたいな単純なことを考えるわけですが、
それはなんかPHPが複雑になりすぎるのとあとで修正するときにめんどくさくなりそうなのでNGとしました。
次に考えられるのは毎日定期的に取得する時に一回DBをDropしてからINSERTすればどうよ?
うーーーーん
それもいいのですが、それだと過去のデータが消えていってしまうのでなんかもったいないおばけが出てきそうです。
こういう時はグーグル先生に聞いてみるもので、やっぱり世の中ほしいと思うようなものはすでにあるわけですよ。
しかも簡単な方法で!!
その方法というのはMySQLのコマンドで
「INSERT…ON DUPLICATE KEY UPDATE構文」という方法があります。
これはまさにピンポイントな方法で
- レコードがなければINSERT、すでにあればUPDATE
- 複数行の一括UPDATE
- フィールド毎に条件判定して更新
というなんとも今回のために生まれてきたような構文です(^◇^)
書き方もすごくシンプルで
INSERT INTO TableName (title, body, create_date) VALUES ($title, $body, now()) ON DUPLICATE KEY UPDATE up_date = now();
てな具合で簡単に書けます
ON DUPLICATE KEY UPDATE
より上に書いている文はINSERT文で、下にあるのがUPDATE文です。
ただこの構文には1つ気を付けないといけないことがあります。
※この構文を使うには必ず UNIQUEインデックス(かPRIMARY KEY)を指定する必要 がある
これを忘れるとUPDATEされずにすべて新規のものと認識されてしまうので注意が必要です。