SQLでJSONを使う

MySQLやMaria DBでも、JSON を使える

create tableでJSON型を指定

CREATE TABLE AlphaVantage (
   t_date date NOT NULL,
   ticker VARCHAR(255) NOT NULL,
   income_stmt JSON,
   CHECK (JSON_VALID(income_stmt)),
   balance JSON,
   CHECK (JSON_VALID(balance)),
   PRIMARY KEY (t_date,ticker)
);

insert 文. json.dump

url = 'https://www.alphavantage.co/query?function=INCOME_STATEMENT~' 
r = requests.get(url)
income_data = r.json()

url = 'https://www.alphavantage.co/query?function=BALANCE_SHEET~'
r = requests.get(url)
balance_data = r.json()

try :
   sql = ('INSERT INTO AlphaVantage  (t_date, ticker, income_stmt,balance) VALUES (now(6), %s, %s,%s) ON DUPLICATE KEY UPDATE income_stmt = VALUES (income_stmt),balance=VALUES(balance);')
data = [
(ticker_name, json.dumps(income_data),json.dumps(balance_data)) 
]
cur.executemany(sql, data)

select は JSON_EXTRACTで

select JSON_EXTRACT(balance, '$.annualReports[0].totalShareholderEquity')
from AlphaVantage;

SQL Chat で Median計算してみた

SQLでMedian(中央値)を求める方法を説明します。

テスト用テーブルの作成

SQL Chat を使い、テーブルを作るSQL文を生成してもらいました。(ChatGPTに聞いているのと同じ)

CREATE TABLE salary_info 
( id INT NOT NULL AUTO_INCREMENT,
 employee_id INT NOT NULL, 
salary INT NOT NULL, 
bonus INT NOT NULL, 
allowance INT NOT NULL, 
tax INT NOT NULL, 
total_salary INT NOT NULL, 
payment_date DATE NOT NULL, PRIMARY KEY (id) );

データの登録

insert文も SQL Chatにお願いしてみた。正解にいたるまで、いろいろエラーになる回答を出してきましたね。

DELIMITER //

CREATE PROCEDURE insert_salary_info()
BEGIN
  DECLARE i INT DEFAULT 1;
  WHILE i <= 100000 DO
    INSERT INTO salary_info (employee_id, salary, bonus, allowance, tax, total_salary, payment_date)
    VALUES (
      FLOOR(RAND() * 1000) + 1,
      FLOOR(RAND() * 500000) + 100000,
      FLOOR(RAND() * 100000),
      FLOOR(RAND() * 50000),
      FLOOR(RAND() * 100000),
      (salary + bonus + allowance) - tax,
      DATE_ADD('2021-01-01', INTERVAL FLOOR(RAND() * 365) DAY)
    );
    SET i = i + 1;
  END WHILE;
END //

DELIMITER ;
CALL insert_salary_info();

Median 関数の本当の方法

中央値はMedian関数を使います。distinctしないと行数文出力されるから、注意しましょう。over()に何も指定しないと全行に対する中央値となります。

MariaDB [sqlchat]>  select distinct median(salary) over() from salary_info;
+-----------------------+
| median(salary) over() |
+-----------------------+
|     349909.0000000000 |
+-----------------------+
1 row in set (0.105 sec)

SQL ChatのMedian求め方

SQL Chatは、Median関数ではなく、ずいぶん複雑なSQLを出してきました。このあたり、まだまだですね。

しかも間違い

SQLのgroup by

SQLを扱う場合、よく使われるのが「GROUP BY」です。GROUP BYは、指定したカラムでデータをグループ化して表示するためのものです。

例えば、以下のような投稿データがあったとします。

idtitlecategory
1WordPressの使い方WordPress
2PHPの基礎PHP
3MySQLの使い方MySQL
4WordPressの使い方WordPress
5Laravelの基礎Laravel

このデータを、categoryごとにグループ化して表示するには、以下のようなSQLを書きます。

SELECT category, COUNT(id) as count FROM wp_posts GROUP BY category;

このSQLを実行すると、以下のような結果が得られます。

categorycount
WordPress2
PHP1
MySQL1
Laravel1

