140
55

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

IT芸人Advent Calendar 2019

Day 1

SQL、サーバ、フロントで出来る処理は、どこにやらせるべきなのか

Last updated at Posted at 2019-11-21

15743358488980752.png

ここで作成しました。
あ、ボクはやりたいことをやれたので満足です。フロントごめん

まえおき

SQLが最速なんだから、可能な限り処理はSQLにやらせるべきだよね!

というツイート(ネタかガチか分からない)を読んだ。この業界に銀の弾丸は存在しないはずだが……。

では、SQL、サーバサイド、フロントエンドで書ける処理はどこに書くべきなのだろうか?
それを判断する材料を考えてみた。

例題

DBの値 画面に出したい値
10 ¥10
999 ¥999
5000 ¥5,000
10500 ¥10,500
21000 ¥21,000

上記のDBの値をブラウザ上に表示させるという仕様があり、既に値自体は画面に表示できているが、三桁区切りと通貨記号(¥)を実装しなければらない!とする。

実装例

※一応書いたけど、そんなに重要じゃない

①SQL

下記はOracleの例だが、TO_CHAR関数を付けるだけで出来る。
サーバサイドのEntityをstring型に変更することになった。

-- Oracle (※DBに通貨記号の設定をする必要がある)
SELECT TO_CHAR(カラム名, 'FML999,999,999') FROM テーブル名;

②サーバサイド

下記はなんとなくC#だが、扱う金額によってはintで済まない。
処理はC#特有であるが、普通に先頭に通過記号つけて、三桁ごとに文字連結とかでもいいんだけどネ。

using System;
using System.Collections.Generic;
using System.Globalization;
public class Money{
    public static void Main(){
        
        // paiza.ioで試したんだが
        // デフォルトだとドルになっちまうんだナ
        CultureInfo jpn = new CultureInfo("ja-JP", false);

        // DBから取ってきたテイのList
        List<int> moneyList = new List<int>();
        moneyList.Add(10);
        moneyList.Add(999);
        moneyList.Add(5000);
        moneyList.Add(10500);
        moneyList.Add(21000);

        // 画面に表示させる値を入れるリスト
        List<string> moneyDisplay = new List<string>();

        // 3桁区切りで通貨記号をつける
        foreach(int money in moneyList)
        {
            moneyDisplay.Add(money.ToString("C", jpn));
        }
        
        // 出力
        foreach(string result in moneyDisplay)
        {
            // マジレスすると俺C#書けないわ。よくがんばった
            Console.WriteLine(result);
        }
    }
}

③フロントエンド

このAPIは対応していないブラウザもあるらしい
ブラウザ対応の都合を考えて、一般的には正規表現でやる。

const money = [10, 999, 5000, 10500, 21000];

// 便利なAPIで日本円にしてくれる
const formatter = new Intl.NumberFormat('ja-JP', {
    style: 'currency',
    currency: 'JPY'
});

const displayMoney = money.map(value => formatter.format(value))

// 配列を出力
console.log(displayMoney);

判断基準

①処理時間
この場合、レコードは5件しかないので、SQL、サーバサイド、フロントエンドのいずれでやっても人間にとっては些細な時間であろう。もしも千件、万件を画面に出そうとしているならSQLが圧倒的に早そう……だけど、少し思いとどまったほうがいいかもしれない。その仕様は本当に大丈夫?

②値の汎用性
もしも出力した値を計算に使う場合はDBでやってしまうと、サーバは文字列型として受け取ってしまうので、サーバ、フロント側で計算処理を書きづらくなる。したがって、SQL以外で処理した方が後で値を使いまわしやすい

③負荷
今回はほぼ影響ないが、処理をサーバ側でやるとサーバに負荷がかかるので、フロントのほうが良い。特に大量にアクセスされるページとかは、なるべくフロントにしたいところ。ブラウザ側で処理が遅くならないようにバランスは調整したい

④役割
この処理は「画面に表示させる処理」ではないので、サーバサイドで行う。「JavaScriptはサーバとの通信とDOM操作だけに徹底する!計算とかはしない!」ルールがあるなら、それもアリ。フロントとサーバの役割をぎっちり分ける会社、現場も一応見たことはある

⑤改修
あんまり気にすることはないかもしれないが、10年、20年後に改修するときにDBがOracleからPostgreSQLに変わるかもしれない。そうなったときに、SQLで関数を多用していたりすると書き直しになる可能性が高い。「SQL YYYY構文」(YYYYには年数が入る)以外の使用は可能な限り避けた方が良いだろう。
サーバサイドは言語のバージョンアップがあるかもしれない。言語の変更もあり得なくはない。フロントエンドはどうなんだろう(JSの改修案件とかみたことない)

※上記の判断基準は一例だが、SQLはオススメできない……。

image.png

まとめ

  • (基本的に)SQLの処理って早いと思うよ
  • 自分だったらこの処理をフロントエンドでやりそう
  • 銀の弾丸はない。現場のルールやいろいろな判断基準を元にどこで書くのが良いかしっかり検討しよう。最速だから何でもかんでもSQLにすればいい!ってもんじゃない

最後に

「いいね」ボタンを押して頂けると、うれしくなって記事を書けます。
あと、一緒に記事を書くIT芸人会の仲間を探しています。

140
55
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
140
55

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?