20200706のMySQLに関する記事は7件です。

HerokuのDB(MySQL)をローカルで確認する方法

HerokuにMySQL(ClearDB)にてアプリをデプロイしました。アプリをデプロイしたのでDBをローカルで確認しようとしたところPostgreSQLでのやり方の説明は多くあったものの、MySQLの説明はつくなかったので紹介します。
おそらくMySQLのコマンドをよく理解してる人はすぐできると思うのですが、自分はあまり理解してなかったので結構時間をとられてしまいした。

HerokuにデプロイしたMySQLをローカルで確認する方法

・heroku configでDBの情報を確認

% heroku config
=== db Config Vars
CLEARDB_DATABASE_URL:     ------
DATABASE_URL:             ------
DB_HOSTNAME:              us-cdbr-east-02.cleardb.com
DB_NAME:                  heroku_aaaa
DB_PASSWORD:              aaaaaaaa
DB_PORT:                  ----
DB_USERNAME:              aaaaaaaaaaaaa
・・・

herokuの情報を元にmyqslコマンドを実行します。
-pDB_PASSWORD-pの後にスペースを開け内容にしてください。

% mysql -u DB_USERNAME -h DB_HOSTNAME DB_NAME -pDB_PASSWORD
mysql> 

このように出てきたら成功です

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SQLの基本的な文法まとめ②

SQLの基本文法のおさらいをしたのでまとめました。

 

データの検索

テーブルの指定

FROM テーブル名

カラムの指定

SELECT カラム名

使い方

ex)
SELECT * FROM users;

ワイルドカード

* のこと
上記では「すべてのカラム」を取得している

取得するレコードの制限

WHERE 条件

ex)
SELECT * FROM users WHERE name = "白石";

条件に使用できる論理演算子

  • AND
  • OR
  • NOT

1つのカラム内での範囲検索

WHERE カラム名 BETWEEN 下限 AND 上限

ex)
SELECT * FROM users WHERE age BETWEEN 21 AND 24;
-- ageが20以上かつ25以下

1つのカラム内でのリスト検索

WHERE カラム名 IN (値1, 値2, ……)

ex)
SELECT * FROM users WHERE prefecture IN ("岐阜", "愛知");

データの検索と形成

データの結合

# CONCAT関数
CONCAT(文字列1, 文字列2, ……)

ex)
SELECT CONCAT(family_name, first_name) FROM users;

検索結果のカラム名の変更

# AS
SELECT 取得するデータ AS 別名

ex)
SELECT CONCAT(family_name, first_name) AS "名前" FROM users;

:pencil: ASは省略ができる。

重複するデータを除外

SELECT DISTINCT カラム名

ex)
SELECT DISTINCT user_id FROM units WHERE date = "2020-07-06";

レコードのグループ化

GROUP BY カラム名

ex)
SELECT user_id FROM units WHERE date = "2020-07-06" GROUP BY user_id;

:pencil: DISTINCT と GROUP BYの例文の取得データは同じ(見た結果)
GROUP BYは集計した結果を取得することができる。

レコードの数を取得

SELECT COUNT(カラム名)

ex)
SELECT user_id, COUNT(*) "コマ数" FROM units WHERE date = "2015-07-01" GROUP BY user_id;

集計関数

  • AVG 平均
  • MAX 最大値
  • MIN 最小値

データの結合

FROM テーブル名1 JOIN テーブル名2 ON テーブル名1.カラム名1 = テーブル名2.カラム名2

ex)
SELECT user_id, COUNT(*) "コマ数", FROM units s JOIN users u ON s.user_id = u.id WHERE date = "2020-07-06" GROUP BY user_id;

サブクエリ

SQLの中に入れ子になってSQLがはいっていること。

ex)
SELECT *
FROM users WHERE id NOT IN ( SELECT DISTINCT user_id FROM shifts WHERE date = "2015-07-01");



どんどん文が複雑になっていきますね。。
でも読み解くことはできるので慣れかな〜と思っています♫

お読みいただき、ありがとうございました?

SQLの基本的な文法まとめ①


  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Equalumがやって来た!(暴走編?)

Equalumの処理能力を探る・・?!

基本的に今回の一連の検証に関しては、約1秒(Pythonのsleep関数を使って設定)間隔で、上流側のCDC設定を行っているMySQL側にPython経由でデータを送り込んで作業を実施していますが、ここで少し0-400m的なチャレンジ企画を行ってみようと思います。

