やる気がストロングZERO

やる気のストロングスタイル

DB

SQL実践入門を読んだ

SQL実践入門気になってたので読んだ。 かなり体系的に理解できて良かった。 読み切ってしまってから記憶だけで振り返ってるので内容に間違いなどはあるかも。 気になる場合は読んでみることをおすすめします。 SQL実践入門 ──高速でわかりやすいクエリの書き…

トランザクション分離レベルについて復習

トランザクション分離レベルについて認識している事を復習をかねてまとめる。 web上で寄せ集めた知識なので、厳密に合ってるのかどうかの保証はない。ざっくり。 トランザクション分離レベルとは DBは複数の処理を同時に実行することが求められるので並列で…

行われている処理がイメージできるようなテーブル構造を設計したい

見れば行われている処理がイメージできるようなテーブル構造を設計するのが良いと思っている。 このテーブル構造で何が読み取れるか? user id state 1 active 2 active 3 disactive ... ... userはステータスを持っているのはわかる。 データを見るとほとん…

性別カラムを1,2で用意するとき、1が男, 2が女だという情報をどこに持つか

性別カラムを1,2で用意するとき、1が男, 2が女だという情報をどこに持つか。 user情報テーブルに性別カラムを用意して男女を1or2で保持させる場合、1が男、2が女である情報をどこに持つのがよいか以前議論になったのを思い出した。 システムで「性別」の情報…

【テーブル設計】削除フラグを使わず削除テーブルを使うべき

データの削除機能において、何らかの理由でデータは残しておきたい場合には「削除フラグ」が使われがちだが、これは絶対にやめたい。 この場合は「削除テーブル」を用意してそちらにデータを移し、元テーブルからはレコード削除を行うようにするべきだと思っ…

【Golang】sql.Open(), Close()を呼ぶタイミング・場所について考えた

