<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>MySQL &#8211; エンジニア見習い</title>
	<atom:link href="https://otonan-syusyoku.work/archives/tag/mysql/feed" rel="self" type="application/rss+xml" />
	<link>https://otonan-syusyoku.work</link>
	<description>三流プログラマー</description>
	<lastBuildDate>Sat, 22 Feb 2025 05:59:22 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://otonan-syusyoku.work/wp-content/uploads/2023/10/cropped-名称未設定のデザイン-16-32x32.png</url>
	<title>MySQL &#8211; エンジニア見習い</title>
	<link>https://otonan-syusyoku.work</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>【設定しましょう】RDS for MySQL のパラメータグループ</title>
		<link>https://otonan-syusyoku.work/archives/1829</link>
					<comments>https://otonan-syusyoku.work/archives/1829#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Wed, 14 Aug 2024 05:36:57 +0000</pubDate>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[インフラ]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[MySQL]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=1829</guid>

					<description><![CDATA[RDS新規立ち上げ時に default パラメータグループを設定している方が多いと思うのですが、default パラメータグループだと色々まずい問題があるのでそれやめましょうというお話をさせて頂ければと思います。 困った [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>RDS新規立ち上げ時に default パラメータグループを設定している方が多いと思うのですが、default パラメータグループだと色々まずい問題があるのでそれやめましょうというお話をさせて頂ければと思います。</p>
<h2>困った話</h2>
<p>slow-query が検出できなくて困ったなぁと言うのが事の発端です。</p>
<p>考えてみると<span class="sc_marker blue"><strong>AWSさんが用意してくれたとりあえずdefaultパラメータを当てておけば問題ない</strong></span> だろうと考えてしまっていたのが大問題でした。</p>
<p>プロジェクトごとにDB周りの設定は変わってくるのは当たり前の話なので、自分のプロジェクトにとって必要な設定値を用意しなかった自分が100%悪いです。</p>
<p>反省です。</p>
<h2>最低限の設定値</h2>
<h3>max_execution_time</h3>
<h4>概要</h4>
<p><span>ミリ秒単位での SELECT ステートメントの実行タイムアウト</span></p>
<h4>値</h4>
<p>ミリ秒になるので <strong>指定したい秒数*1000 </strong>を指定してあげると良い。</p>
<p>例）60秒で切りたい<br />
60 * 1000 = 60000</p>
<h3>general_log</h3>
<h4>概要</h4>
<p>一般ログの出力</p>
<h4>値</h4>
<p>1に設定しましょ</p>
<h3>slow_query_log</h3>
<h4>概要</h4>
<p>slow query のログを出力するか否か</p>
<h4>値</h4>
<p>1に設定しましょ。これで出力するという意味になるよ</p>
<h3><span>long_query_time</span></h3>
<h4>概要</h4>
<p><span>ログに記録されるクエリの最短実行時間の値を設定することが出来る。<br />
この値を超えるとslow</span></p>
<h4>値</h4>
<p>基本的に `max_execution_time` より小さくしましょう。検出できなくなるので。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/1829/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>UbuntuにてMySQLコマンドだけ使いたい場合の備忘録</title>
		<link>https://otonan-syusyoku.work/archives/1446</link>
					<comments>https://otonan-syusyoku.work/archives/1446#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Sun, 17 Dec 2023 11:56:09 +0000</pubDate>
				<category><![CDATA[インフラ]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[LAMP]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[RDS]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=1446</guid>

					<description><![CDATA[ワシはRDSに繋げたいだけなんじゃ！ 先日 RDS を構築した際に EC2 と接続ができなくて泣きたくなった。 原因はシンプルで EC2 に MySQL クライアントが存在しませんよという内容です。 クラウド先（RDS） [&#8230;]]]></description>
										<content:encoded><![CDATA[<h2>ワシはRDSに繋げたいだけなんじゃ！</h2>
<p>先日 RDS を構築した際に EC2 と接続ができなくて泣きたくなった。</p>
<p>原因はシンプルで <span class="sc_marker blue"><strong>EC2 に MySQL クライアントが存在しませんよ</strong></span>という内容です。</p>
<p>クラウド先（RDS）には MySQL が存在しているのに、わざわざ EC2 に MySQL 本体をインストールするのもなぁと思っていたのですが、ちょっと工夫するだけで EC2 から接続できるようにすることができることを知ったので共有ですぅぅぅ〜</p>
<p>[getpost id=&#8221;1426&#8243; cat_name=&#8221;1&#8243; date=&#8221;0&#8243;]</p>
<p>[getpost id=&#8221;1448&#8243; cat_name=&#8221;1&#8243; date=&#8221;0&#8243;]</p>
<h2>いざ実践</h2>
<ul>
<li>とりあえずアプデ
<pre class="line-numbers"><code class="language-other">sudo apt update
</code></pre>
</li>
<li>mysql-client のパッケージを検索<br />
なんかいい感じのやつ出てくるよ</p>
<pre class="line-numbers"><code class="language-other">apt search mysql-clien</code></pre>
</li>
<li>最小を入れたい<br />
(お使いのバージョンに合わせたものを指定してね<br />
(client を入れれば MySQL コマンドが使えるよ</p>
<pre class="line-numbers"><code class="language-other">apt install mysql-client-core-8.x</code></pre>
</li>
<li>MySQL に接続
<pre class="line-numbers"><code class="language-other">mysql -h rds.amazonaws.com -P 3306 -u rds -p</code></pre>
</li>
</ul>
<h2>失敗時のエラー</h2>
<h3>権限不足</h3>
<pre class="line-numbers"><code class="language-other">Permission denied</code></pre>
<ul>
<li>Ubuntu で入ったから何となく行けてんのかと思いきや…</li>
<li>sudo しなさいよ</li>
</ul>
<h3>接続失敗</h3>
<pre class="line-numbers"><code class="language-other">ERROR 2003 (HY000): Can't connect to MySQL server on</code></pre>
<ul>
<li>RDS の設定漏れ</li>
<li>EC2 からの接続許可</li>
</ul>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/1446/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>RDSでフェイルオーバー試してみたよ</title>
		<link>https://otonan-syusyoku.work/archives/1448</link>
					<comments>https://otonan-syusyoku.work/archives/1448#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Wed, 18 Oct 2023 13:52:33 +0000</pubDate>
				<category><![CDATA[インフラ]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[RDS]]></category>
		<category><![CDATA[サーバー]]></category>
		<category><![CDATA[フェイルオーバー]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=1448</guid>

					<description><![CDATA[DBのあるべき姿の冗長構成 みなさんはDBの冗長構成を取っていますか？ 冗長構成とは簡単に言うと、 システムやサービスの障害が発生した場合に、自動的に別のバックアップシステムやリソースに切り替え、中断を最小限に抑える仕組 [&#8230;]]]></description>
										<content:encoded><![CDATA[<h2>DBのあるべき姿の冗長構成</h2>
<p>みなさんはDBの冗長構成を取っていますか？</p>
<p>冗長構成とは簡単に言うと、<br />
<strong>システムやサービスの障害が発生した場合に、自動的に別のバックアップシステムやリソースに切り替え、中断を最小限に抑える仕組み</strong><br />
になります。</p>
<p>&nbsp;</p>
<p>冗長構成を取っていると <span class="sc_marker blue"><strong>DB に障害が発生した際でも被害を最小限に抑えてシステム運用することが可能</strong></span>となっています。</p>
<p>データに破損が起きると案件次第では損害賠償に発展したり、ユーザーへの悪影響が生じたりするなどビジネスチャンスを失ってしまいます。</p>
<p>可能な限り冗長構成を取るようにしましょう〜</p>
<h2>RDS for MySQL でフェイルオーバー試してみた</h2>
<div class="sc_frame_wrap inline orange">
<div class="sc_frame_title"><span class="sc_frame_icon"><i class="fa fa-bolt" aria-hidden="true"><span>fa-bolt</span></i></span>注意</div>
<div class="sc_frame note">
<p>RDS はちゃんとお金かかります！<br />
自分で払える範囲のスペックで構築してください！<br />
後、検証が終わったら RDS は閉じてください！！！<br />
※RDS は停止してもお金がかかります。。。。(インスタンス料金, データベースストレージ料金, バックアップストレージ料金)</p>
</div>
</div>
<h3>事前準備</h3>
<p>EC2 と RDS の構築は済まして置いてください。</p>
<p>その上で1秒毎にDBへデータを登録する処理を PHP で書いていきます。</p>
<pre class="line-numbers"><code class="language-php">&lt;?php
ini_set('mysqlnd.net_read_timeout', 3);
$i = 0;
$end_time = time() + 600;
while (time() &lt; $end_time) {
  $result = hoge();
  sleep(1);
  echo $i . ":" . $result . "\n";
  $i++;
}

function hoge () {
  $result = 'connectionWaiting';
  try {
    $dbh = new PDO(
      'mysql:host=database-1.cizcjskkh2r7.ap-northeast-1.rds.amazonaws.com;dbname=testDB;charset=UTF8mb4',
      'admin',
      'password',
    );
    $dbh-&gt;setAttribute(PDO::ATTR_TIMEOUT, 3);
    $sql = "INSERT INTO testTable (created) VALUES ('" . date('Y-m-d h:i:s') . "')";
    if ($dbh-&gt;query($sql)) {
      $result = 'Succees';
    } else {
      $result = 'Faile';
    }
  } catch (PDOException $e) {
    $request = 'Die';
  }
  return $result;
}
?&gt;</code></pre>
<h3>いざ実行</h3>
<h4>PHPの実行</h4>
<pre class="line-numbers"><code class="language-php">php index.php</code></pre>
<h4>RDS の再起動</h4>
<p>RDS はフェイルオーバー での再起動ができるので、フェイルオーバーのオプションを付けて再起動を行います。</p>
<p>まずはデータ登録処理のPHPを実行します。<br />
フェイルオーバー実行前のデータ↓</p>
<pre class="line-numbers"><code class="language-other">mysql&gt; select * from testTable;
+----+---------------------+
| id | created             |
+----+---------------------+
| 1 | 2023-10-18 10:39:07 |
| 2 | 2023-10-18 10:39:08 |
| 3 | 2023-10-18 10:39:09 |
| 4 | 2023-10-18 10:39:10 |
| 5 | 2023-10-18 10:39:11 |
| 6 | 2023-10-18 10:39:12 |
+----+---------------------+</code></pre>
<p>&nbsp;</p>
<p>フェイルオーバー実行後のデータ↓</p>
<pre class="line-numbers"><code class="language-other">mysql&gt; select * from testTable;
+----+---------------------+
| id | created |
+----+---------------------+
| 50 | 2023-10-18 10:39:57 |
| 51 | 2023-10-18 10:39:58 |
| 52 | 2023-10-18 10:39:59 |
| 53 | 2023-10-18 10:40:00 |
| 54 | 2023-10-18 10:40:01 |
| 55 | 2023-10-18 10:40:02 |
| 56 | 2023-10-18 10:40:03 |
| 57 | 2023-10-18 10:40:04 |        ← 再起動で止まったところと思われる箇所
| 58 | 2023-10-18 10:41:10 |        ← 再起動完了したところと思われる箇所
| 59 | 2023-10-18 10:41:11 |
| 60 | 2023-10-18 10:41:12 |
| 61 | 2023-10-18 10:41:14 |
| 62 | 2023-10-18 10:41:15 |
| 63 | 2023-10-18 10:41:16 |
| 64 | 2023-10-18 10:41:17 |
| 65 | 2023-10-18 10:41:18 |
| 66 | 2023-10-18 10:41:19 |
| 67 | 2023-10-18 10:41:20 |
| 68 | 2023-10-18 10:41:21 |
| 69 | 2023-10-18 10:41:22 |
+----+---------------------+</code></pre>
<h3>わかったこと</h3>
<ul>
<li>データは途切れるが、DB の復旧とともにデータ登録が可能となる
<ul>
<li>被害が大きくなりにくい</li>
<li>エンドポイントが変更されないので、プログラム側で特別な処理は不要（超嬉しい）</li>
</ul>
</li>
<li>難しい設定は不要
<ul>
<li>天下の Oracle 様が解説している高可用性構成の作り方<br />
<a href="https://www.oracle.com/jp/a/tech/docs/technical-resources/120127-mysql-ha.pdf">https://www.oracle.com/jp/a/tech/docs/technical-resources/120127-mysql-ha.pdf</a><br />
<a href="https://downloads.mysql.com/presentations/01_201311_MySQL_JP_Tech-Tour.pdf">https://downloads.mysql.com/presentations/01_201311_MySQL_JP_Tech-Tour.pdf</a></li>
</ul>
</li>
</ul>
<h3>わかっていないこと</h3>
<ul>
<li>大量のデータになった場合の復旧時間
<ul>
<li>今回の検証でもすぐに終わるときもあれば、３分以上かかる場合もあった</li>
</ul>
</li>
<li>PHP 側に `ini_set(‘mysqlnd.net_read_timeout’, 3)` を入れないと再起動が完了しても処理が継続しない
<ul>
<li>RDS 側でデッドロックが走っている？</li>
<li>接続先を探している？</li>
<li>RDS 側に設定が必要？</li>
<li>とりあえずプログラムでちょっとした工夫は必要そう</li>
</ul>
</li>
</ul>
<h2>まとめ</h2>
<p>今回の検証で RDS を使用して冗長性を確保することができたのではないかなぁという所感です〜</p>
<p>実際に検証を通して冗長性のある構成とはこんな感じなんだなぁと言うのがしれたのはかなり大きいです。笑</p>
<p>&nbsp;</p>
<p>実際、 DB を使わないシステムは限りなく少ないので DB が死んでも大丈夫と言える構成を取ることでビジネスチャンスを失わないというのはかなり大切だと考えています。</p>
<p>引き続き検証を続けていく必要がありそうです〜</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/1448/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>僕が考えるRDSを激推する理由</title>
		<link>https://otonan-syusyoku.work/archives/1426</link>
					<comments>https://otonan-syusyoku.work/archives/1426#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Thu, 21 Sep 2023 14:42:53 +0000</pubDate>
				<category><![CDATA[インフラ]]></category>
		<category><![CDATA[業務]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[RDS]]></category>
		<category><![CDATA[フェイルオーバー]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=1426</guid>

					<description><![CDATA[僕が考えるRDS を激推する理由 バックアップが楽ちん RDS を推したい理由の上位にくるのがバックアップの手軽さです。 AWS の公式にも記載がある通り、バックアップを自動で取ってくれます。 過去に クラウドサーバー  [&#8230;]]]></description>
										<content:encoded><![CDATA[<h2>僕が考えるRDS を激推する理由</h2>
<h3>バックアップが楽ちん</h3>
<p>RDS を推したい理由の上位にくるのが<strong>バックアップの手軽さ</strong>です。</p>
<p>AWS の公式にも記載がある通り、バックアップを自動で取ってくれます。</p>
<p>過去に クラウドサーバー 上にインストールした MySQL のバックアップ手法として、<strong>cron にて AWS SDK for PHP を用いて S3にダンプファイルを保管</strong>する手法を取っていた自分からすると RDS のバックアップはかなり楽ちんです。<br />
だって、以下の設定が不要になりますからね。笑</p>
<ol>
<li>AWS SDK for PHP のインストール</li>
<li>cron にて日次の実行処理を記述</li>
<li>S3 に送信処理を記述</li>
</ol>
<blockquote><p>デフォルトで有効になっている Amazon RDS の自動バックアップ機能により、データベースとトランザクションログがバックアップされます。Amazon RDS では DB インスタンスのストレージボリュームのスナップショットを自動的に作成し、個々のデータベースだけではなく、その DB インスタンス全体をバックアップします。</p>
<p>このバックアップは、バックアップウィンドウと呼ばれるユーザーが設定可能な 30 分間隔の時間に 1 日 1 回行われます。自動バックアップは、お客様が設定した日数の間、保持されます (バックアップ保持期間と呼ばれます)。自動バックアップの保持期間は、最大 35 日間まで設定できます。</p>
<p><cite class="blockquote_ref"> <a href="https://aws.amazon.com/jp/rds/features/backup/#%E8%87%AA%E5%8B%95%E3%83%90%E3%83%83%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97" target="_blank" rel="noopener noreferrer">Amazon RDS のバックアップと復元</a> </cite></p></blockquote>
<p>&nbsp;</p>
<p>また、 RDS には自動バックアップに加えてポイントインタイムリカバリという機能があり、特定の時点に戻すことができます。（5分毎にデータベースの変更ログのアーカイブが自動で実行されます）</p>
<p>これは、データの損失を最小限に抑えることのできる機能となっており、ポカしやすい人には必需品と言えるほどの機能となっています。</p>
<p>先程申し上げた日次のバックアップだけでは不足しているバックアップ分を補填しているので、個人的にはすごく好きです。</p>
<blockquote><p>DB インスタンスを特定の時点に復元し、新しい DB インスタンスを作成できます。</p>
<p><cite class="blockquote_ref"> <a href="https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_PIT.html" target="_blank" rel="noopener noreferrer">DB インスタンスを特定の時点に復元し、新しい DB インスタンスを作成できます。</a> </cite></p></blockquote>
<h3>死活監視が楽ちん</h3>
<p>RDS はデフォルトでメトリクスデータを1分間隔で CloudWatch に送信してくれます。<br />
（CloudWatch はメトリクスの収集、アラームの設定、ログの収集と監視などを対応してくれるサービスです）</p>
<p>&nbsp;</p>
<p>これも自分ごとではありますが、死活監視をするために以下のようなインフラを構築しました。</p>
<table style="border-collapse: collapse; width: 100%; height: 519px;">
<tbody>
<tr style="height: 45px;">
<td style="width: 50%; text-align: center; height: 45px;">イメージ</td>
<td style="width: 50%; text-align: center; height: 45px;">設定手順</td>
</tr>
<tr style="height: 474px;">
<td style="width: 50%; height: 474px;"><img fetchpriority="high" decoding="async" src="https://otonan-syusyoku.work/wp-content/uploads/2023/09/アプリケーションを監視するサーバーを監視するサーバー.png" alt="監視構成" width="1000" height="500" class="aligncenter size-full wp-image-1443" srcset="https://otonan-syusyoku.work/wp-content/uploads/2023/09/アプリケーションを監視するサーバーを監視するサーバー.png 1000w, https://otonan-syusyoku.work/wp-content/uploads/2023/09/アプリケーションを監視するサーバーを監視するサーバー-300x150.png 300w, https://otonan-syusyoku.work/wp-content/uploads/2023/09/アプリケーションを監視するサーバーを監視するサーバー-768x384.png 768w" sizes="(max-width: 1000px) 100vw, 1000px" /></td>
<td style="width: 50%; height: 474px;">
<ol>
<li>アプリケーションサーバー構築</li>
<li>アプリケーションサーバーを監視するサーバー（監視サーバー A）を構築
<ol>
<li>Zabbix をインストール</li>
<li>アプリケーションサーバーに 監視サーバーA のエージェントをインストール</li>
</ol>
</li>
<li>監視サーバーA にて監視設定</li>
<li>監視サーバーAを監視する監視サーバーBを構築
<ol>
<li>Zabbix をインストール</li>
<li>監視サーバーAに監視サーバーBのエージェントをインストール</li>
</ol>
</li>
<li>監視サーバーBにて監視設定</li>
</ol>
</td>
</tr>
</tbody>
</table>
<p>[getpost id=&#8221;1243&#8243; cat_name=&#8221;1&#8243; date=&#8221;0&#8243;][getpost id=&#8221;1220&#8243; cat_name=&#8221;1&#8243; date=&#8221;0&#8243;]</p>
<p>&nbsp;</p>
<p>手順書いてみたんですけど、すっげー面倒くさいですね。。。</p>
<p>その反面、 RDS では上記のような面倒くさい事をしなくても死活監視が簡単にできてしまうんです。</p>
<p>下記のあたりを見てれば DBが生きているかどうかを判別することができるので、すごく楽です。</p>
<ul>
<li>データベースの稼働状況</li>
<li>CPU使用率</li>
<li>メモリ使用率</li>
<li>ディスクストレージ</li>
<li>データベースのクエリおよびスロークエリ</li>
</ul>
<p>これらに対して閾値を設定して異常状態を感知できるようにすれば、僕が構築したよく分からない事はしなくても済むなんて素敵すぎる！！！！</p>
<h3>フェイルオーバーが楽ちん</h3>
<p>フェイルオーバー の構成を取っていると何らかの障害が起きた際に被害を最小限に止めることができます。</p>
<p>実際に手動で組み込んだことはないのですが、天下の Oracle 様の解説記事を読んでみるとごちゃごちゃと設定が必要そうで、適切な冗長構成を取るのが難しそうな印象を受けました。</p>
<p>&nbsp;</p>
<p>対して RDS は以下の条件を満たせば、冗長構成を取ることが可能となっています。</p>
<ul>
<li>マルチアベイラビリティーゾーン</li>
<li>ホットスタンバイオプションの有効化</li>
</ul>
<p>実際の手法を確認したい方はこちらの記事をご確認ください。</p>
<p>[getpost id=&#8221;1448&#8243; cat_name=&#8221;1&#8243; date=&#8221;0&#8243;]</p>
<h2>まとめ</h2>
<p>単純なDBを構築したい場合、<strong>RDS を使うことで楽に安全に構築することができます</strong>。</p>
<p>過去の自分に戒めを込めて、 RDS 使うと幸せになれることを胸張って伝えていきたいです。笑</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/1426/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[備忘録]ZabbixにてMySQL監視する</title>
		<link>https://otonan-syusyoku.work/archives/1243</link>
					<comments>https://otonan-syusyoku.work/archives/1243#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Fri, 17 Feb 2023 02:30:42 +0000</pubDate>
				<category><![CDATA[絶対に必要なIT基礎知識]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[サーバー]]></category>
		<category><![CDATA[実務]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=1243</guid>

					<description><![CDATA[前提 Zabbixのインストール 以下2点を実施してZabbixが使える状態にしておいてください。 監視する側にZabbixサーバーをインストール 監視される側へZabbixエージェントをインストール [getpost  [&#8230;]]]></description>
										<content:encoded><![CDATA[<h2>前提</h2>
<h3>Zabbixのインストール</h3>
<p>以下2点を実施してZabbixが使える状態にしておいてください。</p>
<ul>
<li>監視する側にZabbixサーバーをインストール</li>
<li>監視される側へZabbixエージェントをインストール</li>
</ul>
<p>[getpost id=&#8221;1220&#8243; cat_name=&#8221;1&#8243; date=&#8221;0&#8243;]</p>
<h3>MySQLのインストール</h3>
<p>監視される側のサーバーにはMySQLをインストールしておいてください。<br />
MySQLのインストールが分からない場合は下記記事を参照してください。</p>
<p>[getpost id=&#8221;1170&#8243; cat_name=&#8221;1&#8243; date=&#8221;0&#8243;]</p>
<h2>監視するための準備</h2>
<h3>監視される側のサーバー</h3>
<h4>ユーザーの作成</h4>
<p>Zabbixエージェントが監視できるように監視される側のMySQLにユーザーを作成。</p>
<pre class="line-numbers"><code class="language-other">CREATE USER 'zabbix'@'localhost' IDENTIFIED BY 'password' grant all privileges on *.* to 'zabbix'@'%';
FLUSH PRIVILEGES;</code></pre>
<p>※権限の割当は状況に合わせてください。</p>
<h4>.my.cnfファイルの作成</h4>
<p>「/var/lib/zabbix/.my.cnf」を作成してください。<br />
デフォルトでは上記ファイルが存在しないのでtouchから実施することになります。</p>
<pre class="line-numbers"><code class="language-other">[client]
host=IP（監視される側のサーバーのIP）
user=zabbix
password='password'</code></pre>
<p>※hostにはlocalhostを指定しても問題ないはずですが、自分の場合はIPを指定しないと動かなかったです。</p>
<h4>userparameter_mysql.conf の設定</h4>
<p>「/etc/zabbix/zabbix_agentd.d/userparameter_mysql.conf 」を編集します。</p>
<p>このファイルでやりたいことは以下になります。</p>
<ul>
<li>「&#8211;defaults-extra-file」オプションにてMySQLのconfigファイルを指定</li>
<li>「mysql.ping」「mysql.status」などのkeyとcommandを指定</li>
</ul>
<pre class="line-numbers">UserParameter=mysql.ping[*], mysqladmin --defaults-extra-file=/var/lib/zabbix/.my.cnf 
UserParameter=mysql.status[*],echo "show global status where Variable_name='$1';" | mysql --defaults-extra-file=/var/lib/zabbix/.my.cnf -N | awk '{print $$2}' 
UserParameter=mysql.get_status_variables[*], mysql --defaults-extra-file=/var/lib/zabbix/.my.cnf -sNX -e "show global status" 
UserParameter=mysql.version[*], mysqladmin --defaults-extra-file=/var/lib/zabbix/.my.cnf -s version 
UserParameter=mysql.db.discovery[*], mysql --defaults-extra-file=/var/lib/zabbix/.my.cnf -sN -e "show databases" 
UserParameter=mysql.dbsize[*], mysql --defaults-extra-file=/var/lib/zabbix/.my.cnf -sN -e "SELECT SUM(DATA_LENGTH + INDEX_LENGTH) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='$3'" 
UserParameter=mysql.replication.discovery[*], mysql --defaults-extra-file=/var/lib/zabbix/.my.cnf -sNX -e "show slave status" 
UserParameter=mysql.slave_status[*], mysql --defaults-extra-file=/var/lib/zabbix/.my.cnf -sNX -e "show slave status"</pre>
<p>※configファイルのパスやファイルの中身(ユーザー名やパスワード)が間違っていると正常に監視ができずエラー吐きます。</p>
<div class="sc_frame_wrap inline orange">
<div class="sc_frame_title">リファレンス</div>
<div class="sc_frame">
<p>https://www.zabbix.com/documentation/2.2/jp/manual/config/items/userparameters</p>
</div>
</div>
<h2>監視する側のサーバーにて監視設定</h2>
<h3>Ping監視</h3>
<p>画像がないので恐縮ですが、以下手順で実行することが出来ます。</p>
<ul>
<li>Zabbixサーバーにログインし、Webインターフェースを開く</li>
<li>監視対象のMySQLサーバーを選択し、「設定」&gt;「ホスト」を選択</li>
<li>監視対象のMySQLサーバーの設定ページで、「アイテム」タブを選択</li>
<li>「アイテムの追加」をクリックし、以下の設定を入力
<ul>
<li>キー：mysql.ping</li>
<li>名前：MySQL Ping</li>
<li>タイプ：Zabbixエージェント</li>
<li>タイプの情報：MySQLサーバーのIPアドレスまたはホスト名</li>
</ul>
</li>
<li>「監視」&gt;「グラフ」を選択し、グラフを作成</li>
</ul>
<p>&nbsp;</p>
<p>上記の設定で、ZabbixからMySQLサーバーへPingリクエストを定期的に送信し、「MySQLが生きているか」を監視できるようになります。<br />
また、グラフを使用して、Ping応答時間の変化を視覚的に確認することもできます。</p>
<p>&nbsp;</p>
<h3>スロークエリ</h3>
<h4>MySQL側の設定</h4>
<p>MySQLの設定ファイルに以下を設定し、スロークエリの検出を有効化します。</p>
<pre class="line-numbers"><code class="language-other">slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 1</code></pre>
<div class="sc_frame_wrap inline orange">
<div class="sc_frame_title">スロークエリとは</div>
<div class="sc_frame">
<p>MySQLのスロークエリログは、長時間実行されたクエリを特定し、パフォーマンスの問題を特定するための有用なツールです。</p>
</div>
</div>
<div class="sc_frame_wrap inline orange">
<div class="sc_frame_title">MySQLの設定ファイルの違い</div>
<div class="sc_frame">
<p>my.iniはwindows用、my. cnfはwindows以外のOS用の設定ファイル</p>
</div>
</div>
<h4>Zabbix側の設定</h4>
<p>画像がないので恐縮ですが、以下手順で実行することが出来ます。</p>
<ul>
<li>Zabbixサーバーにログインし、Webインターフェースを開く</li>
<li>監視対象のMySQLサーバーを選択し、「設定」&gt;「ホスト」を選択</li>
<li>監視対象のMySQLサーバーの設定ページで、「アイテム」タブを選択</li>
<li>「アイテムの追加」をクリックし、以下の設定を入力
<ul>
<li>キー：mysql.slowqueries</li>
<li>名前：MySQL Slow Queries</li>
<li>タイプ：Zabbixエージェント</li>
<li>タイプの情報：MySQLサーバーのIPアドレスまたはホスト名</li>
<li>更新間隔：30秒（または必要に応じて変更します）</li>
<li>アプリケーション：MySQL</li>
</ul>
</li>
<li>「監視」&gt;「トリガー」を選択し、トリガーを作成
<ul>
<li>名前：MySQL Slow Queries</li>
<li>説明：MySQL Slow Queries</li>
<li>エスカレーション：通知する</li>
<li>表示：プロブレム</li>
<li>依存：なし</li>
<li>条件：{MySQL: mysql.slowqueries.last()}＞0</li>
<li>縮小条件：なし</li>
</ul>
</li>
</ul>
<p>上記の設定でスロークエリを監視できますー。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/1243/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>LAMP環境の構築における注意点</title>
		<link>https://otonan-syusyoku.work/archives/1170</link>
					<comments>https://otonan-syusyoku.work/archives/1170#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Fri, 17 Feb 2023 02:00:37 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[LAMP]]></category>
		<category><![CDATA[MySQL]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=1170</guid>

					<description><![CDATA[いわゆるLAMP環境ってやつです。 普段はXamppを使って開発を行っているのですが、今回始めてテスト環境の構築を任せてもらえたので、備忘録です。 構築環境 構築したい環境は以下のとおりです。 Ubuntu 20.04  [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>いわゆるLAMP環境ってやつです。</p>
<p>普段はXamppを使って開発を行っているのですが、今回始めてテスト環境の構築を任せてもらえたので、備忘録です。</p>
<h2>構築環境</h2>
<p>構築したい環境は以下のとおりです。</p>
<ul>
<li>Ubuntu 20.04 LTS</li>
<li>Apache</li>
<li>PHP 8.0系</li>
<li>MySQL</li>
</ul>
<p>&nbsp;</p>
<p>その他に使用するツールは以下のツールです。</p>
<ul>
<li>MySQL Workbench(MySQLのGUI)</li>
<li>さくらのくらうど(サーバー)</li>
<li>FileZilla</li>
</ul>
<div class="sc_frame_wrap inline orange">
<div class="sc_frame_title">参考サイト</div>
<div class="sc_frame ">
<div class="sc_frame_text">・<a href="https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-on-ubuntu-20-04-ja">Linux、Apache、MySQL、PHP(LAMP)スタックをUbuntu 20.04にインストールする方法</a><br />
・<a href="https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-ubuntu-20-04-ja">Ubuntu 20.04でLet’s Encryptを使用してApacheを保護する方法</a></div>
</div>
</div>
<h2>Linuxの注意点</h2>
<p>リナックスの注意点は以下２つです。</p>
<ul>
<li>ディストリビューション間違えるな</li>
<li>コマンドプロンプト</li>
</ul>
<h3>ディストリビューション</h3>
<p>ディストリビューションをしっかり把握しておいて下さい。</p>
<p>今回はUbuntu上に構築していくのですが、チームメンバーに「UbuntuとCentOSって一緒でしょ？」という人がいたので、驚きました。</p>
<p>ディストリビューションが違えば多少なりとも構築方法が変わってくるので、ディストリビューションは把握しておいて下さい。。</p>
<p>ディストリビューションがわからないという方はリナックスって何？とかでちゃんと調べて下さい。お願いします。。。。。</p>
<h3>コマンドプロンプト</h3>
<p>ウィンドウズ環境にてUnixコマンドをウィンドウズで扱う必要があったので、ウィンドウズでもUnixコマンドを扱えるように<strong>GitBash</strong>を導入しました。</p>
<p>自分が慣れているターミナル使用して下さい。</p>
<h2>Apacheの注意</h2>
<p>Apacheの注意点はSSL化のみです。(SSL化以外は簡単です。記事通りに実施して下さい)</p>
<p>&nbsp;</p>
<h2>MySQLの注意点</h2>
<p>MySQLで気を付ける点は以下の3つです。</p>
<ul>
<li>ファイヤーウォール</li>
<li>バインドの設定</li>
<li>ユーザーの設定</li>
</ul>
<h3>ファイヤーウォール</h3>
<p>初期設定でファイヤーウォールの設定をして下さい。</p>
<p>下記設定を行うことでLinuxがMySQLを受け付けてくれるようになります。</p>
<pre class="line-numbers"><code class="language-other">#ファイヤーウォールの確認
sudo ufw status

#MySQLの開放
sudo ufw allow 3306</code></pre>
<p>&nbsp;</p>
<h3>バインド</h3>
<p>MySQL 標準ではローカルホストからの接続のみ許可しているため、外部からの接続を許可するように設定します。</p>
<p>/etc/mysql/my.cnfの設定ファイルには127.0.0.1 で LISTEN してるので外部から接続するようにしたいので、下記項目をコメントアウトする必要があります。</p>
<p>自分はここでLinuxのIPアドレスを指定していたので、接続が上手くいきませんでした。</p>
<p>ちゃんと理由を調べていないのですが、bind-addressをコメントアウトすることで全てのアクセスを受け付ける事ができるはずです。</p>
<pre class="line-numbers"><code class="language-other">#bind-address            = 127.0.0.1</code></pre>
<h3>ユーザーの設定</h3>
<p>外部ユーザーとしてroot以外のユーザーを作成します。</p>
<pre class="line-numbers"><code class="language-other">--DBの作成
CREATE DATABASE データベース名;

--ユーザーの作成
--'%'はワイルドカード。IPアドレスでも良いよ
CREATE USER 'ユーザー名'@'%'　identified by 'パスワード';

--ユーザーに権限付与
grant all privileges on *.* to 作成したユーザー@'%';

--更新
flush privileges;</code></pre>
<p>&nbsp;</p>
<p>上記設定を行うことで、MySQLWorkBenchから外部接続を行うことができます。</p>
<p>MySQLWorkBenchではなくてもphpMyAdminでも何でも良いので、GUIツールは使用できるようにした方が良いですよー。</p>
<h2>最後に</h2>
<p>phperとしてLAMP環境の構築が出来ないは恥ずかしいので、確実にできるようにしたほうが良いです。</p>
<p>今回は幸いにも実務にて環境構築をさせて頂いたのですが、独学の場合でも自分で出来るようになっていて下さい。</p>
<p>PHPバンザイ。。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/1170/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SQL学んで気づいたことを紹介するョ</title>
		<link>https://otonan-syusyoku.work/archives/1093</link>
					<comments>https://otonan-syusyoku.work/archives/1093#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Wed, 09 Mar 2022 06:00:47 +0000</pubDate>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Oracle]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=1093</guid>

					<description><![CDATA[気づいたこと　〜就職編〜 結局SQL 結局のところSQLは必要不可欠な技術です。 アプリケーションはPHPやJavaといったプログラミング言語を使用すると思いますが、データを扱う事のできる唯一の言語はSQLです。 そのた [&#8230;]]]></description>
										<content:encoded><![CDATA[<h2>気づいたこと　〜就職編〜</h2>
<h3>結局SQL</h3>
<p>結局のところSQLは必要不可欠な技術です。</p>
<p>アプリケーションはPHPやJavaといったプログラミング言語を使用すると思いますが、データを扱う事のできる唯一の言語はSQLです。</p>
<p>そのため、SQLが出来るだけで重宝されます。</p>
<p>[getpost id=&#8221;1028&#8243;]</p>
<h3>インフラにもバックエンドにも</h3>
<p>IT業界の職種はかなり広いのですが、SQLはインフラとバックエンドに領域が被っている為、就職の選択肢がかなり広がります。</p>
<p>最近ではフロントの人間もSQLを使用する事があるそうです。←僕の友達情報</p>
<p>そのため、僕の考えとしてはSQLを基盤に学ぶことでデータを扱えるIT人材になれるので、どこを目指したら良いのか分からない人はとりあえずSQLについて学ぶべきです。</p>
<p>[getpost id=&#8221;1045&#8243;]</p>
<h2>気をつけること　〜考え方編〜</h2>
<h3>実行順序</h3>
<p>実行順序の理解は大切です。</p>
<p>呼ばれる順序が分かることで、目的に沿ったSQL文を書くことが出来ます。逆に言うと<span class="sc_marker blue"><strong>実行順序を意識していなければ意図しないデータを取得する事になってしまいます。</strong></span></p>
<p>実行順は以下の通りです。</p>
<ol>
<li>FROM</li>
<li>WHERE</li>
<li>GROUP BY</li>
<li>HAVING</li>
<li>SELECT</li>
<li>DISTINCT</li>
<li>ORDER BY</li>
</ol>
<p>SQLを学習した当初は欲しいデータに意識が向きすぎてしまいSELECT句が重要だと考えていました。</p>
<p>しかし、本当に欲しいデータを取得する場合は<span class="sc_marker blue"><strong>大本のテーブルから考えていく必要があります。</strong></span></p>
<p><span class="sc_marker y">どのテーブルからどの条件でデータを取得していくのか</span>意識してみてください。</p>
<h3>書き方は十人十色</h3>
<p>早めの段階で知りたかったのですが、<span class="sc_marker blue"><strong>SQLの書き方は十人十色</strong></span>です。</p>
<p>&nbsp;</p>
<p>SQLを学びたての時は教科書通りに書かないといけないという意識が強く、柔軟性にかけたSQLを記述していました。(教科書通り→INはEXISTSで代替。サブクエリはできるだけ書かない。)</p>
<p>&nbsp;</p>
<p>しかし実業務でデータを扱う際にはこんな書き方は良くないよって言われている書き方で実装しているSQLはよく目にします。<br />
※1万レコードをUNIONで横持ちのデータを縦持ちに結合している仰天コードを目にしたことがあります。</p>
<p>&nbsp;</p>
<p><span class="sc_marker y">Aを取得するという目的に対して、こうした方が良いよねって言う書き方はあるけど、正解はありません。</span></p>
<p><span class="sc_marker blue"><strong>必要なデータを取得できないことが悪</strong></span>なので、慣れるまでは速さやキレイにデータを取得すると行った事は気にしないでおきましょう。</p>
<p>SQLに関しては知見が増えてくれば<span class="sc_marker blue"><strong>自然</strong><strong>とどのような記述が最適なのかが理解できてくるので少しづつ努力していけば問題なし</strong></span>です。</p>
<h3>データは超重要</h3>
<p>データなんかより画面動かしたりする方がITっぽくてカッコいい〜！なんて思っていたのですが、<span class="sc_marker blue"><strong>ビジネスに必要なものはデータ</strong></span>だと実務に入って気づきました。</p>
<p>&nbsp;</p>
<p>結局の所、<span class="sc_marker blue"><strong>データを自分たちの使いやすい形でデータを取得or加工し、お金を生み出す形でデータを利用しているのがWebサービスの根幹</strong></span>だと思います。</p>
<p>&nbsp;</p>
<p>データを扱えるって最強です。</p>
<h2>気づいたこと　〜書き方編〜</h2>
<h3>インデントは揃えよう</h3>
<p>SQLの経験が浅くても出来る事その1はインデントを揃えよう！です。</p>
<p>以下2つのSQL文を比較してもらえれば分かると思うのですが、格段に見やすさが異なると思います。</p>
<div class="row sp">
<div class="row sp">
<div class="sc_col2 sp">
<pre class="line-numbers"><code class="language-other">SELECT no , name FROM test 
WHERE no &gt; 4 
AND name IN ('aiueo','test') 
ORDER BY no;</code></pre>
</div>
<div class="sc_col2 sp">
<pre class="line-numbers"><code class="language-other">SELECT no , name FROM test 
 WHERE no &gt; 4 
      AND name IN ('aiueo','test') 
 ORDER BY no;</code></pre>
</div>
</div>
</div>
<p>&nbsp;</p>
<h3>予約文字は大文字</h3>
<p>SQLの経験が浅くても出来る事その1は予約文字は大文字で記述！です。</p>
<p>予約文字はSQLで設定されている単語の事を指します。<br />
(例：SELECT.FROM,WHERE,JOIN,)</p>
<p>こちらも比較してもらえれば分かると思います。</p>
<div class="row sp">
<div class="sc_col2 sp">
<pre class="line-numbers"><code class="language-other">select no,name from test
where no &gt; 4
    and name in('aiueo','test')
order by no</code></pre>
</div>
<div class="sc_col2 sp">
<pre class="line-numbers"><code class="language-other">SELECT no , name FROM test 
 WHERE no &gt; 4
      AND name IN ('aiueo','test') 
 ORDER BY no;</code></pre>
</div>
</div>
<h3>目的を考える</h3>
<p>SQLに慣れてきたら何のデータが欲しいのかを考える癖をつけていきましょう。</p>
<p>SQLは様々な記述方法でデータを取得することが出来るため、目的を明確にし必要なデータを取得する事を意識してください。</p>
<p>目的を明確にすることで<span class="sc_marker blue"><strong>どの記述方法が最適なのか</strong></span>が段々と分かってくるはずです。</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/1093/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>サブクエリの返答は単一行のみ！もしくは述語の指定が必要！</title>
		<link>https://otonan-syusyoku.work/archives/1004</link>
					<comments>https://otonan-syusyoku.work/archives/1004#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Sun, 16 Jan 2022 02:21:38 +0000</pubDate>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Oracle]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=1004</guid>

					<description><![CDATA[複数行を返すとエラーになります Where句で使用するサブクエリの問い合わせ結果が2行以上になってしまうと「single-row subquery returns more than one row」のエラーが帰ってきま [&#8230;]]]></description>
										<content:encoded><![CDATA[<h2>複数行を返すとエラーになります</h2>
<p>Where句で使用するサブクエリの問い合わせ結果が2行以上になってしまうと「single-row subquery returns more than one row」のエラーが帰ってきます。</p>
<pre class="line-numbers"><code class="language-other">SQL&gt; select * from test
 where no = (select no from test); 
 where no = (select no from test)
             *
ERROR at line 2:
ORA-01427: single-row subquery returns more than one row</code></pre>
<p>サブクエリの結果が複数帰ってきてしまうと<span class="sc_marker blue"><strong>No列の比較にどの値を使用したら良いのか分からない為のエラー</strong></span>です。</p>
<p>そのため、サブクエリの帰ってくる値を単一にする必要があります。</p>
<p>サブクエリを使用する時はケースバイケースのため、その都度サブクエリの帰ってくる件数を意識しましょう。</p>
<pre class="line-numbers"><code class="language-other">SQL&gt;  select * from test
 where no = (select no from test where no = 1);  

	NO NAME
---------- --------------------------------------------------
	 1 aaaaa</code></pre>
<pre class="line-numbers"><code class="language-other">SQL&gt; select * from test
  where no = (select max(no) from test);    

	NO NAME
---------- --------------------------------------------------
	 5 youo
</code></pre>
<h2>サブクエリの結果を複数行受け取れる述語</h2>
<p>もしサブクエリの帰ってくる件数を複数のときにしたい場合は「IN」や「EXISTS」、「ANY」などの述語を指定します。</p>
<p>これらの述語を使用することで<strong><span class="sc_marker blue">サブクエリの結果のどれかと一致するものを正とする事</span></strong>を表現することが出来ます。</p>
<pre class="line-numbers"><code class="language-other">SQL&gt; select * from test
 where no IN(select no from test0);   

	NO NAME
---------- --------------------------------------------------
	 1 aaaaa
	 2 iiiii
	 2 uouoo</code></pre>
<p>&nbsp;</p>
<pre class="line-numbers"><code class="language-other">SQL&gt; select * from test
 where exists(select no from test0 where test.no = test0.no);  2  

	NO NAME
---------- --------------------------------------------------
	 1 aaaaa
	 2 iiiii
	 2 uouoo</code></pre>
<p>&nbsp;</p>
<pre class="line-numbers"><code class="language-other">SQL&gt; select * from test
 where no = ANY(select no from test0);  2  

	NO NAME
---------- --------------------------------------------------
	 1 aaaaa
	 2 iiiii
	 2 uouoo
</code></pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/1004/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>テーブル結合の名前が多すぎる！！からまとめたよ</title>
		<link>https://otonan-syusyoku.work/archives/995</link>
					<comments>https://otonan-syusyoku.work/archives/995#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Sat, 15 Jan 2022 07:19:45 +0000</pubDate>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Oracle]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=995</guid>

					<description><![CDATA[参考書を読んでも分かりづらい SQLの学習のために参考書を読んでも、「クロス結合が〜〜」「自然結合は〜〜」とたくさんの結合名称が出てきてしまい、こんがらがったのでまとめました。 当記事では内部結合と外部結合以外も紹介して [&#8230;]]]></description>
										<content:encoded><![CDATA[<h2>参考書を読んでも分かりづらい</h2>
<p>SQLの学習のために参考書を読んでも、「クロス結合が〜〜」「自然結合は〜〜」とたくさんの結合名称が出てきてしまい、こんがらがったのでまとめました。</p>
<p>当記事では内部結合と外部結合以外も紹介しているのですが、内部結合と外部結合さえ知っていればやっていけます。</p>
<p>SQL関連の資格を勉強している方やSQLの知識が浅い方は「そういう結合もあるんだ」くらいの理解をして頂ける記事になっていれば幸いです。</p>
<h2>結合の種類</h2>
<p>自分がテーブル結合の勉強をしている際に出会った結合名称です。</p>
<ol>
<li>内部結合</li>
<li>外部結合(左外部結合、右外部結合)</li>
<li>完全外部結合</li>
<li>自己結合</li>
<li>クロス結合</li>
<li>自然結合</li>
<li>非等価結合</li>
</ol>
<p>※自分はSQLを使用した実務経験が6ヶ月(2022年1月時点)しかないのですが、内部結合と外部結合の使用がほとんどでした。(自己結合と非等価結合は1,2回の使用)</p>
<h2>2テーブルで結合を試していくぅ</h2>
<pre class="line-numbers"><code class="language-other">SQL&gt; select * from testJoin;

	NO NAME       P        AGE T
---------- ---------- - ---------- -
	 1 michel     1 	20 1
	 2 jordan     2 	30 1
	 3
	 4 Lebron     1 	25 1
	 5 hanamiti   2 	18 2
	 0 Popovich   0 	80 2

SQL&gt; select * from testJoin2;

	NO POSITION
---------- ----------
	 1 PG
	 2 SG
	 3 Substitute</code></pre>
<h3>内部結合</h3>
<p>内部結合は、<span class="sc_marker blue"><strong>結合Keyが一致する行のみを取得するため</strong></span>の構文です。</p>
<p>下記のSQL文は、「No:0」がtestJoin1に登録されていない為、testJoinの「No:0,NAME:Popovich」のデータは取得されません。</p>
<p>マスタデータがないデータを弾く時によく使用されますね。</p>
<pre class="line-numbers"><code class="language-other">SQL&gt; select t1.name , t2.POSITION from testJoin t1
inner join testJoin2 t2 on t2.NO = t1.pname;   2  

NAME	   POSITION
---------- ----------
michel	   PG
jordan	   SG
Lebron	   PG
hanamiti   SG
</code></pre>
<h3>外部結合(左外部結合、右外部結合)</h3>
<p>外部結合は、<span class="sc_marker blue"><strong>基となるテーブルのデータをすべて残した上での結合</strong></span>となります。</p>
<p>下記SQL文の場合だと、testJoinを基とするため結合Keyに一致しない「No:0」と「No:3」のレコードを取得することが出来ます。</p>
<pre class="line-numbers"><code class="language-other">select t1.no , t1.name , t2.POSITION from testJoin t1
left join testJoin2 t2 on t2.NO = t1.pname order by t1.no; 
SQL&gt;   2  
	NO NAME       POSITION
---------- ---------- ----------
	 0 Popovich
	 1 michel     PG
	 2 jordan     SG
	 3
	 4 Lebron     PG
	 5 hanamiti   SG</code></pre>
<h3>完全外部結合</h3>
<p>完全外部結合は、<strong><span class="sc_marker blue">結合Keyが不一致でも結合するテーブルの全データを取得するため</span></strong>の構文です。</p>
<p>結合Keyに一致しない「No:0,NAME:Popovich」「No:3,NAME:NULL」「No:NULL,NAME:NULL,Position:Substitute」の列が取得されていることが分かります。</p>
<p>正直使ったことないです。</p>
<pre class="line-numbers"><code class="language-other">SQL&gt; select t1.no , t1.name , t2.POSITION from testJoin t1
Full outer join testJoin2 t2 on t2.NO = t1.pname order by t1.no;   2  

	NO NAME       POSITION
---------- ---------- ----------
	 0 Popovich
	 1 michel     PG
	 2 jordan     SG
	 3
	 4 Lebron     PG
	 5 hanamiti   SG
		      Substitute</code></pre>
<h3>自己結合</h3>
<p>自己結合は、<span class="sc_marker blue"><strong>同一のテーブルを別テーブルと考えてデータを取得する</strong></span>ための構文です。</p>
<p>下記SQL文では、同一のチームに所属している選手同士を出力しています。(<span class="sc_marker y">※自己結合は同一テーブルを別テーブルとして扱うので別名称を付与しなければいけません</span>)</p>
<p>余談ですがWHERE句にNAME列の比較演算子を使用しているので、同じ組み合わせのチームを除外しています。</p>
<pre class="line-numbers"><code class="language-other">SQL&gt; select t1.no,t1.name,t1.team_id,t2.no,t2.name,t2.team_id from testJoin t1 
inner join testJoin t2 on t1.team_id = t2.team_id
where t1.name &gt; t2.name
order by t1.no;   2    3    4  

	NO NAME       T 	NO NAME       T
---------- ---------- - ---------- ---------- -
	 1 michel     1 	 2 jordan     1
	 1 michel     1 	 4 Lebron     1
	 2 jordan     1 	 4 Lebron     1
	 5 hanamiti   2 	 0 Popovich   2</code></pre>
<h3>クロス結合</h3>
<p>クロス結合は<span class="sc_marker blue">結合するテーブルのデータ数を乗算する</span>構文のことを指します。</p>
<p>testJoinは6個のデータを、testJoin1は3個のデータを保持しています。</p>
<p>そのため6×3=18行が取得されます。</p>
<pre class="line-numbers"><code class="language-other">SQL&gt; select t1.name,t2.POSITION from testJoin t1,testJoin2 t2
  order by t1.no,t2.no;  2  

NAME	   POSITION
---------- ----------
Popovich   PG
Popovich   SG
Popovich   Substitute
michel	   PG
michel	   SG
michel	   Substitute
jordan	   PG
jordan	   SG
jordan	   Substitute
	   PG
	   SG

NAME	   POSITION
---------- ----------
	   Substitute
Lebron	   PG
Lebron	   SG
Lebron	   Substitute
hanamiti   PG
hanamiti   SG
hanamiti   Substitute</code></pre>
<h3>自然結合</h3>
<p>自然結合は、<span class="sc_marker blue"><strong>結合するテーブル同士のカラム名称とデータ型をSQLさんが判断してくれる</strong></span>構文です。</p>
<p>下記SQL文だと、testJoinのNo列(NUMBER型)とtestJoin1のNo列(NUMBER型)が同一名称、同一データ型になるためNO列を結合Keyに設定してくれています。</p>
<p>下記のデータを正として取得します。</p>
<p>testJoin「No:1,NAME:michel」= testJoin1「No:1,PG」<br />
testJoin「No:2,NAME:jordan」= testJoin1「No:1,SG」<br />
testJoin「No:3,NAME:NULL」= testJoin1「No:1,Substitute」</p>
<p>多分実務で使うこと無いんじゃないかと思います。</p>
<pre class="line-numbers"><code class="language-other">SQL&gt; select no,t1.name,t2.POSITION from testJoin t1 
natural LEFt join testJoin2 t2;  

	NO NAME       POSITION
---------- ---------- ----------
	 0 Popovich
	 1 michel     PG
	 2 jordan     SG
	 3	      Substitute
	 4 Lebron
	 5 hanamiti
</code></pre>
<h3>非等価結合</h3>
<p>非等価結合は<span class="sc_marker blue"><strong>結合条件に「＝」演算子を使用しない</strong></span>構文を指します。</p>
<p>「＝」を条件に指定しないだけなので、あまり難しく考える必要はありません。</p>
<pre class="line-numbers"><code class="language-other">SQL&gt; select * from testJoin t1 
inner join testJoin2 t2 on t1.PNAME &lt;&gt; t2.POSITION
where t1.no &lt;3
order by t1.no;  2    3    4  

	NO NAME       P        AGE T	     NO POSITION
---------- ---------- - ---------- - ---------- ----------
	 0 Popovich   0 	80 2	      1 PG
	 0 Popovich   0 	80 2	      2 SG
	 0 Popovich   0 	80 2	      3 Substitute
	 1 michel     1 	20 1	      1 PG
	 1 michel     1 	20 1	      2 SG
	 1 michel     1 	20 1	      3 Substitute
	 2 jordan     2 	30 1	      1 PG
	 2 jordan     2 	30 1	      2 SG
	 2 jordan     2 	30 1	      3 Substitute</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/995/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>NULLが嫌いと感じる理由をまとめてみた</title>
		<link>https://otonan-syusyoku.work/archives/945</link>
					<comments>https://otonan-syusyoku.work/archives/945#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Sun, 17 Oct 2021 01:14:20 +0000</pubDate>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Oracle]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=945</guid>

					<description><![CDATA[NULLの特徴 NULLとは0でも空文字でもない値のことを指します。（イメージ的には存在しない値を分かりやすくするためにNULLというシールを貼っている状態のこと。） 例えば、財布の中身はいくら？という問いに対して下記の [&#8230;]]]></description>
										<content:encoded><![CDATA[<h2>NULLの特徴</h2>
<p>NULLとは<span class="sc_marker blue">0でも空文字でもない値</span>のことを指します。（イメージ的には存在しない値を分かりやすくするためにNULLというシールを貼っている状態のこと。）</p>
<p>例えば、財布の中身はいくら？という問いに対して下記の場合が値を保持しているということが証明できます。</p>
<ul>
<li>財布の中身が0円であれば財布が空なので0円という値を保持。</li>
<li>10円が入っていれば10円という値を保持。</li>
</ul>
<p>しかし、財布自体がなければ10円を保持することも0円を保持することもできません。</p>
<p>この財布がない状態の事をSQLの世界ではNULLと呼んでいます。</p>
<h2>NULLが嫌い</h2>
<h3>「=」が使えない</h3>
<p>SQLにおいて値の比較や参照において「＝」を使用するのですが、NULLに「＝」は使用できません。</p>
<p>NULLの特徴でもお話したとおり、NULLは値ではないため「＝」「＜」「＞」などの演算子を使用することができません。値ではないものを比較しようとするとSQLさんに怒られます。</p>
<p>そのため、<strong>IS　NULL</strong>という構文を用いて値の参照や比較を行います。</p>
<pre class="line-numbers"><code class="language-other">--名前が無い人の検索
SELECT name FROM family WHERE name IS NULL;

--名前がある人の検索
SELECT name FROM family WHERE name IS NOT NULL;</code></pre>
<div class="sc_frame_wrap inline orange">
<div class="sc_frame_title">補足</div>
<div class="sc_frame ">
<div class="sc_frame_text">NULLに対して「＝」ではなくISを使用していることから<br />
何もない状態を可視化するための目印なので値ではなく、名詞という認識のほうが良いです。</div>
</div>
</div>
<h3>文字結合ができない</h3>
<p>NULL＋文字列の結合を行なうと異変が起きてしまいます。</p>
<p>MysqlにてNULL値と文字列をCONCAT関数を使用して文字列結合を行うと、NULL値を含む文字列はNULLになってしまいました。(数学で言うところの｛数字×0＝0｝みたいな感じなんですね。)</p>
<pre class="line-numbers"><code class="language-other">mysql&gt; SELECT * FROM BUSYO;
+----------+-----------------+
| busyo_no | busyo_name      |
+----------+-----------------+
|        1 | 開発部          |
|        2 | デザイン部      |
|        3 | 営業部          |
|        4 | サービス部      |
|        5 | NULL            |
+----------+-----------------+
5 rows in set (0.00 sec)

mysql&gt; SELECT CONCAT(busyo_name,'hoge') FROM BUSYO;
+---------------------------+
| CONCAT(busyo_name,'hoge') |
+---------------------------+
| 開発部hoge                |
| デザイン部hoge            |
| 営業部hoge                |
| サービス部hoge            |
| NULL                      |
+---------------------------+
5 rows in set (0.00 sec)</code></pre>
<div class="sc_frame_wrap inline orange">
<div class="sc_frame_title">補足</div>
<div class="sc_frame ">
<div class="sc_frame_text">文字列の結合で特にこんがらがったのが、OracleではNULL値を空文字として扱うという事です。<br />
Oracleにて、CONCAT(&#8216;あいうえお&#8217;,NULL)；を実行すると｛あいうえお’’｝という結果が返ってきます。</div>
</div>
</div>
<h3>値の並び順</h3>
<p>ORDER BYによって値を並び替える時、NULL値を含む列の場合はNULL値が一番上(もしくは一番下)にきます。</p>
<p><strong>値ではない</strong>のがNULLの特徴なので、<span class="sc_marker blue">比較して並べかえを実現する事はできない</span>みたいです。</p>
<p>&nbsp;</p>
<p>NULL値の順序を指定する場合、「NULLS FIRST(or LAST)」を指定することで思い通りの順序にすることが可能です。</p>
<pre class="line-numbers"><code class="language-other">SQL&gt; select * from fruit2 order by name1;

NAME1	   NAME2
---------- ----------
apple	   orange
apple	   apple
banana	   banana
banana	   apple
banana	   orange
orange	   orange
	           orange

SQL&gt; select * from fruit2 order by name1 nulls first;

NAME1	   NAME2
---------- ----------
	           orange
apple	   orange
apple	   apple
banana	   orange
banana	   banana
banana	   apple
orange	   orange</code></pre>
<h3>論理演算にNULLが紛れ込むとやっかい</h3>
<p>WHERE句に下記のようなサブクエリを記述した際にサブクエリの結果がNULLを返すと意図しない結果が帰ってきます。</p>
<pre class="line-numbers"><code class="language-other">SQL&gt;SELECT * FROM TEST1
         WHERE no &lt;(SELECT min(no) FROM TEST2);</code></pre>
<p>NULLに比較演算子は使用できないため、サブクエリの結果がNULLになると大元のSQLは１行も返してくれません。</p>
<p>TEST2テーブルにNULLが存在しないと思いこんで上記SQL文を発行してしまうと想定外の結果が帰ってくるので気をつけましょう。</p>
<p>対策としては、サブクエリ内でNULL値を変換してくれるcoalesce関数などの使用がおすすめです。</p>
<h2>他にも</h2>
<p>まだ学習不足で確認ができていないのですが、</p>
<ul>
<li>インデックスとNULL</li>
<li>NULLの便利な使用方法</li>
</ul>
<p>などを今後追記していきます。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/945/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
