20210917のMySQLに関する記事は4件です。

外部キー制約での整合性について

はじめに 現在GolangでAPIサーバーを構築しております。 それに伴いDBの関連付けを行おうとしたところエラーが起きて躓いてしまったため、記録を残します。 外部キー制約について(公式より) MySQL では、テーブル間の相互参照関連データを許可する外部キー、および関連データの一貫性を保つための外部キー制約がサポートされています。 外部キー関係には、初期カラム値を保持する親テーブルと、親カラム値を参照するカラム値を持つ子テーブルが含まれます。 子テーブルに外部キー制約が定義されています。 環境 MYSQL8.0 問題のコード CREATE TABLE `users` ( id bigint AUTO_INCREMENT NOT NULL, name VARCHAR(255), created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP, deleted_at TIMESTAMP NULL DEFAULT NULL, PRIMARY KEY (id) ); CREATE TABLE `answers` ( id INT AUTO_INCREMENT NOT NULL, user_id INT, answer VARCHAR(255), created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP, deleted_at TIMESTAMP NULL DEFAULT NULL, PRIMARY KEY (id), FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ); Migrateしようとしたら。。。。 Migration failed: Error 3780: Referencing column 'user_id' and referenced column 'id' in foreign key constraint 'answers_ibfk_1' are incompatible. handling 20210829033132-answers.sql usersテーブルのidカラムとanswersデーブルのuser_idの互換性がない。と怒られています。 修正版 CREATE TABLE `users` ( id INT AUTO_INCREMENT NOT NULL, ←ここを修正 name VARCHAR(255), created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP, deleted_at TIMESTAMP NULL DEFAULT NULL, PRIMARY KEY (id) ); CREATE TABLE `answers` ( id INT AUTO_INCREMENT NOT NULL, user_id INT, answer VARCHAR(255), created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP, deleted_at TIMESTAMP NULL DEFAULT NULL, PRIMARY KEY (id), FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ); すごく簡単なことでしたが、親テーブルと子テーブルの関連付けているカラムの型が異なっていたため、整合性がなくエラーになっていました。 ↓公式にも書いてありました。 外部キー内の対応するカラムと、参照されるキーは同様のデータ型を持っている必要があります。 ご参考まで。 参考サイト MYSQL公式
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Mysqlエラー:ERROR! The server quit without updating PID file

環境 $ mysql --version mysql Ver 8.0.26 for macos11.3 on x86_64 (Homebrew) 状況 Mysql起動時に下記の権限エラー $ mysql.server start Starting MySQL ./usr/local/Cellar/mysql/8.0.25_1/bin/mysqld_safe: line 144: /usr/local/var/mysql/XXXXXXMacBook-Pro.local.err: Permission denied /usr/local/Cellar/mysql/8.0.25_1/bin/mysqld_safe: line 144: /usr/local/var/mysql/XXXXXXMacBook-Pro.local.err: Permission denied /usr/local/Cellar/mysql/8.0.25_1/bin/mysqld_safe: line 199: /usr/local/var/mysql/XXXXXXMacBook-Pro.local.err: Permission denied /usr/local/Cellar/mysql/8.0.25_1/bin/mysqld_safe: line 144: /usr/local/var/mysql/XXXXXXMacBook-Pro.local.err: Permission denied ERROR! The server quit without updating PID file (/usr/local/var/mysql/XXXXXXMacBook-Pro.local.pid). 様々な記事を参考に試したが解決できず… ・PC再起動 ・Mysql再起動 ・権限付与 解決方法 最終手段としてMysqlを再インストールすることにした HomebrewでのMysqlの再インストールが丁寧に説明されていて分かりやすかった →無事にMysql起動できた! 参考 エラー解消で試したこと
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MysqlでLIKEを使う時の実験

Index 現在のMySQLはB+tree構造でデータを保存しています。 B+treeのイメージはこんな感じです。 Indexを使えば、検索するデータに辿り着くまでO(log(n))がかかることが分かります。 逆に、queryによってこのindexを使わなくなると、検索量がO(n)になって、 データが大きくなるにづれ、検索に非常に時間がかかることがあります。 実験 例えばこういうテーブルがあります CREATE TABLE table ( a string, b string, ); mysql> explain select * from table where a LIKE "abc%"; +----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+ | 1 | SIMPLE | table | NULL | range | a | a | 1022 | NULL | 1 | 100.00 | Using index condition | +----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+ 1 row in set, 1 warning (0.03 sec) mysql> explain select * from table where a LIKE "%abc"; +----+-------------+-----------+------------+------+---------------+------+---------+------+-------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------+------------+------+---------------+------+---------+------+-------+----------+-------------+ | 1 | SIMPLE | table | NULL | ALL | NULL | NULL | NULL | NULL | 49175 | 11.11 | Using where | +----+-------------+-----------+------------+------+---------------+------+---------+------+-------+----------+-------------+ 1 row in set, 1 warning (0.03 sec) mysql> explain select * from table where a LIKE "%abc%"; +----+-------------+-----------+------------+------+---------------+------+---------+------+-------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------+------------+------+---------------+------+---------+------+-------+----------+-------------+ | 1 | SIMPLE | table | NULL | ALL | NULL | NULL | NULL | NULL | 49175 | 11.11 | Using where | +----+-------------+-----------+------------+------+---------------+------+---------+------+-------+----------+-------------+ 1 row in set, 1 warning (0.03 sec) 結論を言うと indexを使う検索 前方一致 indexを使わない検索 後方一致 部分一致 LIKEを使う場合、前方一致を活用できるかどうかは検索時間の最適化に関わっています。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MySQLでLIKEを使う時の実験

Index 現在のMySQLはB+tree構造でデータを保存しています。 B+treeのイメージはこんな感じです。 Indexを使えば、検索するデータに辿り着くまでO(log(n))がかかることが分かります。 逆に、queryによってこのindexを使わなくなると、検索量がO(n)になって、 データが大きくなるにづれ、検索に非常に時間がかかることがあります。 実験 例えばこういうテーブルがあります CREATE TABLE table ( a varchar(255), b varchar(255), KEY 'a' ('a'), KEY 'b' ('b'), ); mysql> explain select * from table where a LIKE "abc%"; +----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+ | 1 | SIMPLE | table | NULL | range | a | a | 1022 | NULL | 1 | 100.00 | Using index condition | +----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+ 1 row in set, 1 warning (0.03 sec) mysql> explain select * from table where a LIKE "%abc"; +----+-------------+-----------+------------+------+---------------+------+---------+------+-------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------+------------+------+---------------+------+---------+------+-------+----------+-------------+ | 1 | SIMPLE | table | NULL | ALL | NULL | NULL | NULL | NULL | 49175 | 11.11 | Using where | +----+-------------+-----------+------------+------+---------------+------+---------+------+-------+----------+-------------+ 1 row in set, 1 warning (0.03 sec) mysql> explain select * from table where a LIKE "%abc%"; +----+-------------+-----------+------------+------+---------------+------+---------+------+-------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------+------------+------+---------------+------+---------+------+-------+----------+-------------+ | 1 | SIMPLE | table | NULL | ALL | NULL | NULL | NULL | NULL | 49175 | 11.11 | Using where | +----+-------------+-----------+------------+------+---------------+------+---------+------+-------+----------+-------------+ 1 row in set, 1 warning (0.03 sec) 結論を言うと indexを使う検索 前方一致 indexを使わない検索 後方一致 部分一致 LIKEを使う場合、前方一致を活用できるかどうかは検索時間の最適化に関わっています。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む