GoでDBアクセスする為のサンプルコードを探すとどこもこんな感じ func main() { # dbコネクション(pool)を取得 pool, err = sql.Open("driver-name", *dsn) if err != nil { // This will not be a connection error, but a DSN parse error or // another i…

アプリケーション要件に関わらずテーブルには事実を記録する

「このアプリケーションのこの機能は【年月日】までしか意識しない。【時分秒】はデータとして不要なのでテーブルにはdate型で【年月日】だけ持たせれば良い。」 と言われた事があったが例えアプリケーションにとって不要でもDBテーブルにはdatetimeとかtime…

扱いやすいテーブル・扱いにくいテーブル

システムのDBには様々なテーブルが定義されている。 色々作業していると「扱いやすいテーブル」「扱いづらいテーブル」がある事に気がつく。 なんとなく見えてきたパターンについて書いてみる。 ※もしかしたら当たり前の知識なのかもしれないが、自分の観測…

重複Insertを防ぐ(postgreSQL)

例えばユーザー名の重複登録をNGとする場合、こんな感じでバリデーションと登録処理を書くことが多い。 ※疑似コードです begin name = "山田太郎" // dbからデータを取ってみて存在しないことを確認する user = getUserByName(name) if user != null { retur…

「シンプルな構造にすれば保守性があがる」わけではないという話

こんがらがったシステムの保守開発で苦労した経験から新規開発では「シンプルな構成・シンプルな実装にしよう」という話が出る。 目指す方向としては間違って無いように思えるのに、それだけだとうまく行かない。 「保守しやすい構造」とはそれなりに多くの…

やっぱり正規化をベースにしたテーブル設計しか勝たん

テーブル設計は正規化を基本にして設計する手法しか成功しない気がしてる。 DBやテーブル設計系の書籍を読むとどれにも「正規化」による設計手法が書かれているけど、現場ではなぜかあまり正規化に重きをおいた設計が行われていない場合が多かった。 先人の…

PostgreSQLでのトランザクション分離レベルの使い分けを考えた

標準としてのトランザクション分離レベルは一応把握してたけど、MySQLやPostgreSQLとか、実装によって結構事情が異なっててそのあたりあまり理解できてなかったのでPostgreSQLにおいてのトランザクション分離レベルを学び直した。 ※参考にしたのはこのあたり…

【テーブル設計】フルネームで保持しているカラムを後から「名字・名前」に分けたい時

フルネームで保持しているカラムを後から「名字・名前」に分けたい時、どうすればいいか考えてみた。 出来たと思うけど、脳内シミュレーションしただけで実際にシステムに対して行ったことがあるわけではないので、もしかしたら穴があるかも。 サンプルケー…

【Go】gorpにdecimal型を認識させる

経緯 データベースライブラリにgorpを使ってみている。 gorpでは(gorpというより、database/sqlの範疇かも)Goのint型はDBのintと、GoのstringはDBのtextやvarcharと、みたいに自動的にマッピングされて意識しなくてもデータやり取りができる。 Goには標準…

テーブル数が増えることを避けた末路(シミュレーション)

テーブルの正規化を理由にテーブルを増やす提案をしたら嫌がられた記憶がある。 「なるべくテーブルを増やしたくない。たぶんカオスになる」という考えっぽいけど、これは正しく設計されずに不要なテーブルを作成されまくってしまったケースの経験が元になっ…

【テーブル設計】利便性のために余計なデータを持たせるのはアンチパターン

テーブルに見やすさや利便性などの為に余計なデータをもたせるのはアンチパターンだと思った。 ※アンチパターンというか、普通に駄目だと思う。 サンプルケース 以下のようなテーブルを使って社員情報を管理しているとする。 (会社テーブルを自己参照にすべ…

tableのstateカラムはアンチパターン(だと思う)

DBテーブルにstateカラムを用意して、stateを更新していくような作りは良くないと思ってるので理由を書く。 サンプルケース Aフォルダに大量のファイルが入っており、1時間に1回、1つのファイルをBフォルダにコピーする定時実行処理があるとする。 テーブル …

【DB】テーブル集計結果を別テーブルに持たせたくない

DBからデータを集計し、新たなデータを生んで保存するようなことをしたくないと思っている。 サンプルケース 家計簿システムがある。 お金の出入りがあったらその日に金額を入力し保存する。 月集計と年収計が確認できる。 [実装] 金額入力をしたらdailyテー…

【テーブル設計】売上詳細データをどう持つか

状況 2019/01/01にスーパーボールを100円で「たかし」に販売した。 初期テーブル設計 商品マスタ id 商品名 価格 1 スーパーボール 100 ユーザーマスタ id 名前 10 たかし 売上詳細 id ユーザーid 商品id 販売価格 販売日 100 10 1 100 2019-01-01 正規化し…

DBスペシャリストの問題で出てくる「テーブルサイズ見積もり計算」の解き方

必要になる数値 [見積もり行数(行)] テーブルの総行数の見積もり。 そのテーブルが最大でどれくらいの行数になるのかの見積もり [平均行サイズ(バイト)] テーブルの行長が可変の場合、そのテーブルの平均行サイズ [ページサイズ(バイト)] 扱われるデー…

DBスペシャリスト勉強メモ

候補キーを全て洗い出す問題 ※推移的関数従属や部分関数従属があればそれも記載するような問題 言葉に馴染みがないので何を問われているのかがそもそもわからなかったりした。 候補キーとは 候補キーとは「主キーとなる候補」の事らしい。 「主キーになる候…

【PostgreSQL】 online alter tableを考える

Django migrationをオンラインで行えるのかどうか考えていた。 オンラインで行えるのかどうかはDjangoのmigrationコマンドの問題ではなく、使っているDB(今回の場合だとPostgreSQL)がどのようにロックを行うのかによるということがわかった。 では具体的に…

テーブル設計:ある項目によって保存したいデータ内容が変化する場合

SQLアンチパターン:EAV(エンティティ・アトリビュート・バリュー) - やる気がストロングZERO ↑ここで書いた事と同内容。 例えばペットの種類によって保存したい内容が異なる場合 例) 犬:名前、鳴き声、リードの色、小屋の色 猫:名前、鳴き声、毛色、し…

SQLアンチパターン:EAV(エンティティ・アトリビュート・バリュー)

SQLアンチパターンを読んだ。とても良かったです。 SQLアンチパターン作者: Bill Karwin,和田卓人,和田省二,児島修出版社/メーカー: オライリージャパン発売日: 2013/01/26メディア: 大型本購入: 9人 クリック: 698回この商品を含むブログ (46件) を見る 「S…

トランザクション内で「重複チェック」してから「DB登録実行」しても重複が発生する場合がある

例えば「ユーザー名」など重複を許さない項目はDBへ登録クエリを投げる前にバリデーションで重複チェックするが、普通にやっていると「重複チェックをパスしたのに、DB登録実行時点では重複が発生している」となるケースが存在する。 「重複チェック」と「DB…

トランザクション分離レベル Serializableでも同時実行でエラーがでる可能性がある

やりたかったこと IDが重複しないことを確認してから、DBにレコードを追加したかった。(IDの自動インクリメントは使わないものとする) ユニーク制約があるので、重複登録しようとしてもエラーになるのだが、 予めチェックしてエラーにならないようにしたか…