1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【MySQL】少し踏み込んだMySQLの基本的な文法

Last updated at Posted at 2021-03-20

#はじめに

本記事は【MySQL】基本的な文法やデータ型についてまとめてみた。の続きです。
そちらをご覧になっていない方はもしよかったらご覧ください。

##コマンド

前回の記事で使用していた、postsテーブルを使用して説明していきます。

postsテーブルは、messagelikesの二つのCULUMNがありました。
Twitterでいう、ツイート内容といいねだと思ってください。

###値に制限をつける

テーブルを作成する際に、格納することができるデータに制限を付けることが出来ます。

message VARCHAR(140) UNIQUEですが、UNIQUEが追加されています。
このUNIQUEですが、同じ値がすでに存在している時にエラーが発生します。

また、likes INT CHECK (likes >= 0 AND likes <= 100)は、
0以上100以下でないとlikesに入れることができないという制限です。

CHECKの後に条件式を指定します。
ANDというのは**〜かつ〜**という意味で、前後の条件を満たしている時しかTRUEになりません。

次に場合ですと、Thanksが被っているのでエラーが発生します。

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  message VARCHAR(140) UNIQUE, 
  likes INT CHECK (likes >= 0 AND likes <= 100)
);

INSERT INTO posts (message, likes) VALUES 
  ('Thanks', 12),
  ('Thanks', 4),
  ('Merci', 100);

SELECT * FROM posts;

実行結果
ERROR 1062 (23000) at line 7: Duplicate entry 'Thanks' for key 'message'

なので、次のようにしてあげるとエラーが消えてデータを格納することが出来ます。

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  message VARCHAR(140) UNIQUE, 
  likes INT CHECK (likes >= 0 AND likes <= 100)
);

INSERT INTO posts (message, likes) VALUES 
  ('Thanks', 12),
  ('Thank you', 4),
  ('Merci', 100);

SELECT * FROM posts;

実行結果
+-----------+-------+
| message   | likes |
+-----------+-------+
| Thanks    |    12 |
| Thank you |     4 |
| Merci     |   100 |
+-----------+-------+

###主キーを設定する
テーブルからレコード(行)を取り出す際に、
そのレコードを一意に識別するためのカラムを設定するのが一般的です。

大抵の場合はidという名前でNULLではない整数の連番にします。
NULLとは、何も値が入っていない状態を指します。

テーブルのカラムにidを追加するので、
CREATE TABLE内にidを追加します。

この時、NULLは許容しないのでid INT NOT NULLと記述します。
**idはINT型でNULLはNOTですよ!**的な感じです。

また、このidを主キー(プライマリキー)にしたいので、
PRIMARY KEY (id)を定義します。

下記の場合では、(2, 'Arigato', 4)(2, 'Merci', 4)
idの値が被っているのでエラーが発生します。

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  id INT NOT NULL,
  message VARCHAR(140), 
  likes INT,
  PRIMARY KEY (id)
);
  
INSERT INTO posts (id, message, likes) VALUES 
  (1, 'Thanks', 12),
  (2, 'Arigato', 4),
  (2, 'Merci', 4);
  
SELECT * FROM posts;

実行結果
ERROR 1136 (21S01) at line 23: Column count doesn't match value count at row 1

なので、idを書き換えて再度実行してみます。

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  id INT NOT NULL,
  message VARCHAR(140), 
  likes INT,
  PRIMARY KEY (id)
);
  
INSERT INTO posts (id, message, likes) VALUES 
  (1, 'Thanks', 12),
  (2, 'Arigato', 4),
  (3, 'Merci', 4);
  
SELECT * FROM posts;

実行結果
+----+---------+-------+
| id | message | likes |
+----+---------+-------+
|  1 | Thanks  |    12 |
|  2 | Arigato |     4 |
|  3 | Merci   |     4 |
+----+---------+-------+

また、こちらのidですが、自動で振ることも可能です。

自動で振る場合はid INT NOT NULL AUTO_INCREMENTとします。

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  id INT NOT NULL AUTO_INCREMENT,
  message VARCHAR(140), 
  likes INT,
  PRIMARY KEY (id)
);
  