設定環境

環境としては

   (1)Equalumサーバ    Core i7 (4C8T) 32GB 256GB SSD CentOS7
   (2)MemSQLサーバ     Core i7 (4C8T) 32GB 256GB SSD CentOS7
   (3)MySQLサーバ     Core i7 (4C8T) 32GB 512GB SSD Windows10

    > Windows版のMySQLを利用し、同環境上にPythonを稼働
    > PCはベアボーンで構成した自作マシン
    > ネットワークはGbE(WiFiと兼用の市販汎用品)

になります。

image.png

使ったPythonスクリプトは以前の物から時間稼ぎの処理を取り除き、上流側のデータソースへ1000個のデータ生成を設定して一気に連続して挿入処理を実施し、ターゲット側のデータソースにそのままの形(レプリケーションと同じ)でEqualumに処理させる形の検証を行いました。

では検証結果を・・・

MySQL側の処理結果

  1|2020-07-03 14:47:04.167946|2020-07-03 14:47:04.0|泡盛     | 1980|    5|佐島  |
  2|2020-07-03 14:47:04.171034|2020-07-03 14:47:04.0|泡盛     | 1980|   10|一丁目 |
  3|2020-07-03 14:47:04.173314|2020-07-03 14:47:04.0|スコッチ   | 3500|    6|旭町  |
  4|2020-07-03 14:47:04.175366|2020-07-03 14:47:04.0|ビール    |  490|    5|一丁目 |
  5| 2020-07-03 14:47:04.17785|2020-07-03 14:47:04.0|泡盛     | 1980|    2|五本木 |

>>> 途中省略

498|2020-07-03 14:47:05.363334|2020-07-03 14:47:05.0|日本酒    | 1980|    8|一丁目 |  
499|2020-07-03 14:47:05.365319|2020-07-03 14:47:05.0|テキーラ   | 2000|   10|三丁目 | 
500|2020-07-03 14:47:05.367315|2020-07-03 14:47:05.0|テキーラ   | 2000|    3|住吉町 |  
501|2020-07-03 14:47:05.369285|2020-07-03 14:47:05.0|テキーラ   | 2000|    6|佐島  |
502|2020-07-03 14:47:05.371346|2020-07-03 14:47:05.0|芋焼酎    | 2000|    7|住吉町 |

>>> 途中省略

 996|2020-07-03 14:47:06.487793|2020-07-03 14:47:06.0|テキーラ   | 2000|    6|五本木 |
 997|2020-07-03 14:47:06.489917|2020-07-03 14:47:06.0|泡盛     | 1980|    2|二丁目 |
 998|2020-07-03 14:47:06.491941|2020-07-03 14:47:06.0|日本酒    | 1980|    9|古橋  | 
 999|2020-07-03 14:47:06.493771|2020-07-03 14:47:06.0|バーボン   | 2500|    8|西新町 |
1000|2020-07-03 14:47:06.495692|2020-07-03 14:47:06.0|スコッチ   | 3500|    7|旭町  |

MemSQL側の処理結果

  1|2020-07-03 14:47:04.167946|2020-07-03 14:47:04.0|泡盛     | 1980|    5|佐島  |
  2|2020-07-03 14:47:04.171034|2020-07-03 14:47:04.0|泡盛     | 1980|   10|一丁目 |
  3|2020-07-03 14:47:04.173314|2020-07-03 14:47:04.0|スコッチ   | 3500|    6|旭町  |
  4|2020-07-03 14:47:04.175366|2020-07-03 14:47:04.0|ビール    |  490|    5|一丁目 |
  5| 2020-07-03 14:47:04.17785|2020-07-03 14:47:04.0|泡盛     | 1980|    2|五本木 |

>>> 途中省略

498|2020-07-03 14:47:05.363334|2020-07-03 14:47:05.0|日本酒    | 1980|    8|一丁目 |
499|2020-07-03 14:47:05.365319|2020-07-03 14:47:05.0|テキーラ   | 2000|   10|三丁目 | 
500|2020-07-03 14:47:05.367315|2020-07-03 14:47:05.0|テキーラ   | 2000|    3|住吉町 | 
501|2020-07-03 14:47:05.369285|2020-07-03 14:47:05.0|テキーラ   | 2000|    6|佐島  | 
502|2020-07-03 14:47:05.371346|2020-07-03 14:47:05.0|芋焼酎    | 2000|    7|住吉町 |

