タグ

ブックマーク / sikushima.hatenablog.com (32)

  • MVCがなぜ間違っているか? - SQLer 生島勘富 のブログ

    WebシステムにMVCを適用するのは間違っています(正確にはインターフェースが足りません)。 paperface.hatenablog.com このように思考停止したエンジニアにはわからないかもしれませんが、もう一度解説してみましょう。 目次 目次 そもそもMVCとは? 歴史を振り返ってみましょう インピーダンスミスマッチとORMの登場! こうあるべきでしょう? ストアドプロシージャにすることに問題はないの? Fetch してグルグルしない 文字列連結は要らない どちらが極端ですか? 分離開発するべき そもそもMVCとは? MVCができた頃 MVCは、スタンドアロー向けのプログラムがあまりにぐちゃぐちゃだったので、「違う機能は疎結合にしよう!」という考えで作り出されました。 1980年代の頃のお話です。 それ自体は正しいです。 歴史を振り返ってみましょう Webシステムを「MVCに適用させ

    MVCがなぜ間違っているか? - SQLer 生島勘富 のブログ
  • 実行計画のキャッシュについて2 - 各RDBMSについて - SQLer 生島勘富 のブログ

    SQL文の動的生成を避けるには、実行計画のキャッシュを意識しなければなりません。 そこで、RDBMS毎にキャッシュのやり方が違いますからその違いと、「当はこういう構造にすれば良いのに」という提案について書きます。 目次 目次 各RDBMSの実行計画のキャッシュ MySQL PostgreSQL SQLServer Oracle Oracleはよくできているが逆! Oracleの処理の概要 私が欲しい処理 まとめ 各RDBMSの実行計画のキャッシュ MySQL 実行計画はキャッシュしない。 SQLと結果をキャッシュする。 PostgreSQL 実行計画のキャッシュはセッション単位。プリペアードステートメントにするとキャッシュする。 SQLServer 基的に実行計画をキャッシュする。 RECOMPILE オプションでキャッシュをキャンセルできる。 Oracle的に実行計画をキャッシ

    実行計画のキャッシュについて2 - 各RDBMSについて - SQLer 生島勘富 のブログ
  • もうちょっと「艦これ」からSQLを考えてみる3 - SQLer 生島勘富 のブログ

    前回の続き。 前回のパターンであれば、全体を(パフォーマンス・サーバの負荷・開発工数・メンテナンス性)を鑑みて、IF文と四則演算は、DBサーバより、APサーバ。APサーバより、クライアントにある程度キャッシュさせて、処理もクライアントで行った方が良いです。 そう判断するには、設計段階でSQLで処理したときどうなるか、SQLで処理しなかったときどうなるか。が正確に分かってないと判断できません。 例えば、「艦これ」からは随分と離れますが、あるテストの男子と女子、全体の平均と最高点・最低点を求めたいとする。(面倒なので性別は非正規化されているとする) テーブルは以下の通り 成績テーブル テストID 生徒番号 性別(1:男子、2:女子) 得点 1.SQLで処理する SELECT テストID , AVG(CASE WHEN 性別 = 1 THEN 得点 ELSE NULL END) AS 男子平均

    もうちょっと「艦これ」からSQLを考えてみる3 - SQLer 生島勘富 のブログ
  • もうちょっと「艦これ」からSQLを考えてみる2 - SQLer 生島勘富 のブログ

    前回の続き。 「艦これ」で起きた障害は、カタログスペックの100分の1以下の処理量で発生ししていると思われる。その原因はDBサーバに対する無理解、SQLに対する無理解から起きているのでは?という考察です。 もちろん、中身は知らないけれどね。 どこで処理するか? 少し昔話から。コンピュータシステムはざっくりと、 汎用システム クライアントサーバシステム Webシステム と発展してきました。 汎用システムの時代は、端末に処理能力がありませんでしたから、あらゆる処理をホストコンピュータが担っていました。これがクライアントサーバシステムになったとき、どちらで処理を行うかを考える必要が出てきました。 Webシステムになると、DBサーバ、APサーバ、クライアントのいずれもが処理能力を持ち、多くの処理をそれぞれが代替することができる。 開発時はDBサーバ・APサーバ・クライアントが1台のPCで行われるこ

    もうちょっと「艦これ」からSQLを考えてみる2 - SQLer 生島勘富 のブログ
  • 「艦これ」もう少し思い出して考えてみた - SQLer 生島勘富 のブログ

    艦これ」はあんまり関係ないのですが、スケールアウトについて。 「艦これ」は既に MySQL Cluster を使っているなら関係ないのですが、何度も書きますけれど、「JOIN禁止」はスケールアウトと関係ない。 Twitter規模になれば別の考え方が必要になりますが、取りあえず今は DBサーバ は1台だけれど、「スケールアウトのためにJOIN禁止」は「究極のバッドテクニック」ですのでやらないように! 単純だから良いも、複雑だから良いもない。 必要なのは効率的かどうかを考えることだけで、それはどんなシステムでも同じ。 「艦これ」は…… 「艦これ」は MySQL Cluster を使っているとのこと。私が始めた頃は、4・5個の鎮守府(サーバ群)があった様に記憶しています。 MySQL Clusterと聞いて、DBは1つのクラスタ構成で処理されていると思ったのですが、障害は鎮守府(サーバ群)単位

    「艦これ」もう少し思い出して考えてみた - SQLer 生島勘富 のブログ
    atm_09_td
    atm_09_td 2013/09/04
  • 「艦これ」から、ソーシャル系のサーバ構成を考える - SQLer 生島勘富 のブログ

    私は、ソーシャル系とは縁遠い仕事ばっかりしているのですが、そういう依頼も若干増えてきたので話題になっている「艦これ」をお盆にやってみた。 残念ながら、「艦これ」の魅力は分からなかった。しかし、ミッションを用意されると、「クリアーしたい」という欲求から意地になるのは、何となく理解できました。それより、同時に始めた「Clash of Clans」には嵌まりました。気になっていた「ゲームの中に如何に自然に課金システムを取り入れるか」という課題についても、個人的には「Clash of Clans」の方が上手に解決しているように思います。 「艦これ」は、同時アクセスが10万以上あって、何度かシステム障害があったとのこと(そりゃあるでしょうが……)。私の興味の方向性は、課金システムであったり、システム構成にあるので、「艦これ」のシステム障害の方が強い興味の対象になります(苦笑) というわけで、「ソーシ

    「艦これ」から、ソーシャル系のサーバ構成を考える - SQLer 生島勘富 のブログ
  • SQL文を組み立てるには?SQLが書ける様になるには? - SQLer 生島勘富 のブログ

    SQL文ができない人は、どこまでも文法で考えようとしている。 私が、SQLに違和感を感じずに理解することができたのは、文法を気にしてなかったからで、私の勉強法というか、どうやって習得してきたのかを整理してみました。 例えば IN と EXISTS の違い カラオケで説明します。 カラオケ10万曲から、とある曲リストと一致する曲を抽出するとします。 手続き型では、次のいずれかになるでしょう。(細かいところは端折るよ) Aパターン foreach (string 曲名 in 曲リスト){ 結果セット.add(カラオケ.find(曲名)); }Bパターン foreach (Song 曲 in カラオケ){ if(曲リスト.exists(曲.曲名)){ 結果セット.add(曲); } } Bパターンなんて使わないと思いますか? 「とある曲リスト」が「男性ヴォーカリストの曲」でも? COBOL世代の

    SQL文を組み立てるには?SQLが書ける様になるには? - SQLer 生島勘富 のブログ
  • SQL的(集合的)考え方と、ループ(手続き型)の考え方3 - SQLer 生島勘富 のブログ

    問題を少し変更 問題)部品在庫から、作成可能な製品の情報をとる。 ※来はマスタテーブルと組み合わすべきですが、ツールの関係上2テーブルしか同時に表示出来ないので名称で結合する形になります。 SQLで考えるなら という風に考えます。 言い換える 『在庫数が必要量を満みたす製品のみ』 → 『在庫数が必要量を満たさないレコードがある製品を削る』 『満たさない』= NOT EXISTS(あるいは、NOT IN) 答えは SELECT * -- 当は必要なもののみ FROM 部品表 AS bh INNER JOIN 在庫 AS zk ON bh.材料名 = zk.材料名 WHERE NOT EXISTS (SELECT * FROM 部品表 AS bh_s INNER JOIN 在庫 AS zk_s ON bh_s.材料名 = zk_s.材料名 WHERE bh_s.製品名 = bh.製品名 -

    SQL的(集合的)考え方と、ループ(手続き型)の考え方3 - SQLer 生島勘富 のブログ
  • SQL的(集合的)考え方と、ループ(手続き型)の考え方2 - SQLer 生島勘富 のブログ

    もう一度問題 問題)部品在庫から、作成可能な製品名をとる。 ※来はマスタテーブルと組み合わすべきですが、ツールの関係上2テーブルしか同時に表示出来ないので名称で結合する形になります。 SQLで考えるなら 答えは SELECT 製品名 FROM 部品表 INNER JOIN 在庫 ON 部品表.材料名 = 在庫.材料名 GROUP BY 製品名 HAVING MIN(在庫.数量 - 部品表.必要量) >= 0; 三枚の図になっていますが、考え方さえ理解していれば数十秒で答えまでたどり着けます。パターン認識じゃないので忘れてもどってことはないのです。 考え方としてはこんな感じになります。 必要なテーブルを引っ付け、ゴールを目指して削り出して行けば良い。 プラモデルと、彫刻の違いです。 言い換えは、他の言語より重要? プログラムも翻訳と同じですから、言い換えは必要です。 上の図の「SQL的思考

    SQL的(集合的)考え方と、ループ(手続き型)の考え方2 - SQLer 生島勘富 のブログ
  • SQL的(集合的)考え方と、ループ(手続き型)の考え方1 - SQLer 生島勘富 のブログ

    前回、勉強会に参加したときに感じたことの続き。 みんなはどう考えているか? この問題は正答率が低かった。答えを見たら「あぁ〜」ってなるレベルですが、なかなか、出てこないようです。 問題)部品在庫から、作成可能な製品名をとる。 ※来はマスタテーブルと組み合わすべきですが、ツールの関係上2テーブルしか同時に表示出来ないので名称で結合する形になります。 逆に、私には、なぜ、正答率が低いのか分からずに悩んでいました。そこに、SQLが流行らない理由があるんだろうけれど、私には分からないのです。私はタイピングが滅茶苦茶遅いので時間は掛かるのですが、頭の中では答えは何十秒かで出ています。 皆さんが難しいと感じるものを、私が数十秒で答えまでたどり着くのは経験の差じゃない。単純に考え方の違いと分かっているのですが、それをどう表現したら良いのか……、何年も考えているのですが、なにぶん、皆さんの考えていること

    SQL的(集合的)考え方と、ループ(手続き型)の考え方1 - SQLer 生島勘富 のブログ
  • 久しぶりに更新 - SQLer 生島勘富 のブログ

    昨日、SQLWorldの「みんなでSQLを書いてみよう」というハンズオンの企画の勉強会に参加した。 最初にお知らせ 次回の企画のために、「実務で困っているSQL」を募集するそうです。 「こんなのSQLで出来るの?」という問題があれば、コメントやメール info@g1sys.co.jp でご相談ください。 やっぱり、できた方が良いと思うよ 私の興味はSQLとは全く違うところに向いたけれど(苦笑)SQLについて、これだけマシンが速くなったら、パフォーマンスはあんまり拘らなくても良いかなとも思っているのですが、それでもできた方が工数的にもメリットが大きいと実感した。 特に、最後にやった問題は、実務ではもっとかなり複雑だけれど、その複雑な実務でもSQLで恐らく可能です。在庫とか、生産管理の山積み、山崩しなどの複雑な業務も、数個のSQLで可能ですが……。 しかし、現実にはグリグリ回してやることになる

    久しぶりに更新 - SQLer 生島勘富 のブログ
  • なぜごり押しなのか4 - SQLer 生島勘富 のブログ

    私は基的に、インターネット上の議論では個別の事情は挟むべきではない。と考えています。 私が個別の事情を挟んでいるとか、感情的とかいう人がいるけれど、全く逆です。 相手が【詐欺師レベル】と分かったとき、議論を打ち切って感情的に怒っているだけの話です。 できない人がいるは個別の事情。 私がSQLが得意だから推す。と考える人は、自分自身が得意なものを推そうとする人でしょう。ですから、そんなこと全く言ってない私の感情を、自分の感情で補完しているだけでしょう。自分の心の醜さが出ているだけです。 私はRDBMSを使う以上、SQLを使いきることが効率的であると言ってるに過ぎません。 ただし、以前にも書きましたが過ぎたるは及ばざるがごとし。例えば、【闇雲に】トリガーを仕込みまくったりしたら効率は確かに落ちます。【闇雲に】が重要であって【使ってはいけない】ではないのです。 私は当たり前のことしか言ってない

    なぜごり押しなのか4 - SQLer 生島勘富 のブログ
  • トリガーを自動生成2 - SQLer 生島勘富 のブログ

    前回の続き。 非正規化した項目の整合性を維持するトリガーをかいてみます。 トランザクションテーブルにトリガーを設定する。 例として、以下の様な受注明細があったとして、その非正規化項目の整合性を維持するトリガーを書いてみます。 CREATE TABLE T010_受注明細 ( ID             int IDENTITY(1, 1) NOT NULL, T000_ID           int NOT NULL, 受注CD           nchar(10) NOT NULL, 行番号           int NOT NULL, M000_ID           int, 製品CD           nvarchar(20) NOT NULL, 製品区分          nvarchar(10) NOT NULL, 製品基準日         datetime NO

    トリガーを自動生成2 - SQLer 生島勘富 のブログ
  • トリガーを自動生成1 - SQLer 生島勘富 のブログ

    トリガーの適応範囲はエクセルで出力できるところまでとすると、必然的にできることは限られます。関連チェックや整合性の維持に限られるでしょう。 まずは書いてみる。 以前書いたトリガーを少し修正してみましょう。(SQLServerで書きました。) トリガーを仕込むテーブル。 CREATE TABLE M000_製品 ( ID              int IDENTITY(1, 1) NOT NULL, CD              nvarchar(20) NOT NULL, 区分             nvarchar(10) NOT NULL, 名前             nvarchar(255) NOT NULL, ステータス          int NOT NULL, 有効期限開始         datetime NOT NULL, 有効期限終了         dat

    トリガーを自動生成1 - SQLer 生島勘富 のブログ
  • トリガーの勘所 -- 「自動的にやってくれる」と「勝手に変わった」 - SQLer 生島勘富 のブログ

    トリガーを嫌う人は非常に多い。 トリガーはレコードの更新を起点(トリガーにして)に自動的に動くので、アプリケーション側のプログラムソースからは追いかけられず、プログラマが意図しない結果になることがある。というのが嫌われる一番の理由でしょう。 しかし、「自動的に動く」というのは非常に便利で、多くのアプリケーションや、OS、IDE、(メタ)プログラミング言語が目指すところです。 では、なぜトリガーは異常に嫌われるのでしょうか。 「自動的にやってくれる」と「勝手に変わった」 トリガーは自動的に動くので非常に便利で、当たり前の制限はありますが何でもできます。「何でもできる」というのは曲者で、トリガーは作っている(コーディングしている)ときは非常に便利ですが「後で訳が分からなくなる」という「諸刃の剣」になる典型のテクニックです。 実際にプロジェクトで使わなくても、試しに使ったぐらいで「諸刃の剣」ぶり

    トリガーの勘所 -- 「自動的にやってくれる」と「勝手に変わった」 - SQLer 生島勘富 のブログ
  • 効率の山は複数回訪れる。 - SQLer 生島勘富 のブログ

    正規化の効率を考えてみる。 正規化は基的な技術ですが、COBOLから抜けきれていないと正規化すると遅くなると感じる様になる。 これはおそらく私もだろうと思うけれど、効率をグラフ化して最初に訪れた山が最高と感じるものです。それはつまり、落ち始めたらそれ以上は危険と判断するからで、その先に進めなくなる人が非常に多い。 イメージとしてはこんな感じになります。 COBOLから始めた人は、最初に訪れる効率の山が全体としては極めて低くても、それが最高と判断してしまう。実際にCOBOLから始めた人が大半を占めるプロジェクトでは決して珍しくない光景です。 壁から先は見えてないから、COBOLからスタートした人達が見ているのはここまでです。その先は見えていません。 この曲線は、スポーツでも、勉強でも、何にでもあるものですが、いわゆる『壁』ってヤツです。最初に訪れた効率の山をくだるのは非常に怖く辛い。その先

    効率の山は複数回訪れる。 - SQLer 生島勘富 のブログ
  • OLAP(分析)関数について -- 完成 - SQLer 生島勘富 のブログ

    前回の続きです。やっと完成です。 ざっくりとした考え方(毎回) GROUP BY は集約するので、結果が(集約キーを出力すれば)一意になる。つまり、出力される結果が一意になるまで集約される。 しかし、OLAP(分析)関数は、SELECTされた結果を区切って処理する。そのため、レコード数に変化はない。 集約する → GROUP BY 区切る → PARTITION BY となる。これだけが分かっていれば実は簡単です。 SQLの完成。 拡大する 前回説明したように、OLAP(分析)関数を使ってイメージの通り順に考えて行くと、サブクエリーの中には不要なものも入っていますが、以下の様なSQLが完成します。 SELECT 納品書番号, 行, 商品ID, 単価, 数量, 消費税率 , 明細計, 納品書合計金額, 納品書消費税額 , CASE WHEN ABS(消費税誤差) >= 金額の多い順 THEN

    OLAP(分析)関数について -- 完成 - SQLer 生島勘富 のブログ
  • OLAP(分析)関数について -- OLAP(分析)関数はSELECT句で並び替え - SQLer 生島勘富 のブログ

    前回の続きです。やっとOLAP(分析)関数までたどり着きました。 ざっくりとした考え方(毎回) GROUP BY は集約するので、結果が(集約キーを出力すれば)一意になる。つまり、出力される結果が一意になるまで集約される。 しかし、OLAP(分析)関数は、SELECTされた結果を区切って処理する。そのため、レコード数に変化はない。 集約する → GROUP BY 区切る → PARTITION BY となる。これだけが分かっていれば実は簡単です。 納品書合計金額までをOLAP(分析)関数で計算する。 OLAP(分析)関数で処理すると SELECT 納品書番号, 行, 商品ID, 単価, 数量, 消費税率 , 単価 * 数量 AS 合計 , ROUND(単価 * 数量 * 消費税率) AS 明細毎の消費税 , SUM(単価 * 数量) OVER (PARTITION BY 納品書番号) AS

    OLAP(分析)関数について -- OLAP(分析)関数はSELECT句で並び替え - SQLer 生島勘富 のブログ
  • OLAP(分析)関数について -- その前にサブクエリーで処理 - SQLer 生島勘富 のブログ

    前回の続きです。 ざっくりとした考え方(毎回) GROUP BY は集約するので、結果が(集約キーを出力すれば)一意になる。つまり、出力される結果が一意になるまで集約される。 しかし、OLAP(分析)関数は、SELECTされた結果を区切って処理する。そのため、レコード数に変化はない。 集約する → GROUP BY 区切る → PARTITION BY となる。これだけが分かっていれば実は簡単です。 イメージを確認。 ■要望 ■納品書明細(テーブル) 納品書番号 行 商品ID 単価 数量 消費税率 というテーブル構造にで、消費税率は一律5%が入っています。 消費税は、納品書単位に金額を合計したものに消費税率を掛け、四捨五入して請求しています。 しかし、経理上、明細毎の消費税額が必要になり、明細単位に四捨五入すると、請求した消費税との誤差が発生します。 その誤差を明細合計金額の多い順に1円ず

    OLAP(分析)関数について -- その前にサブクエリーで処理 - SQLer 生島勘富 のブログ
  • サロゲートキーは後付けでもできる。 - SQLer 生島勘富 のブログ

    業務システムのほとんどはナチュラルキーで構築されていると思います。 しかし、シノニムやトリガーを利用すれば、既存システムを変更することなくサロゲートキーを追加して、それ以降、サロゲートキーによる運用も可能になります。手順は以下の通りです。 元のテーブル 以下の3つのテーブルをサロゲートキーによる運用に変更します。 ■ Foods 料理マスタ 物理名論理名備考 CD料理CD主キー Name名前 Price価格 …… ■ Ingredients 材料マスタ 物理名論理名備考 CD材料CD主キー Name名前 Cost_Price材料費 …… ■ Recipes レシピマスタ 物理名論理名備考 Food_CD料理CD主キー(複合) Ingredient_CD材料CD主キー(複合) Quantity使用量 …… IDカラムを付加する。 現在のテーブル名にIDを採番したシノニムを作成し、全部のテーブ

    サロゲートキーは後付けでもできる。 - SQLer 生島勘富 のブログ