INSERT INTO posts (message, likes) VALUES 
  ('Thanks', 12),
  ('Arigato', 4),
  ('Merci', 4);
  
SELECT * FROM posts;

実行結果
+----+---------+-------+
| id | message | likes |
+----+---------+-------+
|  1 | Thanks  |    12 |
|  2 | Arigato |     4 |
|  3 | Merci   |     4 |
+----+---------+-------+

こちらの方がidの書き忘れもなく
自動で番号を増やしていってくれるので楽ですね。

###データの抽出

データを抽出する際にはSELECTを使用します。

今までSELECT * FROM posts;と記述していましたが、
テーブルから一部のデータを抽出することも出来ますし、
条件を付けて抽出することも出来ます。

SELECT * FROM posts;は全てのデータを抽出します。

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  id INT NOT NULL AUTO_INCREMENT,
  message VARCHAR(140), 
  likes INT,
  PRIMARY KEY (id)
);

INSERT INTO posts (message, likes) VALUES 
  ('Thanks', 12),
  ('Arigato', 4),
  ('Merci', 4),
  ('Gracias', 15),
  ('Danke', 23); 

SELECT * FROM posts;

実行結果
+----+---------+-------+
| id | message | likes |
+----+---------+-------+
|  1 | Thanks  |    12 |
|  2 | Arigato |     4 |
|  3 | Merci   |     4 |
|  4 | Gracias |    15 |
|  5 | Danke   |    23 |
+----+---------+-------+

SELECT * FROM posts;
SELECT id, message FROM posts;に変更します。

idmessageをpostsテーブルから抽出します。

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  id INT NOT NULL AUTO_INCREMENT,
  message VARCHAR(140), 
  likes INT,
  PRIMARY KEY (id)
);

INSERT INTO posts (message, likes) VALUES 
  ('Thanks', 12),
  ('Arigato', 4),
  ('Merci', 4),
  ('Gracias', 15),
  ('Danke', 23); 

SELECT id, message FROM posts;

実行結果
+----+---------+
| id | message |
+----+---------+
|  1 | Thanks  |
|  2 | Arigato |
|  3 | Merci   |
|  4 | Gracias |
|  5 | Danke   |
+----+---------+

SELECT * FROM posts;から
SELECT * FROM posts WHERE message != 'Danke';にします。

これは、messageの文字がDankeではないデータを抽出します。

なぜ、「ではない」なのかというと、message != 'Danke'の通り、
!=が使用されているからです。

!=は**ノットイコール(〜ではない)**という意味合いになります。

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  id INT NOT NULL AUTO_INCREMENT,
  message VARCHAR(140), 
  likes INT,
  PRIMARY KEY (id)
);

INSERT INTO posts (message, likes) VALUES 
  ('Thanks', 12),
  ('Arigato', 4),
  ('Merci', 4),
  ('Gracias', 15),
  ('Danke', 23); 

SELECT * FROM posts WHERE message != 'Danke';

実行結果
+----+---------+-------+
| id | message | likes |
+----+---------+-------+
|  1 | Thanks  |    12 |
|  2 | Arigato |     4 |
|  3 | Merci   |     4 |
|  4 | Gracias |    15 |
+----+---------+-------+

SELECT * FROM posts;から
SELECT * FROM posts WHERE likes >= 10 AND message = 'Thanks';にします。

SELECT * FROM postsの部分で、postsから全てのデータを抽出します。が、
WHERE likes >= 10 AND message = 'Thanks'の部分により、
likesの値が10以上かつmessageの文字がThanksのデータのみになります。

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  id INT NOT NULL AUTO_INCREMENT,
  message VARCHAR(140), 
  likes INT,
  PRIMARY KEY (id)
);

INSERT INTO posts (message, likes) VALUES 
  ('Thanks', 12),
  ('Arigato', 4),
  ('Merci', 4),
  ('Gracias', 15),
  ('Danke', 23); 

SELECT * FROM posts WHERE likes >= 10 AND message = 'Thanks';