このように、同じカテゴリーの投稿をグループ化して、その数を計算することができます。また、GROUP BYにはさまざまな関数を組み合わせることができるため、より高度な集計を行うこともできます。

WordPressでは、データベースにアクセスするための関数が用意されており、これらを利用することで簡単にSQLを実行することができます。以下は、上記のSQLをWordPressで実行する例です。

wordpressのSql実行例
global $wpdb;

$result = $wpdb->get_results("
    SELECT category, COUNT(id) as count
    FROM {$wpdb->prefix}posts
    GROUP BY category
");

foreach ($result as $row) {
    echo "{$row->category}: {$row->count} posts<br>";
}

このように、WordPressではSQLを簡単に扱うことができます。GROUP BYを使って、データの集計や分析を行う際には、ぜひWordPressの関数を活用してみてください。

SQL Chat ってどう?

SQL Chatとは

SQL chatは、生成AIサービスのchatGPTと連携したSQLエディターサービスです。運営元はBytebaseっていう中国系の会社のようでセキュリティは気になりますね。Tikokの運営会社のBytedanceと似た名前ですよね

Linked In で見ると、出身者の多くは中国です。
本社はUS San Noseなんですが、やっぱ中国系かなあ
https://www.linkedin.com/company/bytebase/people/

OpenAIのAPIキー取得

OpenAIのサイトでView API Keysを選択します

create new secret keyからAPIキーを作成

これでAPIキーは取得出来ます。

SQL Chatの設定

Gitリポジトリをクローン

# git clone https://github.com/sqlchat/sqlchat.git

envファイルを編集

# cd sqlchat ; cp .env.example .env
# vi .env
# Do not share your OpenAI API key with anyone! It should remain a secret.
  OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxx # ここに追加
  OPENAI_API_ENDPOINT=xxxxxxxxxxxxxxxxx #(オプション)ここに追加

PNPMをインストールしてプログラムを起動

# curl -fsSL https://get.pnpm.io/install.sh | sh -

SQL Chat を起動

# pnpm i && pnpm dev

画面イメージはデモサイトが参考になります

SQL入門

データベース

※データベースを知らない人向けに、SQLを簡単に説明する記事です。

リレーショナル・データベースでは、表形式のデータに対し、IDとなる列を決め、IDの値を指定してアクセスします。

社員情報のテーブルです。この社員IDのような列を「主キー」と呼びます。以降では社員情報をデータベースに格納する方法を説明します。

社員ID 社員名所属部署
0001田中 ABC人事部
0002山田 CDE営業部
0003佐藤 XYZ情シス部
0004鈴木 ABC人事部
0005佐藤 CDE営業部

Oracleのマニュアルのリレーショナルデータベースの記事も参考になります

テーブルを作る

まず最初にテーブルを作ります。その名も “CREATE TABLE”。先頭で、各レコードを一意に特定できるID情報を主キーに設定します。

MySQL)

CREATE TABLE shain_table
(shain_no int NOT NULL PRIMARY KEY,
 shain_name varchar(30),
 busho varchar(20));

Oracle)

CREATE TABLE shain_table
(shain_no number NOT NULL PRIMARY KEY,
 shain_name varchar2(30),
 busho varchar2(20));

参考:Oracleマニュアル 

データを登録する

テーブルにデータを登録します。 INSERT文を使います

insert into shain_table values( 1, '田中 ABC','人事部');
insert into shain_table values( 2, '山田 CDE','人事部');
insert into shain_table values( 3, '佐藤 XYZ','情シス部');

SELECT する

SELECT 文でデータを取得します。

select * from shain_table;

| shain_no | shain_name | busho   |
|        1 | 田中 ABC   | 人事部   |
|        2 | 山田 CDE   | 人事部   |
|        3 | 佐藤 XYZ   | 情シス部|
3 rows in set (0.000 sec)

検索条件を指定する場合

select * from shain_table where shain_no =3;

| shain_no | shain_name | busho  |
|        3 | 佐藤 XYZ   | 情シス部 |
1 row in set (0.000 sec)

まあ、はじめはこんな感じです。エクセルのような表形式のデータを扱うイメージがついてくれればいいのですが

RMAN

RMANについて    


