- 投稿日:2021-03-29T18:21:23+09:00
DockerイメージのMySQL5.6と5.7はタイムゾーン設定が異なる
MySQL5.6から5.7に移行するにあたって、開発環境を整理していたらDockerイメージのデフォルトのタイムゾーンが変わっていることに気付いた。
MySQL 5.6のタイムゾーン設定
5.6のデフォルトのタイムゾーンは以下の通り設定されていた。
mysql> show variables like '%time_zone%'; +------------------+--------+ | Variable_name | Value | +------------------+--------+ | system_time_zone | UTC | | time_zone | SYSTEM | +------------------+--------+ 2 rows in set (0.00 sec)そのため、Dockerfileで以下のコマンドを実行して、タイムゾーンを変更していた。
RUN cp -p /usr/share/zoneinfo/Japan /etc/localtimeMySQL 5.7のタイムゾーン設定
5.7のデフォルトのタイムゾーンは以下の通りだった。
mysql> show variables like '%time_zone%'; +------------------+--------+ | Variable_name | Value | +------------------+--------+ | system_time_zone | JST | | time_zone | SYSTEM | +------------------+--------+ 2 rows in set (0.00 sec)system_time_zoneがロケールの時間帯を採用するように変更されたらしい。
これによって最初から日本時間で処理されるようになった。
- 投稿日:2021-03-29T16:36:17+09:00
SQL テーブルの結合
こちらの記事では、私が学んだSQLについて記載しております。
自身の忘れないためのメモとしております。
間違っている部分もあるかもしれませんので、ご了承ください。テーブルの結合とは
テーブル同心をある条件で結合することにより、[正規化なし]の状態を作り出すこと。
テーブルの[正規化]は重要!!
・データ管理が容易になる
・データ容量の削減
→特別な意図がなければ、データは正規化する。例 ユーザー情報の中で都道府県のデータを取得する際に ”文字列”でデータを保存してしまうと、データに負荷がかかる。 テーブルは別にして、都道府県のみのデータにすることで、”文字列”をまとめられる。 [正規化なし] テーブルusers id name 都道府県 1 田中 大阪 2 鈴木 大阪 3 佐藤 大阪 [正規化あり] テーブルusers テーブル都道府県 id name 都道府県 id 都道府県 1 田中 2 1 東京 2 鈴木 2 2 大阪 3 佐藤 2 3 京都 テーブルを分け正規化することで、データ管理がしやすくなり、容量を削減可能。 もし今後、都道府県の「大阪」が「太田」と変更された場合でも、テーブル都道府県の変更を行えばすぐに対応可能になる。内部結合 inner joinで結合可能
***記述方法*** select テーブル名a.id, テーブル名b.表記したいカラム名 ←テーブル名b.nameなど from テーブル名a inner join テーブル名b on テーブル名a.id = テーブル名b.a_id; ←2つのテーブルのidを結合する ***テーブル名は省略も可能*** テーブル users, orders select u.id, u.name, o.name from users u ←users as uとして変更可能。asは省略も可能なので左のような記載になる。 inner join orders o on u.order_id = o.id;外部結合 left outer join/right outer join
inner joinではnullは表記せず、left outer joinではnullも表記する
select u.last_name, u.id, o.user_id, o.id from users u -- inner join left outer join orders o on u.id = o.user_id order by u.id;3つ以上のテーブルの結合 inner join連続で記述
テーブル users, orders, orders_details select u.id, u.name, o.name, od.price from users u inner join orders o on u.order_id = o.id inner join orders_details od on od.order_id = o.id; 一対多もしくは多対多の関係は、確認して行うこと!!!テーブルの足し算 union/union all
テーブル1とテーブル2で列数(カラム名)を合わせる必要があります!! テーブル users ,adomin select email, name, gender from users union ←unionのみだと重複は省略。union allだと重複も表記される。 select email, name, gender from admin ; ***条件分岐*** order byのみ全体の1つしか記述できない!!!!!!! select email, last_name, first_name, gender from users where gender = 1 union select email, last_name, first_name, gender from admin_users where gender = 2 order by gender ←order byは全体記述の最後! ;補足
主キー/外部キー
・主キー・・1つの行を特定できる列(カラム)のこと
・外部キー・・・他のテーブルの関連付けに使う列(カラム)のこと記述順序
記述順序 実行順序 select・・・・・取得カラムの指定 from・・・・・・・対象テーブルの指定 from・・・・・・・対象テーブルの指定 結合処理 結合処理 where・・・・・・絞り込み条件式の指定 where・・・・・・絞り込み条件の指定 group by・・グループ化の条件を指定 group by・・グループ化の条件指定 having・・・・・グループ化した後の絞り込み条件を指定 having・・・・・グループ化した後の絞り込み条件指定 select・・・・・取得カラムの指定 order by・・・並び替え条件指定 order by・・並び替え条件を指定 limt・・・・・・・・取得する行数の制限 limit・・・・・・取得する行数の制限
- 投稿日:2021-03-29T13:04:34+09:00
【MySQL】複数のカラムで重複しているデータを見つける方法
データ解析に使ったので、メモ
サブクエリ内では、countを実行するだけ。
メインクエリ内では、countが1以上のものは重複していると言えるので、以下のような形でできる。select * from ( select concat(column1, '-', column2) as token, COUNT(*) as cnt FROM table_name GROUP BY (token) ) as contents WHERE cnt > 1;解析に使っただけだが、実際のプロダクションコードとしてで扱うには、あまりよくない気がする。
- 投稿日:2021-03-29T11:59:27+09:00
【JDBCドライバ】MySQL Connector/J 8.0ダウンロード手順
はじめに
自身がJava学習中にDB接続の環境を整える際に悩んだので、
JDBCドライバのダウンロードから環境のセットアップまでを記載します。使用環境
開発環境:paizacloud
Javaバージョン:13.0.1
Apache Tomcatバージョン:9.0.41
DB:MySQL
JDBCバージョン:8.0.231.JDBCのインストーラーダウンロード
![]()
![]()
![]()
![]()
2.インストーラ起動
![]()
3.connect/Jをダウンロード
C:\Program Files (x86)\MySQL\Connector J 8.0\mysql-connector-java-8.0.23.jar4.jarファイルを配置
ダウンロードしたドライバ(jarファイル)をWEB-INF\libに配置する。
5.Javaには下記のように記載する。
ドライバ名がバージョンで異なるそうです。
ドライバのバージョンが8.0系の場合
Class.forName("com.mysql.cj.jdbc.Driver");※ドライバのバージョンが8.0系よりも前の場合
Class.forName("com.mysql.jdbc.Driver");参考
- 投稿日:2021-03-29T08:07:36+09:00
税込から税抜を求めるには切り上げ?切り下げ?→ケースバイケースで要注意な件
4月から税込み表示が義務化され、また世のエンジニアが苦労する中、逆に税込から税抜を求めるの思った以上に苦労した話です。
一般的な小売では税込から税抜を求める状況はないと思いますが、相対取引で定価が無い場合は税込価格から決まることはザラです。具体例として
10096円〜10099円
の間の価格でお話ししますと
10097円は÷1.1して切り捨てた9179円が正解です。
10099円は÷1.1して切り上げた9181円が正解です。なぜなら双方とも誤って切り上げたり、切り下げると共に9180円になり、そこから税込価格を逆算すると10098円一択となってしまい元に値と矛盾するからです。ちなみに
10098円は割り切れる整数なので、切り捨て切り上げ関係なく、9180円の一択になります。
10096円は切り捨てて9178円、切り上げて9179円としてどちらでも良いのですが、それらからの税込み価格の計算は、端数の取扱次第で10095〜10097円まで幅広く解釈することができます。これらを踏まえ実装としては、税抜価格netが最大化する按分になるceilでまず計算してみて、そこから税込の逆算が矛盾を起こす場合のみ、floorを採用する条件分岐が必要になります。
MySQLなら以下の通りです。mysql> SELECT -> taxed, -> case when floor(ceil(taxed/1.1)*1.1)=taxed or ceil(ceil(taxed/1.1)*1.1)=taxed then ceil(taxed/1.1) else floor(taxed/1.1) end as net -> FROM ( -> SELECT 10096 AS taxed UNION -> SELECT 10097 AS taxed UNION -> SELECT 10098 AS taxed UNION -> SELECT 10099 AS taxed -> ) prices; +-------+------+ | taxed | net | +-------+------+ | 10096 | 9179 | | 10097 | 9179 | | 10098 | 9180 | | 10099 | 9181 | +-------+------+ 4 rows in set (0.01 sec)MySQLは問題ありませんでしたが、実装には浮動小数点の問題があり要注意です。
端的に以下に例示すると100円の税込みは110円のはずですが、どちらも111円になります。体感的にはもはやバグです。JavaScriptによる例Math.ceil(100*1.1) // 111pythonによる例import math math.ceil(100*1.1) # 111このリスクに対応するため8桁以降を丸めた処理を挟んで以下のようになりました。
pythonによる例from math import floor, ceil {taxed: ceil(round(taxed / 1.1, 8)) if floor(round(ceil(round(taxed / 1.1, 8)) * 1.1, 8)) == taxed or ceil(round(ceil(round(taxed / 1.1, 8)) * 1.1, 8)) == taxed else floor(round(taxed / 1.1, 8)) for taxed in [10096, 10097, 10098, 10099]} # {10096: 9179, 10097: 9179, 10098: 9180, 10099: 9181}1万円までの全価格を走査して統計とったスクリプトを書いたので、貼っておきます。
価格(整数)の集合全体の8割は割った後に切り上げ切り下げどちらでも良いのですが、残り1割ずつは切り上げ限定か切り下げ限定の困ったちゃん価格なのが分かります。from math import floor, ceil import pprint result = {} for taxed in range(100, 10100): recalc = { "FF": floor(round(floor(round(taxed / 1.1, 8)) * 1.1, 8)), "CF": floor(round(ceil(round(taxed / 1.1, 8)) * 1.1, 8)), "FC": ceil(round(floor(round(taxed / 1.1, 8)) * 1.1, 8)), "CC": ceil(round(ceil(round(taxed / 1.1, 8)) * 1.1, 8)), } key = tuple(k for k, v in recalc.items() if v == taxed) if len(key) == 0: print(taxed) raise result[key] = [*result.get(key, []), taxed] print(taxed, key, recalc) pprint.pprint({k: { "min": min(v), "max": max(v), "len": len(v), } for k, v in result.items()})税抜き価格の計算は税率で割って丸めるだけ、そんなふうに考えていた時期が俺にもありました。。。