実行結果
+----+---------+-------+
| id | message | likes |
+----+---------+-------+
|  1 | Thanks  |    12 |
+----+---------+-------+

###LIKEと"%"もしくは"_"で文字列を抽出する

文字列の抽出についてですが、完全一致なら=を使用すればよかったです。
しかし、一部分一致しているものを抽出したい!という時に%_を使います。

%0文字以上の任意の文字を、
_任意の一文字を表現することが出来ます。

例えば**「ありがとう」を含むデータを抽出してくれ!**という場合は
%ありがとう%のように記述します。

何文字かわからないけど、ありがとうの前後に文字がある場合なので%ありがとう%とします。

また、0文字以上の任意の文字列なので、
文字数だけでないどのような文字でも大丈夫です。

つまり、「ありがとう」という単語さえ入っていれば一致です。

では、実際に**「t」という文字が入っているデータ**を抽出します。

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  id INT NOT NULL AUTO_INCREMENT,
  message VARCHAR(140), 
  likes INT,
  PRIMARY KEY (id)
);

INSERT INTO posts (message, likes) VALUES 
  ('Thank you!', 12),
  ('thanks 100%', 4),
  ('Gracias', 4),
  ('Arigato_gozaimasu', 15),
  ('Arigato! desu', 23);

SELECT * FROM posts WHERE message LIKE '%t%';

実行結果
+----+-------------------+-------+
| id | message           | likes |
+----+-------------------+-------+
|  1 | Thank you!        |    12 |
|  2 | thanks 100%       |     4 |
|  4 | Arigato_gozaimasu |    15 |
|  5 | Arigato! desu     |    23 |
+----+-------------------+-------+

どれもtが入っているものです。

次に、**3文字目にYが入っているデータをくれ!**という場合。
%Y%としてしまうと、何文字目か分からないけどYが入っているデータが抽出されます。

3文字目という指定があるので、この時は_を使用します。
_任意の一文字を表現するので__YとすればOKです。

実際に3文字目にaが入っているデータを抽出します。

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  id INT NOT NULL AUTO_INCREMENT,
  message VARCHAR(140), 
  likes INT,
  PRIMARY KEY (id)
);

INSERT INTO posts (message, likes) VALUES 
  ('Thank you!', 12),
  ('thanks 100%', 4),
  ('Gracias', 4),
  ('Arigato_gozaimasu', 15),
  ('Arigato! desu', 23);

SELECT * FROM posts WHERE message LIKE '__a%';

実行結果
+----+-------------+-------+
| id | message     | likes |
+----+-------------+-------+
|  1 | Thank you!  |    12 |
|  2 | thanks 100% |     4 |
|  3 | Gracias     |     4 |
+----+-------------+-------+

無事抽出することが出来ました!

ここで一つ疑問に思うのが、
thanks 100%Arigato_gozaimasu のような文字列に対して、
%_で条件を絞る場合はどうすればいいの?ということです。

%%%のように記述しても全ての値を抽出するだけです。
ではどうするのかというわけですが、%\%%のように記述します。

バックスラッシュを付けることによって%が文字という扱いになります。
バックスラッシュの打ち方は、Macならoption + ¥キーです。
Windowsは¥キーだけで平気かな?

実際に記述してみます。

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  id INT NOT NULL AUTO_INCREMENT,
  message VARCHAR(140), 
  likes INT,
  PRIMARY KEY (id)
);

INSERT INTO posts (message, likes) VALUES 
  ('Thank you!', 12),
  ('thanks 100%', 4),
  ('Gracias', 4),
  ('Arigato_gozaimasu', 15),
  ('Arigato! desu', 23);

SELECT * FROM posts WHERE message LIKE '%\%%';

実行結果
+----+-------------+-------+
| id | message     | likes |
+----+-------------+-------+
|  2 | thanks 100% |     4 |
+----+-------------+-------+

_も同様の方法で行うことが出来ます。

###抽出結果を並び替える

抽出結果をlikes(いいね)の数で並び替えたりすることも可能です。