RMAN (Recovery Manager) は、Oracle DBを丸ごとバックアップを取得するツールで、マルチテナントのPDBの単位でバックアップ・リストアが出来ます。


データをいつでも戻せるよう、RMANを毎日実行するのが、Oracleの基本的な考え方になっています。

Data Guard環境だとプライマリのバックアップからスタンバイもリストア出来たり、非常に便利ですね。

RMANとData Pumpの相違

Data PumpとRMANは似ているんですが、機能は違うんです。毎日のバックアップをしっかりとる、という場合はRMANを使います。

RMANData Pump
DB全体のバックアップ
差分バックアップ×
データ時点の保証×
テーブル単位のバックアップ×

バックアップ方法

RMANのバックアップ先をまず考える必要があり、本来はメディアライブラリですが、ディスクに格納する場合もあります。

まあ、ディスクに格納する場合はDB サーバのディスクが全体的に壊れた時に戻せなくなるのが難点ですね。

メディアライブラリNetBackupやArcServeといったバックアップソフトのOracleオプションとの統合
ディスクディスク上へのバックアップ

MySQLとは

MySQLの人気

DBMSの人気ランキング
https://db-engines.com/en/ranking

1Oracle
2MySQL
3SQL Server
4PostgreSQL
5MongoDB
6Redis
7IBM DB2
8Elasticsearch
9SQLite
10Access

世界には多くのデータベースソフトがあって、一番人気は Oracle DB。それ以外では、フリーソフトであるMySQLの人気が高いです。

MySQLから派生したMariaDBも人気があります。Linuxのインストーラには、MariaDBの方が入ってます。

MySQLのインストール方法

MySQLやMaria DBのインストールは、Oracle と比べてとても簡単です。

# apt install mysql-server
# mysql_secure_installation

これですぐにデータベースとして利用できます。

$ sudo mysql
> CREATE DATABASE db;

> GRANT ALL ON 
  db.* TO user@localhost 
  IDENTIFIED BY pass;

インストールも簡単で無償。あまり重要じゃないシステムであれば、MySQLで十分じゃないですかね?

MySQLのバックアップ

その名も”mysql-backup”というコマンドがあり、これをcronに登録すれば、簡単にバックアップできます。

mysql-backup -uroot --backup --target-dir /root/backup

mysqldump と mysql-backupの違い

mysqldump というテーブル単位でバックアップをとるツールもありますが、毎日のバックアップにはmysql-backupをつかいます。

Oracle DB のRMAN と Data Pumpの関係に似ていると思いませんか。RMANの記事

mysql-backupmysqldump
DB全体のバックアップ
差分バックアップ×
データ時点の保証×
テーブル単位のバックアップ×

Data Pump

エクスポートの方法

Data Pumpはテーブルのエクスポートに使います。以下はスキーマ単位でエクスポートする例です。

$ expdp user/password@pdb1
   schemas=user  
   directory=data_directory
   dumpfile=xxx.dmp
※ ORACLEと同じサーバで実行する

ディレクトリ作成


OSコマンドでディレクトリを作成した後で、sqlplusでも設定が必要です。昔のエクスポート(exp)ではこの作業は不要だったんで、注意が必要

$ mkdir /home/oracle/dump
$ sqlplus sys/xxx@pdb
SQL> create or replace directory
 data_directory as '/home/oracle/dump'

インポート方法

データがおかしくなった場合の復旧や
別のサーバにデータをコピーしたい場合にインポートします。

$ impdp user/password@pdb1
   schemas=user  
   directory=directory
   dumpfile=xxx.dmp

初めてのOracle Cloud

Oracle CloudはOracle社が提供する
パブリック・クラウドサービス
IaaS、SaaSなどで使える

<Oracle Cloud ホームページ>
https://www.oracle.com/jp/cloud/

Oracle Cloud 無料枠(Free)

以下の機能が無料で利用できて、Oracleのテスト環境として便利そうですね。

2つのOracle Autonomous Database
2つのAMD Compute VM

クレカ認証に失敗しやすい

多くのブログで記載されてるんですが、Oracle Cloud無料枠のクレジットカード認証は失敗する場合が多く、「鬼」と書いているブログも。

私もサインアップできませんでした。残念。。