WAVE Log
テーブル名,カラム名

マイルール
1) 予約語に気をつける。
2) 大文字を使わない。
3) 複数単語の連結表記にはスネークケース( snake_case )を使う。

CREATE

CREATE TABLE `table_name` ( `id` int UNSIGNED NOT NULL AUTO_INCREMENT, `name` varchar(191) NOT NULL, `hash` varchar(255) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, `token` char(64) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, `url` varchar(2083) COLLATE utf8mb4_bin NOT NULL, `mail` varchar(254) COLLATE utf8mb4_general_ci NOT NULL, `color` varchar(7) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL DEFAULT '#0000ff', `timezone` varchar(50) CHARACTER SET ascii COLLATE ascii_bin NOT NULL DEFAULT 'Asia/Tokyo', `file` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, `font_name` VARCHAR(255) COLLATE utf8mb4_bin DEFAULT NULL, `birthday` date DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `unique_mail` (`mail`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

int:-2147483648~2147483647までの数字を格納できる。
UNSIGNED:正の数のみ設定できるようにする。0~4294967295まで格納できるようになる。

ストレージ最小値最大値
(バイト)(符号付き/符号なし)(符号付き/符号なし)
TINYINT1-128127
0255
SMALLINT2-3276832767
065535
MEDIUMINT3-83886088388607
016777215
INT4-21474836482147483647
04294967295
BIGINT8-92233720368547758089223372036854775807
018446744073709551615

AUTO_INCREMENT:レコードが追加されたとき、自動的に付与される(インクリメントされる)

varchar(文字数)
VARCHAR型の最大長は65,535バイト。 UTF-8エンコーディングを使用する場合、1文字が1〜4バイトで表現されるため、最大で16,383文字(全てが4バイト文字の場合)から65,535文字(全てが1バイト文字の場合)まで保存できる。

TEXT型
具体的な「文字数の指定」がなく、最大保存可能なバイト数で制限されます。

TEXT型の種類と最大サイズ
TEXT型 最大サイズ
TINYTEXT 255バイト
TEXT 65,535バイト
MEDIUMTEXT 16,777,215バイト
LONGTEXT 4,294,967,295バイト

DEFAULT:デフォルトの値を設定する。

date:yyyy-mm-dd
datetime:yyyy-mm-dd hh:mm:ss

NOT NULL を記述すると該当のカラムには NULL を格納できなくなります。デフォルトでは NULL が格納できます。

PRIMARY KEY:重複した値を登録することができなくなる(UNIQUE制約)。また、NULLを登録することもできなくなる(NOT NULL制約)。

UNIQUE KEY:重複を許可しないユニークな制約を付ける場合に使用します。
UNIQUE KEY キー名 (カラム名)の形式です。
キー名は省略可能ですが、指定すると管理しやすくなります。

《文字コードと照会順序》

`hash` → パスワードハッシュ値

utf8mb4またはascii
パスワードハッシュ値は通常英数字や特殊文字を含む固定長の文字列であるため、ASCII文字だけでも十分対応可能です。特にasciiは効率的で、ストレージ使用量を最小限に抑えます。ただし、環境や拡張性の観点でutf8mb4も一般的に使われます。

utf8mb4_binまたはascii_bin
ハッシュ値は大小文字やバイナリデータをそのまま比較する必要があるため、_binのようなバイナリ照会順序を使用するべきです。これにより、ハッシュ値同士を正確に比較することができます。

補足:
PASSWORD_DEFAULTは将来的に別のアルゴリズムに変更される可能性があります。そのため将来のアルゴリズムがより長いハッシュ値を生成する可能性を考慮し、VARCHAR(255) のように余裕を持たせて設計するのが一般的です。

ハッシュ値を保存する際に使用する文字コードと照会順序は、asciiとascii_binが最適です。効率的で正確に比較が可能です。

`token` → bin2hex(random_bytes(32))で生成されるURLトークン

asciiとascii_binが最適です。

さらに、トークンの安全な保存や運用を考慮して、以下の点を押さえておくとよいでしょう:
カラム長の設定: bin2hex(random_bytes(32))は64文字の固定長文字列を生成します。そのため、データ型はCHAR(64)を使用すると適切です。
インデックスの設定: トークンが検索や確認に頻繁に使われる場合、カラムにインデックスを設定することでパフォーマンスが向上します。

`url` → URLアドレス

utf8mb4
URLには英数字だけでなく、特殊文字や国際化ドメイン名(非ASCII文字を含む)が含まれることがあります。そのため、utf8mb4を使用することで、すべての可能性を包括的にサポートできます。

utf8mb4_bin
URLの正確な比較が必要な場合、大文字小文字や特殊文字の違いを区別する照会順序であるutf8mb4_binを使用すると適切です。URLアドレスは通常、完全一致で判定することが求められるため、バイナリ順序が最適です。

カラムの最大文字数:
データ型: VARCHAR(2083)
一般的に、URLの最大長はウェブブラウザの制限(例えば2083文字)を考慮して設定されます。これにより長いURLも問題なく保存できます。
短いURLだけを使用する場合は、必要に応じて制限を減らすことができますが、将来の拡張性を考慮して余裕を持たせるのが理想的です。

補足
インデックスの設定: URLが検索や一致判定に頻繁に使われる場合、インデックスを付与することで検索パフォーマンスが向上します。

`mail` → メールアドレス

utf8mb4
メールアドレスには、国際化ドメイン名や特殊文字(たとえば、非ASCII文字を含むアドレス)が含まれることがあり得ます。utf8mb4を使用することで、すべての可能性を包括的にサポートできます。
英数字のみのメールアドレスが多い場合でも、柔軟性のためutf8mb4が推奨されます。

utf8mb4_general_ci
メールアドレスのドメイン部分(例:@example.com)は大小文字を区別しないことが標準です。そのため、_ci(case-insensitive)の照会順序を使用することで、大小文字の違いを無視した比較が可能になります。

補足:
保存するカラムのデータ型:
メールアドレスの長さは通常最大254文字です。そのため、データ型はVARCHAR(254)を設定するのが一般的です。
一意性の保証:
メールアドレスはユニークな値であることが多いので、UNIQUE制約をカラムに追加することを検討してください。

`color` → Webの色指定

例えば#ff00ff(16進数表現)やrgb(0, 0, 255)、さらにはgreenのような英語名についても、データベースで保存する場合はasciiとascii_binが適しています。

1. 各形式に対する適合性
16進数カラーコード(例:#ff00ff) 文字列はASCII範囲内の文字(0-9, a-f, #)のみで構成されています。そのため、ascii文字コードで効率よく保存できます。
RGB形式(例:rgb(0, 0, 255)) この形式もASCII範囲内の文字(英数字と括弧、カンマ、スペース)で表現されるため、同様にasciiで対応可能です。
色名(例:green) 色名はすべて英字で表記されるため、ASCII文字セットで完全にカバーされます。

2. 照会順序(Collation)
色指定は正確な比較が必要になることが多い(特に16進数やRGB値)ため、大小文字区別をするascii_binが推奨されます。例えば、#FF00FFと#ff00ffを別々の値として扱いたい場合に役立ちます。#FF00FFと#ff00ffを同じものとして扱いたい場合は、ascii_general_ciの照会順序が適しています。

`timezone` → タイムゾーン名(例:Asia/Tokyo)

asciiとascii_binの設定で問題ありません。

理由
ASCII文字のみを使用
タイムゾーン名は英字、数字、スラッシュ(/)、およびアンダースコア(_)のみで構成されており、これらはすべてASCII文字セットに収まるため、asciiが適しています。
正確な比較が必要
タイムゾーン名は一般的に正確な一致が必要なデータ(Asia/Tokyoとasia/tokyoを区別するなど)なので、大小文字を区別するascii_binの照会順序が最適です。
カラムの最大文字数
タイムゾーン名は現在のIANAタイムゾーンデータベース(TZ Database)に基づいており、一番長いものは35文字程度です(例:America/Argentina/ComodRivadavia)。そのため、余裕を見て以下を推奨します:
データ型: VARCHAR(50) これにより将来の更新にも対応可能です。

`file` → ファイル名

utf8mb4
ファイル名には国際化された文字や特殊文字が含まれる可能性があります。utf8mb4を使用することで、ASCII文字だけでなく、全ての非ASCII文字も安全に保存できます。この設定は広範な文字セットに対応するため推奨されます。

utf8mb4_bin
ファイル名は通常正確な一致が必要なので、大文字小文字や特殊文字を区別する照会順序であるutf8mb4_binが最適です。

カラムの最大文字数:
データ型: VARCHAR(255) 多くのファイルシステムでは、ファイル名の長さが最大255文字までに制限されています(例: NTFSやext4)。これに合わせてデータベース側もVARCHAR(255)を設定するのが一般的です。

補足:
一意性の保証: ファイル名が一意である必要がある場合は、UNIQUE制約を追加して重複を防ぐことができます。
インデックス: ファイル名で頻繁に検索や比較を行う場合は、インデックスを設定することで効率を向上させます。
ディレクトリパスの扱い: ファイル名にディレクトリパスを含む場合は、より長いカラム(例: VARCHAR(1000)など)が必要になる可能性があります。

`font_name` → フォント名

文字コード
utf8mb4 → 日本語・絵文字・特殊記号をすべて安全に保存できる。

照合順序
utf8mb4_bin
→ 大文字小文字、記号、スペースの違いを厳密に区別する。
→ フォント名は「厳密一致」が基本なので最も安全。

utf8mb4 の照合順序比較
_general_ci _unicode_ci _bin _0900_ai_ci
(MySQL 8)
_uca1400_ai_ci
(MariaDB 11.5+)
大文字小文字 区別しない 区別しない 区別する 区別しない 区別しない
ひらがな/カタカナ 区別する 区別しない 区別する 区別しない 区別しない
絵文字の区別 弱い やや弱い 完全一致 強い 強い
INSERT

INSERT INTO table_name (number, name, mail, birthday) VALUES (440, 'Yuu', 'yuu@example.net', '2001-05-06');

SELECT

すべてのカラムの値を取得する

SELECT * FROM table_name;

10件読み飛ばして30件表示する(11~40番を表示)は、「LIMIT 10, 30」となる。

SELECT * FROM table_name LIMIT 10, 30;

読み飛ばしが0の場合は省略できる。
3件表示する。

SELECT * FROM table_name LIMIT 3;

「ORDER BY {カラム名}」を指定することで任意の列でソートすることができる。
ORDER BYでカラム指定した後に「DESC」を指定すると「降順」になる。
ORDER BYのデフォルトは「昇順」。意図的に昇順と指定する場合は「ASC」を指定する。

SELECT * FROM table_name ORDER BY number DESC;

ソートの対象として 2 つのカラムを指定する場合。
最初に name カラムの値でソートを行い、 name カラムの値が同じデータに関して number カラムの値でソートを行う。カラム毎に昇順か降順かは指定できる。

SELECT * FROM table_name ORDER BY name DESC, number ASC;

ランダムにレコードを取得する場合。

SELECT * FROM table_name ORDER BY RAND ();

SELECT文に続いて「WHERE 条件式」というように条件指定をして検索する。

SELECT * FROM table_name WHERE name = 'No Name';

複数の条件式を指定する際は、論理演算子の「AND」や「OR」で接続する。

ワイルドカードを使って文字列を検索する。
アンダスコア記号(_)→任意の1文字にマッチする。
パーセント記号(%)→0個以上のの連続した文字にマッチする。

SELECT * FROM table_name WHERE birthday LIKE '199%';

カラムの値が指定した値のリストの中に一致したものを抽出。

SELECT * FROM table_name WHERE id IN(8, 38, 43);

IN のリストの順番でソートする。

SELECT * FROM table_name WHERE id IN(7, 5, 3) ORDER BY FIELD(id, 7, 5, 3);

検索欄が空欄のとき、全検索にする。

SELECT * FROM table_name WHERE CASE WHEN 検索値 = '' THEN TRUE ELSE 検索対象列 = 検索値 END;

同一単語を複数カラム(colA, colB)にわたって検索する。

SELECT * FROM table_name WHERE CONCAT(IFNULL(colA,''), IFNULL(colB,'')) = 検索値;

UPDATE

指定したカラムの値を更新する。 WHERE 句を指定しなければテーブルに格納されているすべてのデータが更新される。特定のデータのカラムの値だけを更新したい場合は WHERE 句で指定する。

UPDATE table_name SET mail = 'yuu@example.com' WHERE name = 'Yuu';

UPDATE table_name SET name = 'John' WHERE id IN (1, 3, 5);

デフォルト値にする。カラム名を引数で指定する。指定のカラムにデフォルト値が設定されていない場合はエラーとなる。

UPDATE table_name SET name = DEFAULT(name) WHERE number = 00051;

カラムの値を1増やす。

UPDATE table_name SET colA = colA + 1 WHERE id = 123;

DELETE

データを削除する。 WHERE 句を指定しなければテーブルに格納されているすべてのデータが削除される。特定のデータを削除したい場合は WHERE 句で指定する。

DELETE FROM table_name WHERE id = 5;