並び替えを行うにはORDER BYを使用します。
また、並び替えた後にDESCを使用し降順か昇順かを変えることも可能です。

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  id INT NOT NULL AUTO_INCREMENT,
  message VARCHAR(140), 
  likes INT,
  PRIMARY KEY (id)
);

INSERT INTO posts (message, likes) VALUES 
  ('Thanks', 12),
  ('Merci', 4),
  ('Arigato', 4),
  ('Gracias', 15),
  ('Danke', 8);

SELECT * FROM posts ORDER BY likes;
SELECT * FROM posts ORDER BY likes DESC;

実行結果
+----+---------+-------+
| id | message | likes |
+----+---------+-------+
|  2 | Merci   |     4 |
|  3 | Arigato |     4 |
|  5 | Danke   |     8 |
|  1 | Thanks  |    12 |
|  4 | Gracias |    15 |
+----+---------+-------+
+----+---------+-------+
| id | message | likes |
+----+---------+-------+
|  4 | Gracias |    15 |
|  1 | Thanks  |    12 |
|  5 | Danke   |     8 |
|  2 | Merci   |     4 |
|  3 | Arigato |     4 |
+----+---------+-------+

降順と昇順が切り替わっているのがわかります。

また、DESCを付けた場合、
同じlikesの値で4番目にMerci、5番目にArigatoがきています。

likesの値は同じなので、その場合はmessageでも降順と昇順を変えたい!
という場合は少なくないと思います。

その場合は下記のように行います。

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  id INT NOT NULL AUTO_INCREMENT,
  message VARCHAR(140), 
  likes INT,
  PRIMARY KEY (id)
);

INSERT INTO posts (message, likes) VALUES 
  ('Thanks', 12),
  ('Merci', 4),
  ('Arigato', 4),
  ('Gracias', 15),
  ('Danke', 8);
  
SELECT * FROM posts ORDER BY likes DESC, message;

実行結果
+----+---------+-------+
| id | message | likes |
+----+---------+-------+
|  4 | Gracias |    15 |
|  1 | Thanks  |    12 |
|  5 | Danke   |     8 |
|  3 | Arigato |     4 |
|  2 | Merci   |     4 |
+----+---------+-------+

これで綺麗に並び替えることが出来ました。

次に、likesの数が大きい順で上から3レコード(上位3位)分を取得したい場合です。
その場合はLIMITを使用します。

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  id INT NOT NULL AUTO_INCREMENT,
  message VARCHAR(140), 
  likes INT,
  PRIMARY KEY (id)
);

INSERT INTO posts (message, likes) VALUES 
  ('Thanks', 12),
  ('Merci', 4),
  ('Arigato', 4),
  ('Gracias', 15),
  ('Danke', 8);

SELECT * FROM posts ORDER BY likes DESC, likes LIMIT 3;

実行結果
+----+---------+-------+
| id | message | likes |
+----+---------+-------+
|  4 | Gracias |    15 |
|  1 | Thanks  |    12 |
|  5 | Danke   |     8 |
+----+---------+-------+

あまりないかもしれませんが、
上から3番目のレコードから3レコード分取得したい場合があったとします。

つまり、下記の場合ならDankeからMerciまでです。

+----+---------+-------+
| id | message | likes |
+----+---------+-------+
|  4 | Gracias |    15 |
|  1 | Thanks  |    12 |
|  5 | Danke   |     8 |
|  3 | Arigato |     4 |
|  2 | Merci   |     4 |
+----+---------+-------+

その場合はOFFSETを使用します。

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  id INT NOT NULL AUTO_INCREMENT,
  message VARCHAR(140), 
  likes INT,
  PRIMARY KEY (id)
);

INSERT INTO posts (message, likes) VALUES 
  ('Thanks', 12),
  ('Merci', 4),
  ('Arigato', 4),
  ('Gracias', 15),
  ('Danke', 8);
  
SELECT * FROM posts ORDER BY likes DESC, message LIMIT 3 OFFSET 2;

実行結果
+----+---------+-------+
| id | message | likes |
+----+---------+-------+
|  5 | Danke   |     8 |
|  3 | Arigato |     4 |
|  2 | Merci   |     4 |
+----+---------+-------+