>>> 途中省略

 996|2020-07-03 14:47:06.487793|2020-07-03 14:47:06.0|テキーラ   | 2000|    6|五本木 |
 997|2020-07-03 14:47:06.489917|2020-07-03 14:47:06.0|泡盛     | 1980|    2|二丁目 |   
 998|2020-07-03 14:47:06.491941|2020-07-03 14:47:06.0|日本酒    | 1980|    9|古橋  | 
 999|2020-07-03 14:47:06.493771|2020-07-03 14:47:06.0|バーボン   | 2500|    8|西新町 |
1000|2020-07-03 14:47:06.495692|2020-07-03 14:47:06.0|スコッチ   | 3500|    7|旭町  | 

各ポイントでの数値比較

# 最初のデータに関するタイムスタンプ情報
MySQL     1|2020-07-03 14:47:04.167946|2020-07-03 14:47:04.0
MemSQL    1|2020-07-03 14:47:04.167946|2020-07-03 14:47:04.0

# 中間データに関するタイムスタンプ情報
MySQK   500|2020-07-03 14:47:05.367315|2020-07-03 14:47:05.0
MemSQL  500|2020-07-03 14:47:05.367315|2020-07-03 14:47:05.0

# 最終データに関するタイムスタンプ情報
MySQL  1000|2020-07-03 14:47:06.495692|2020-07-03 14:47:06.0
MemSQL 1000|2020-07-03 14:47:06.495692|2020-07-03 14:47:06.0

1000個のデータ処理時間 2.327746   MySQLMemSQL間の平均TIMESTAMP(6)の差 0.000000

TIMESTAMP(6)における時間差0.000000秒の衝撃・・・

Fakerでデータを作成する際に、最初に秒単位までの日時情報を文字列化して上流側のMySQLに設定しているDemoテーブルのdtカラムに書き込んでEqualumに引き渡ししており、その情報は着地地点のMySQLまで引き継がれていますので、以前の検証の様に綺麗に1秒間隔にはならずに、1000個のデータにおけるこの部分は、かなりの数で同じ秒数を占めるdt情報が連続する形になっています。ですので、今回の「リミッター無し」の状況では、Equalumのコアにおけるkafka連携の性能がそのまま出る形になっていると考えられ(途中の計算処理等を外している関係上、Sparkエンジンを深く叩くことは無いと思われますので・・・)、まさに1000個の連続処理を超高速で行う仕組みを、誰でもプログラム不要で構成出来るポテンシャルが有る・・という事を明確に示していると言えるでしょう。

約2秒で1000個のデータ処理をプログラム不要で実現するという事・・・・

また、今回は自動車の世界でいうところの・・・0-400mやドラッグレース的な感じの検証にはなるかと思いますが、速さの余裕は何度も申し上げている通りに、諦めていた仕様の実現可能性を一気に引き上げると同時に、新たなデータ・コンピューティングのアイディアを創出出来るという事です。そしてこの事は、データセントリックという考え方で、データドリブンの為のデータコンピューティング・・・そしてその可能性を飛躍的に高めるポテンシャルをEqualumは持っているという事を、明確かつ如実に示してくれたのかもしれません。

今回のまとめ

