質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.77%

SQLで単位付き数値の扱い方

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,068

huk66361

score 8

 実現したいこと

単位付き数値を持つデータの扱い方について、ご意見をいただきたいです。

 発生している問題

以下のような数値とその単位の情報を持つカラムやテーブルが複数あり、見にくくなっています。
単位を揃えてやればいいのでしょうが、単位も記録しておきたいので、このような形をとっています。

fruits テーブル

name     height   unit_of_height   width   unit_of_width
apple    100      mm               200     cm
banana   300      dm               400     m

 試したこと 1

単位付き数値として格納してみました。
カラム数が減り、すっきりしましたが height と width が数値ではなく文字列になったので計算が大変そうです。

fruits テーブル

name     height    width
apple    100mm     200cm
banana   300dm     400m

 試したこと 2

長さを別テーブルにしてみました。
height と width は、それぞれ lengths の id に紐付いています。

fruits テーブル

name     height   width
apple    1        2
banana   3        4

lengths テーブル

id   unit   value
1    mm     100
2    cm     200
3    dm     300
4    m      400

 補足

でてくる単位はその4つに限られますか、それとも任意で入力されてくるものですか。

いいえ、選択肢が用意されていて、その中から選びます。

単位は同じ単位系のみですか?つまりメートル系ならメートル系のみでヤード系とは混ざらない?

はい、メートル系であれば、そこに設定できるのはその単位系だけになります。

もう少し用途を明確にした方が良いです。単位を保存する意味がわからないし、数値にこだわる(どのような計算をする?)意味もわからないです。

言葉足らずですみません。
単位を保存する理由は、入力フォームの単位を揃えてしまうと、その単位に馴染みがないユーザーが扱いづらいというだけです。
計算は、プログラムで単位を揃えて足し算や引き算を行い、任意の単位で結果を返します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kaz.Suenaga

    2018/10/01 19:51

    でてくる単位はその4つに限られますか、それとも任意で入力されてくるものですか。

    キャンセル

  • papinianus

    2018/10/01 19:52

    単位は同じ単位系のみですか?つまりメートル系ならメートル系のみでヤード系とは混ざらない?

    キャンセル

  • ssasaki

    2018/10/01 19:56

    もう少し用途を明確にした方が良いです。単位を保存する意味がわからないし、数値にこだわる(どのような計算をする?)意味もわからないです。

    キャンセル

  • huk66361

    2018/10/01 20:25

    ご質問ありがとうございます。補足を追加させていただきました。

    キャンセル

回答 4

+3

回答は複数ありそうですが一案としてです。

  • 基準とする単位を決める(例えば「mm」)
  • 単位のマスタとして、 単位 - 基準とした単位で換算した値 のテーブルを作る
  • 質問の「fruits」テーブルの単位とそのマスタを結合して、数値と基準とした単位で換算した値をかけ合わせる

ことで、基準単位での値が取得できるかと思います。

例)

units テーブル

 unit   value 
 mm     1     
 cm     10    
 m      1000  

SQL

SELECT
  name,
  height,
  unit_of_height,
  unit_of_height * U1.value AS unit_of_height_by_mm ,
  width,
  unit_of_width,
  unit_of_width * U2.value AS unit_of_width_by_mm ,
From
  fruits
  LEFT JOIN units U1 ON fruits.unit_of_height = U1.unit
  LEFT JOIN units U2 ON fruits.unit_of_width = U2.unit

みたいな感じです。
(テストしていないのでケアレスミスはあるかも)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/01 20:52

    ご回答ありがとうございます。
    units テーブルを使った計算方法、非常に参考になります。
    この場合も fruits テーブルに単位を記録する方法がいいということですね。

    キャンセル

  • 2018/10/01 20:58

    実際にどのようにデータを扱うのかによって正解は違うかもしれませんがここで提示されている範囲であればレコードごとに単位の情報が必要なのは間違いないので、別のテーブルにする意味はあまりないと思います。

    > 単位を保存する理由は、入力フォームの単位を揃えてしまうと、その単位に馴染みがないユーザーが扱いづらいというだけです。
    > 計算は、プログラムで単位を揃えて足し算や引き算を行い、任意の単位で結果を返します。

    ということであればフォームに出力する際に必要なデータが fruits テーブルだけで完結しますし。

    キャンセル

checkベストアンサー

+2

計算が絡む以上、DB 側の数値の単位をあわせないという選択肢は無いと思います。
単位を気にする理由がまだあまり明確ではないと思うのですが、、、

ユーザーが入力する際に好きな単位を指定したい
→フォームでは好きに選択させ、DB に書き込む時にシステム側で決まった単位に変換してやればよい

ユーザーが見やすい単位で表示したい
→プログラム側で DB から取得した値を、ユーザーの指定する単位に変換して表示してやればよい

ということで、普通の用途であれば DBに単位を持つこと自体が不要にも思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/01 20:44

    ご回答ありがとうございます。
    数値は入力後にも変更が可能で、次回以降の入力時に前回と同じ単位で入力させたいので必要です。

    キャンセル

  • 2018/10/01 20:57 編集

    > プログラム側で DB から取得した値を、ユーザーの指定する単位に変換して表示してやればよい
    なるほど。
    次回以降の入力時、フォーム側でユーザーが指定した単位に数値を直せば、確かに単位なしで記録できますね。

    キャンセル

+1

普通に単位は単位で書いて、残りはmで保存すればよいのでは

name height unit_of_height width unit_of_width
apple 0.1 mm 2 cm
banana 30 dm 400 m

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/01 20:44

    ご回答ありがとうございます。
    1テーブルのカラム数が多くなり見にくいのですが、やはり、この方法が一番いいのでしょうか。

    キャンセル

+1

SQLをシンプルに記述し、パフォーマンスが良いようにするため、ひとつのカラムにはひとつの意味しか持たせてはならない、って掟があります。
カラム数が多いと思ったからと言って数値と単位をひとつのカラムにまとめたら、実際に使う時に数値と単位を分ける必要がありますから、無駄にSQLが複雑になり保守性も悪くなります。

テーブルは一度作ったら変更するとSQLもそのSQLを使っているプログラムも変更しなければなりません。システムが完成した後のテーブル設計の変更は負荷が大きいので、最初からきちんと設計しなければなりません。
DB論理設計の手順とチェックポイント

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.77%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る