上手く抽出が出来ていることがわかります。

ここで疑問に思う人がいると思うのですが、OFFSET 2だと、
2番目から抽出してしまうのではないか?というところです。

これは、配列などと同じで、
1番目を、2番目を、3番目をと数えます。

なので、OFFSET 2は上から3番目ということになります。

###レコードの更新を行う

Twitterでもユーザの名前が変わったり、
プロフィール内容が変わったりとよくデータを変更します。

なのでレコードの更新方法について説明します。

レコードの更新にはUPDATEを使用します。
UPDATEは下記のように記述します。

UPDATE <テーブル名> SET <カラム(複数指定可)> WHERE <条件(省略可)>;

なお、UPDATEは長くなることが多いので改行して書くことをおすすめします。

UPDATE
  <テーブル名> 
SET
  <カラム(複数指定可)> 
WHERE
  <条件(省略可)>;

では実際のテーブルを更新してみたいと思います。

今回は、likesの値を+5messageの文字列を大文字にするを行います。
しかし、WHEREでlikesの値が10以上のレコードのみです。

文字列を全て大文字にするのにはUPPER()関数を使用します。

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  id INT NOT NULL AUTO_INCREMENT,
  message VARCHAR(140), 
  likes INT,
  PRIMARY KEY (id)
);

INSERT INTO posts (message, likes) VALUES 
  ('Thanks', 12),
  ('Merci', 4),
  ('Arigato', 4),
  ('Gracias', 15),
  ('Danke', 8);
 
UPDATE 
  posts 
SET 
  likes = likes + 5,
  message = UPPER(message)
WHERE
  likes >= 10;
SELECT * FROM posts;

実行結果
+----+---------+-------+
| id | message | likes |
+----+---------+-------+
|  1 | THANKS  |    17 |
|  2 | Merci   |     4 |
|  3 | Arigato |     4 |
|  4 | GRACIAS |    20 |
|  5 | Danke   |     8 |
+----+---------+-------+

###レコードを削除する

ツイートを削除した際にそのツイートのデータを削除するように、
レコードの削除処理もよく行われます。

レコードの削除を行うにはDELETEを使用します。

全てのレコードを削除する場合は、DELETE FROM <テーブル名>;ですが
全て削除することはあまりないと思うので条件を付けたい時があると思います。

条件を付ける場合はUPDATEの時と同じで後ろにWHEREを付けます。

下記の場合は、likesが10以下のレコードを全て削除しています。

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  id INT NOT NULL AUTO_INCREMENT,
  message VARCHAR(140), 
  likes INT,
  PRIMARY KEY (id)
);

INSERT INTO posts (message, likes) VALUES 
  ('Thanks', 12),
  ('Merci', 4),
  ('Arigato', 4),
  ('Gracias', 15),
  ('Danke', 8); 

DELETE FROM posts WHERE likes < 10;
SELECT * FROM posts;

実行結果
+----+---------+-------+
| id | message | likes |
+----+---------+-------+
|  1 | Thanks  |    12 |
|  4 | Gracias |    15 |
+----+---------+-------+

実行結果を見ると、5つあったレコードの内3つが削除され、id1とid4が残りましたが、
この状態の時にデータを追加した時のidは2なのか6なのかどちらだと思いますか?

ということでレコードを追加してみたいと思います。

レコードの追加はINSERT INTOです。

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  id INT NOT NULL AUTO_INCREMENT,
  message VARCHAR(140), 
  likes INT,
  PRIMARY KEY (id)
);

INSERT INTO posts (message, likes) VALUES 
  ('Thanks', 12),
  ('Merci', 4),
  ('Arigato', 4),
  ('Gracias', 15),
  ('Danke', 8); 
  
DELETE FROM posts WHERE likes < 10;
INSERT INTO posts (message, likes) VALUES ('Xie Xie', 10);

SELECT * FROM posts;

実行結果
+----+---------+-------+
| id | message | likes |
+----+---------+-------+
|  1 | Thanks  |    12 |
|  4 | Gracias |    15 |
|  6 | Xie Xie |    10 |
+----+---------+-------+