今回は、暴走編としてEqualumに0-400m的なベンチマーク検証を行ってみました。結果としては、複雑な処理FLOWをデザインして間に入れても良し、単純にレプリケーション的に利用する事(例えば現業に影響を及ぼさずに、レプリカ側にAIとかBIとか各種のデータ・ソリューションを連携させ、同じ時間帯でより高度なデータ連携作業を可能にする(現場の仕事を、今のデータでバックエンド側から能動的にサポートする事が可能になります)という、データドリブンの時間軸を極めて今に近い今!で実施することが出来るようになる事を明確に示しています。

image.png

現場で稼働している既存業務系のデータベース絡みの仕組みは、設計段階からキチンとサイジングされている状況が普通だと思いますので、昨今脚光を浴びている「後付けのトランザクション製造機」的なデータ・コンピューティング系のソリューションを連携させる事・・・かなり現場側への負担が増加する方向になってしまい、結局現場の業務の後とか合間に・・・という利用になっているのではないでしょうか?

現場が忙しい時に、そのデータを即時活用してサポートや展開する作業も忙しくなる・・・

まさに、データドリブンでDx時代における「ジレンマの一つ」かもしれません。

また、従来からのバッチ処理に関しても、データの流れを上手くデザインする事により、今までのような「かなり昔に遡っての作業」ではなく、処理の間隔を短時間化させる事が出来るようになると思いますので、良い意味での「小計」確認とそれに対する適切な施策等が可能になるでしょう。

ちなみに、今回のベンチマーク的な時間計測に関するEqualum側の設定でも・・・当然一切のプログラミング作業は発生しなかった事を最後に報告させて頂きます。

誰でもkafka/Spark使いに「プログラミング無しでなれる」・・・

データは結果の一つではあるが、その結果のすぐ後には新しいデータが発生している
データに関わる時間軸への柔軟性を積極的に活用する事で、より戦略的なドリブンを可能に出来る

xxオンラインシステム・・的な年ベースのBigプロジェクトではなく、データサイエンティストの方や、プログラミングは・・・でも社内の業務関連DBのテーブルとカラム位の意味は分かる(どのテーブルに何のカラムが有るかでOKです)。。。という方であれば、最前線のkafkaベースの出高度なリアルタイム・データ・システムが作れる時代になったという事が、一連のEqualum検証で見えてきた事実かもしれません。

次回こそは番外編としてEqualumにもれなく付いてくるバッチ系の簡単な検証を追加して前半戦を終了させて頂こうかと思います。
・・・新しいネタが有れば、暴走編2になるかもしれませんが・・・・

Equalumがやって来た!(爆走編?)に続く

謝辞

本検証は、Equalum社の特別の許可を得て実施しています。この貴重な機会を設定して頂いたEqualum社に対して感謝の意を表すると共に、本内容とEqualum社の公式ホームページで公開されている内容等が異なる場合は、Equalum社の情報が優先する事をご了解ください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SQLの基本的な文法まとめ①

SQLの基本的な文法について学び直しました。
自分のメモ用としても記録しています。

データを定義する

DDL(Data Definition Language)

  • CREATE
  • ALTER
  • DROP

データを操作する

DML(Data Manipulation Language)

  • INSERT
  • UPDATE
  • DELETE
  • SELECT



:pencil: ;(セミコロン)文末につける
:pencil: 大文字でも小文字にでもOK!

データベースの構造の操作

データベースの一覧表示

SHOW DATABASES;

データベースの選択

USE データベース名;

データベースの作成

CREATE DATABASE データベース名;

テーブルの構造の操作

テーブルの確認

SHOW TABLES;

テーブルの作成

CREATE DATABASE テーブル名 (カラム名 カラムの型, カラム名 カラムの型, ...);

テーブルの構造確認

SHOW columns FROM テーブル名;

ALTER TABLE文

テーブルの構造の変更にて使用。

  • カラムの追加
  • カラムの修正
  • カラムの削除
ALTER TABLE テーブル名 操作

カラムを追加する

# 1つのカラムを追加する
ALTER TABLE テーブル名 ADD カラム名 カラムの型;

# 複数のカラムを追加する
ALTER TABLE テーブル名 ADD (カラム名 カラムの型, カラム名 カラムの型, ...);

カラムを修正する

ALTER TABLE テーブル名 CHANGE 古いカラム名 新しいカラム名 新しいカラムの型;

:pencil: カラムの型は変更していなくても、再度記述が必要です。

カラムを削除する

ALTER TABLE テーブル名 DROP カラム名;

データの操作

データを登録する

# 全てのカラムに値を登録する
INSERT INTO テーブル名 VALUES(値1, 値2, 値3);

# 特定のカラムに値を登録する
INSERT INTO テーブル名(カラム名1, カラム名2) VALUES(値1, 値2);

:pencil: 文字列はクォーテーションで囲む。(ダブルクォーテーションでもOK)

データを更新する

UPDATE テーブル名 SET 変更内容 WHERE 条件;

ex)
DELETE FROM books WHERE id = 2;

データを削除する

DELETE FROM テーブル名 WHERE 条件;




SQLの基本的な文法まとめ②では、データベース内の検索について書きます。
お読みいただき、ありがとうございました?


  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Knex.jsでMySQLのUPSERTを実行する方法

Knex.jsで、MySQLのUPSERTを実行する方法を紹介します。

UPSERTとは

UPSERTとは、RDBにおいてキーが重複するレコードがあればUPDATEし、なければINSERTする処理のことです。
といっても、UPDATE文やINSERT文のようにUPSERT文があるわけではないので、データベース製品によってその構文は異なります。

MySQLにおけるUPSERT

MySQLでUPSERTを行なうには、INSERT ... ON DUPLICATE KEY UPDATE構文を用います。1

