はじめてのMySQL
突然いろいろすっ飛ばすが、バージョンが5.7か8かみたいになってるのはなぜ…?
え、なんで急に5.7から8なん笑
なにか別のところから来た数字なんだろうか…
Myは生みの親Wideniusさんの娘さんの名前由来なんだ…脱退後に作ったMariaDBのMariaは次女の名前由来。v6/v7がない理由はよくわからない。v8も2018年からとのことなので、とりあえずv8を使っておけばよさそう。
ツール
CREATE TABLE
uuid
え、ただただUUIDにするだけでめちゃめちゃ大変じゃない…?そういうもん…?
- customer_id binary(16) primary key default (UUID()),
+ customer_id binary(16) primary key default (UUID_TO_BIN(UUID(), 1)),
これでいけた
int
text
created_at, updated_at
copilotだとnow()になったけど何がちがう…?シノニムってことは同じ?
ChatGPTに聞いてみた
Q: current_timestampとnow()の違いはなんですか?
A: CURRENT_TIMESTAMPとNOW()は、MySQLの両方の関数で、現在の日時を返します。しかし、次のような違いがあります。
CURRENT_TIMESTAMPは、SQL標準で定義されている関数であり、構文はCURRENT_TIMESTAMPまたはCURRENT_TIMESTAMP()です。
NOW()は、MySQL固有の関数であり、構文はNOW()です。
CURRENT_TIMESTAMPは、引数を取らない場合は、現在の日時を返します。ただし、引数を指定することで、指定したタイムゾーンでの現在時刻を取得することもできます。例えば、CURRENT_TIMESTAMP('+9:00')とすると、UTC+9のタイムゾーンでの現在時刻を返します。
NOW()は、常に現在の日時を返します。引数を指定することはできません。
したがって、CURRENT_TIMESTAMPはより柔軟であり、タイムゾーンを変更できるため、クロスタイムゾーンの環境で使用する場合に便利です。一方、NOW()はシンプルで使いやすく、常に現在の日時を返すため、特に日時のタイムゾーンを意識する必要がない場合に便利です。
Q:
CURRENT_TIMESTAMP
とCURRENT_TIMESTAMP()
の違いはなんですか
A: CURRENT_TIMESTAMPとCURRENT_TIMESTAMP()は、MySQLの関数であるCURRENT_TIMESTAMPの構文に関する違いです。
CURRENT_TIMESTAMPは、構文にカッコをつけなくても機能する関数で、引数を持たない場合は現在のタイムスタンプを、引数を持つ場合は指定したタイムゾーンでのタイムスタンプを返します。つまり、以下の2つのクエリは同じ結果を返します。
sql
Copy code
SELECT CURRENT_TIMESTAMP;
sql
Copy code
SELECT CURRENT_TIMESTAMP();
一方、NOW()という関数は、構文にカッコをつけないと機能しません。つまり、以下の2つのクエリは異なる結果を返します。
sql
Copy code
SELECT NOW;
sql
Copy code
SELECT NOW();
NOWは、無効な関数名として解釈され、エラーが発生します。一方、NOW()は、現在のタイムスタンプを返します。
とりあえずTimestampは使わずDatetimeでいいよって感じなのかな…?なぜ上の人はupdated_atだけTimestampをつかったのか…
FK
FK大変…
その他
どちらかが必須
Q: 2つのカラムのうち、どちらかが必須という指定はどうすればよいでしょうか
A: 2つのカラムのうち、どちらかが必須という指定をするには、CHECK 制約を使用することができます。以下は、例として column1 と column2 のうち、どちらかが必須であるテーブルを作成する例です。
sql
Copy code
CREATE TABLE my_table (
id INT PRIMARY KEY,
column1 VARCHAR(50),
column2 VARCHAR(50),
CHECK (column1 IS NOT NULL OR column2 IS NOT NULL)
);
このように、CHECK 制約を使用することで、カラムの値に対する複雑な制約を定義することができます。ただし、CHECK 制約は、一部のMySQLバージョンではサポートされていない場合があるため、使用する前に確認してください。また、CHECK 制約は性能の観点から、使用を避けるべき場合もあります。
ChatGPTのやり取りをきれいに貼り付ける方法ないだろうか。
日本語がでない
Docker内のMySQLで日本語を打つと空文字になってしまう。
エラーでた
create table hoge4(
customer_id char(36) primary key,
phone text not null,
);
エラー文不親切過ぎん!?
create table hoge(
customer_id char(36) primary key,
- phone text not null,
+ phone text not null
);
最後のカンマがだめだったぽい
- create table hoge1 ()
- create table hoge2 ()
+ create table hoge1 ();
+ create table hoge2 ();
セミコロン必要
create table hoge (
...
- price int not null unsigned,
+ price int unsigned not null,
...
);
unsignedが先
DB思った以上にめんどくさい…めんどくさいというか、初心者からするとデフォルトで決まっていてほしいことがいろいろ決まってない感じ?
テーブル変更
INSERT
ダミーデータの投入
テーブルAのUUIDをテーブルBのFKとして参照する場合、まずテーブルAを一旦insertし、そのIDをコピーして、下記のように固定し、その固定したUUIDをBのFKとして利用するということをやろうとしていたが、selectでinsertできるらしい。
// テーブルA
insert into M_SET_TYPES(set_type_id, name) values
- (UNHEX('11EDDBA6561E5DA09B0D0242AC150002'), '盛り込み'),
- (UNHEX('11EDDBA6561EB7699B0D0242AC150002'), 'にぎり'),
+ ('盛り込み'),
+ ('にぎり'),
// テーブルB
insert into M_SET_MENUS(set_id, set_type_id, name, price) values
- (UNHEX('11EDDBA756CFE5B49B0D0242AC150002'), UNHEX('11EDDBA6561E5DA09B0D0242AC150002'), 'はな', 8650),
- (UNHEX('11EDDBA756D0836D9B0D0242AC150002'), UNHEX('11EDDBA6561E5DA09B0D0242AC150002'), 'わだつみ', 5680),
+ ((select set_type_id from M_SET_TYPES where nama='盛り込み'), 'はな', 8650),
+ ((select set_type_id from M_SET_TYPES where nama='盛り込み'), 'わだつみ', 5680),
SELECT
LIKEよくわからん
なるほど
UNION