答えは6で追加されました。

2・3・5がもったいない!と思います。
再度しっかりとidを振り直したい場合はテーブルを削除するしかありません。

テーブルの削除はDROPで行えますが、
削除した後に再作成するTRUNCATEを使うこともできます。

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  id INT NOT NULL AUTO_INCREMENT,
  message VARCHAR(140), 
  likes INT,
  PRIMARY KEY (id)
);

INSERT INTO posts (message, likes) VALUES 
  ('Thanks', 12),
  ('Merci', 4),
  ('Arigato', 4),
  ('Gracias', 15),
  ('Danke', 8); 
  
TRUNCATE TABLE posts;
INSERT INTO posts (message, likes) VALUES ('Xie Xie', 10);

SELECT * FROM posts;

実行結果
+----+---------+-------+
| id | message | likes |
+----+---------+-------+
|  1 | Xie Xie |    10 |
+----+---------+-------+

テーブルが再作成されて、idが1番からふり直されていることが確認出来ました!

###作成、更新日時を自動で設定する

レコードが作成された日時と、レコードが更新された日時を自動で設定します。

テーブルのカラムにcreated DATETIME DEFAULT NOW()
updated DATETIME DEFAULT NOW() ON UPDATE NOW()を記述します。

DEFAULTというのは、そのままの意味でデフォルトの値です。

INSERT INTOの際にVALUESで値を指定していますが、
DEFAULTがついているカラムはVALUESで値を指定しなかった場合にデフォルト値が入ります。

今回はそのデフォルト値をNOW()として現在時刻を入れるようにしています。

次に、ON UPDATE NOW()ですが、
レコードの更新を行う際のUPDATEを使用した時にNOW()を自動で入れてくれます。

つまり、updatedの値はUPDATEを行うたびに
自動で更新されていくという仕組みになります。

SELECT id, created, updated FROM posts;で、
現在のテーブルのid, 作成日, 更新日の値を取得しています。

SELECT SLEEP(3);は処理を3秒間止めるコマンドです。

3行後にUPDATE posts SET likes = 100 WHERE id = 1;を実行します。
idのレコードに対してlikesの値を100にしています。

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  id INT NOT NULL AUTO_INCREMENT,
  message VARCHAR(140), 
  likes INT,
  created DATETIME DEFAULT NOW(),
  updated DATETIME DEFAULT NOW() ON UPDATE NOW(),
  PRIMARY KEY (id)
);

INSERT INTO posts (message, likes) VALUES 
  ('Thanks', 12),
  ('Merci', 4),
  ('Arigato', 4),
  ('Gracias', 15),
  ('Danke', 8);
  
SELECT id, created, updated FROM posts;
SELECT SLEEP(3);
UPDATE posts SET likes = 100 WHERE id = 1;

SELECT id, created, updated FROM posts;

実行結果
+----+---------------------+---------------------+
|  1 | 2021-03-20 20:05:34 | 2021-03-20 20:05:34 |
|  2 | 2021-03-20 20:05:34 | 2021-03-20 20:05:34 |
|  3 | 2021-03-20 20:05:34 | 2021-03-20 20:05:34 |
|  4 | 2021-03-20 20:05:34 | 2021-03-20 20:05:34 |
|  5 | 2021-03-20 20:05:34 | 2021-03-20 20:05:34 |
+----+---------------------+---------------------+
+----------+
| SLEEP(3) |
+----------+
|        0 |
+----------+
+----+---------------------+---------------------+
| id | created             | updated             |
+----+---------------------+---------------------+
|  1 | 2021-03-20 20:05:34 | 2021-03-20 20:05:37 |
|  2 | 2021-03-20 20:05:34 | 2021-03-20 20:05:34 |
|  3 | 2021-03-20 20:05:34 | 2021-03-20 20:05:34 |
|  4 | 2021-03-20 20:05:34 | 2021-03-20 20:05:34 |
|  5 | 2021-03-20 20:05:34 | 2021-03-20 20:05:34 |
+----+---------------------+---------------------+