INSERT INTO `users` (`id`, `name`, `status`)
  VALUES (1, 'John Smith', 'I\'m happy')
  ON DUPLICATE KEY UPDATE `id` = 1, `name` = 'John Smith', `status` = 'I\'m happy';

UPSERT用関数を作成

Knex.js自体にはUPSERT用のAPIはないので、UPSERTを実行するための関数をつくります。

import Knex from 'knex'

interface Params {
  db: Knex,
  table: string,
  record: Record<string, any>
}

/**
 * Execute UPSERT (INSERT ... ON DUPLICATE KEY UPDATE) for MySQL
 * @see https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html
 */
export function upsert ({
  db,
  table,
  record
}: Params): Knex.Raw<any[]> {
  const insert = db.insert(record).into(table)
  const values = Object.entries(record)
    .map(([column, value]) => db.raw('?? = ?', [column, value]))
    .join(', ')
  return db.raw(`${insert} ON DUPLICATE KEY UPDATE ${values}`)
}

この関数は、次のように使用します。

await upsert({
  db: knex,
  table: 'users',
  record: {
    id: 1,
    name: 'John Smith',
    status: "I'm happy"
  }
})

戻り値の型はKnex.Raw<any[]>なので、生成されたSQL文字列を取得することもできます。

const query = upsert({
  db: knex,
  table: 'users',
  record: {
    id: 1,
    name: 'John Smith',
    status: "I'm happy"
  }
})
console.log(query.toString())
await query

上記の出力を整形(可読性のために改行を追加)すると、次のようになります。

insert into `users` (`id`, `name`, `status`)
  values (1, 'John Smith', 'I\'m happy')
  ON DUPLICATE KEY UPDATE `id` = 1, `name` = 'John Smith', `status` = 'I\'m happy'

参考リンク

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

docker-composeで、nginx、php、mysqlの環境を作成してみた

私は初心者です。間違っていたりもっと良いやり方がありましたら教えていただけるとありがたいです

こちらのリンクにコードを置きました

参考

docker-compose.yml
version: "3"

services:
  web:
    image: nginx
    ports:
      - "8080:80"
    volumes:
      # ホストのdefault.confを同期
      - ./default.conf:/etc/nginx/conf.d/default.conf
      # ホストの./myappフォルダを同期
      - ./myapp:/var/www/html
    depends_on:
      - php

  php:
    build: .
    volumes:
      # ホストの./myappフォルダを同期
      - ./myapp:/var/www/html

  db:
    image: mysql
    # PDOでhostを指定するときにこのコンテナ名を使う
    container_name: mysql
    # MySQL8.0でのデフォルトの認証方式が「caching_sha2_password」なので変更する
    # 設定しないと "The server requested authentication method unknown to the client" とエラーになる
    command: --default-authentication-plugin=mysql_native_password
    environment:
      # 設定必須、rootパスワード
      - MYSQL_ROOT_PASSWORD=root
      # この設定はオプション、イメージの起動時に作成されるデータベース名
      - MYSQL_DATABASE=sample
default.conf
server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;
    root /var/www/html;

    location / {
        index  index.php index.html;
    }

    location ~ \.php$ {
       fastcgi_pass   php:9000;
       fastcgi_index  index.php;
       fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
       include        fastcgi_params;
    }
}
Dockerfile
FROM php:7-fpm

# 拡張モジュールをインストール
RUN docker-php-ext-install pdo pdo_mysql
myapp/index.php
<?php
    try {

        echo (new PDO(
            'mysql:host=mysql;dbname=sample;charset=utf8mb4',
            'root',
            'root',
            [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            ]
        ))
        ->query('select concat(\'MySQL Version :\', version()) v')
        ->fetch()['v'];

    } catch (PDOException $e) {
        echo $e->getMessage();
    }

Screen Shot 2020-07-06 at 2.20.15.png

以上です。m(_ _)m

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【MySQL】特定のテーブルでERROR 1064 (42000)

概要

正しくSELECT文を打ったのに、特定のテーブルでERROR 1064 (42000)エラーがでてしまう現象を解決。

ふと、あれ?と思ってしまったので備忘録

テーブル名が予約語の場合は要注意

今回groupsテーブルをSELECTしようとしたらエラーになってしまった。

mysql> SELECT * FROM groups;

対処法

テーブル名に「`」で囲む

mysql> SELECT * FROM `groups`;

以上。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む