実行結果からわかる通り、
id1のみupdatedが更新されています。

###テーブルの設計を変更する

一度テーブルを作成した後に、
「カラムを追加したい!」、「カラムの名前を変えたい!」、「テーブルの名前を変えたい!」
なんて時があるかもしれません。

その時のコマンドを紹介します。

・カラムを追加する時

カラムを追加する時は下記のコマンドで行います。

ALTER TABLE <テーブル名> ADD <カラム名> <型>;

場所を指定することも出来ます。

ALTER TABLE <テーブル名> ADD <カラム名> <型> AFTER <カラム名>;

では、実際にやってみます。

authorというカラムをVARCHAR(255)型で追加します。

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  id INT NOT NULL AUTO_INCREMENT,
  message VARCHAR(140), 
  likes INT,
  PRIMARY KEY (id)
);

INSERT INTO posts (message, likes) VALUES 
  ('Thanks', 12),
  ('Merci', 4),
  ('Arigato', 4),
  ('Gracias', 15),
  ('Danke', 8);

ALTER TABLE posts ADD author VARCHAR(255);
DESC posts;

実行結果
+---------+--------------+------+-----+---------+----------------+
| Field   | Type         | Null | Key | Default | Extra          |
+---------+--------------+------+-----+---------+----------------+
| id      | int(11)      | NO   | PRI | NULL    | auto_increment |
| message | varchar(140) | YES  |     | NULL    |                |
| likes   | int(11)      | YES  |     | NULL    |                |
| author  | varchar(255) | YES  |     | NULL    |                |
+---------+--------------+------+-----+---------+----------------+

authorが追加されているのがわかります。

idの下に追加したい場合は下記のようにします。

ALTER TABLE posts ADD author VARCHAR(255) AFTER id;

・カラム名を変えたい時

カラム名を変えたい時は下記のコマンドを記述します。

ALTER TABLE <テーブル名> CHANGE <変更前カラム名> <変更後カラム名> <型>;

実際に記述すると下記のようになります。

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  id INT NOT NULL AUTO_INCREMENT,
  message VARCHAR(140), 
  likes INT,
  PRIMARY KEY (id)
);

INSERT INTO posts (message, likes) VALUES 
  ('Thanks', 12),
  ('Merci', 4),
  ('Arigato', 4),
  ('Gracias', 15),
  ('Danke', 8);

ALTER TABLE posts CHANGE likes points INT;
DESC posts;

実行結果
+---------+--------------+------+-----+---------+----------------+
| Field   | Type         | Null | Key | Default | Extra          |
+---------+--------------+------+-----+---------+----------------+
| id      | int(11)      | NO   | PRI | NULL    | auto_increment |
| message | varchar(140) | YES  |     | NULL    |                |
| points  | int(11)      | YES  |     | NULL    |                |
+---------+--------------+------+-----+---------+----------------+

likespointに変わっているのがわかります。

・テーブル名を変える時

テーブル名を変える時は下記のコマンドを記述します。

ALTER TABLE <変更前テーブル名> RENAME <変更後テーブル名>;

変更後のテーブルが存在しているとエラーになりますので要注意。

実際に記述すると下記のようになります。

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  id INT NOT NULL AUTO_INCREMENT,
  message VARCHAR(140), 
  likes INT,
  PRIMARY KEY (id)
);

INSERT INTO posts (message, likes) VALUES 
  ('Thanks', 12),
  ('Merci', 4),
  ('Arigato', 4),
  ('Gracias', 15),
  ('Danke', 8);

ALTER TABLE posts RENAME messages;
SHOW TABLES;

実行結果
+-----------------+
| Tables_in_myapp |
+-----------------+
| messages        |
+-----------------+

postsテーブルmessageテーブルに変更しているのがわかります。

#さいごに

このくらい覚えておけばそれなりに操作することができるのではないかなと思います。
ただ、まだまだできることはたくさんあるのでぜひ調べてみてください!

私も学習しながら役に立つ内容があったら共有しようと思います!

以上、最後までご覧いただきありがとうございました。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?