【MySQL】テーブルの追加、削除、変更、クエリ
CRUD : Create(作成)、Retrieve(読み取り)、Update(更新)、Delete(削除)
1. 挿入操作 ----挿入
ユーザーテーブルを作成し、4つのフィールドを設定します
mysql> create table user(
-> id int unsigned primary key auto_increment,
-> sn int unsigned unique key,
-> name varchar(20) not null,
-> tel varchar(11) unique key
-> );
1.1 簡単な挿入
--指定列插入--
mysql> insert into user (id,sn,name) values(1,200,'刘邦');
Query OK, 1 row affected (0.01 sec)
--全列插入--
mysql> insert into user values(2,201,'刘倍','1111111');
Query OK, 1 row affected (0.01 sec)
--全列多行插入--
mysql> insert into user values(3,202,'刘某','000010'),(4,203,'王某','220');
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
--指定列多行插入--
mysql> insert into user (sn,name,tel) values(300,'刘某','999'),(303,'王某','888');
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
注: insert into は、insert として省略できます。
1.2 ----ON DUPLICATE KEY UPDATE挿入時に更新するかどうか
主キーまたは一意キーに対応する値がすでに存在しており、同期更新操作を選択的に実行できるため、挿入は失敗します。
mysql> insert into user values(2,201,'刘倍','1110111');
ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'
mysql> insert into user values(11,201,'刘倍','1111111');
ERROR 1062 (23000): Duplicate entry '201' for key 'sn'
mysql>
INSERT ... ON DUPLICATE KEY UPDATE
column = value [, column = value] ...
insert into user values(2,201,'刘倍','1110111')on duplicate key update sn=20,name='刘备',tel='2222';
Query OK, 2 rows affected (0.01 sec)
-- 0 row affected: 表中有冲突数据,但冲突数据的值和 update 的值相等
-- 1 row affected: 表中没有冲突数据,数据被插入
-- 2 row affected: 表中有冲突数据,并且数据已经被更新
注: 更新されたデータは他のデータと競合することはできません
1.3 挿入時の置換 ----REPLACE
-- 主键 或者 唯一键 没有冲突,则直接插入;
-- 主键 或者 唯一键 如果冲突,则删除后再插入
mysql> replace into user(sn,name,tel)values(666,'xiaohaizi','1111111');
Query OK, 2 rows affected (0.00 sec)
-- 1 row affected: 表中没有冲突数据,数据被插入
-- 2 row affected: 表中有冲突数据,删除后重新插入
2. クエリ - 選択
データテーブルを作成してデータを追加する
mysql> CREATE TABLE exam_result (
-> id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
-> name VARCHAR(20) NOT NULL COMMENT '同学姓名',
-> chinese float DEFAULT 0.0 COMMENT '语文成绩',
-> math float DEFAULT 0.0 COMMENT '数学成绩',
-> english float DEFAULT 0.0 COMMENT '英语成绩'
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> INSERT INTO exam_result (name, chinese, math, english) VALUES
-> ('唐三藏', 67, 98, 56),
-> ('孙悟空', 87, 78, 77),
-> ('猪悟能', 88, 98, 90),
-> ('曹孟德', 82, 84, 67),
-> ('刘玄德', 55, 85, 45),
-> ('孙权', 70, 73, 78),
-> ('宋公明', 75, 65, 30);
Query OK, 7 rows affected (0.00 sec)
Records: 7 Duplicates: 0 Warnings: 0
2.1 単純なクエリと重複排除
--全列查询
mysql> select * from exam_result;
--指定列查询
mysql> select name from exam_result;
クエリフィールドは式です
-- 表达式不包含字段会在结果后面拼接上
SELECT id, name, 10 FROM exam_result;
クエリ結果のエイリアス化
SELECT column [AS] alias_name [...] FROM table_name;
如:
select chinese+math+english as total from exam_result;
結果の重複排除
select distinct math from exam_result;
2.2 基本的なクエリ----where 条件
比較演算子:
オペレーター | 説明する |
---|---|
>、>=、<、<= | より大きい、以上、より小さい、以下 |
= | 等しい。NULL は安全ではない。たとえば、NULL = NULL は NULL となる。 |
<=> | 等しい、NULL セーフ、例: NULL <=> NULL は TRUE(1) と評価されます。 |
!=、<> | 等しくない |
a0とa1の間 | 範囲一致、[a0, a1]、a0 <= 値 <= a1 の場合、TRUE (1) を返します。 |
IN(オプション、…) | いずれかのオプションの場合、TRUE (1) を返します。 |
無効である | 無効である |
NULL ではありません | NULLではない |
好き | ファジーマッチ。% は任意の数字 (0 を含む) の任意の文字を表し、_ は任意の 1 文字を表します |
条件演算子: 同じかどうか
オペレーター | 説明する |
---|---|
と | 結果が TRUE (1) になるには、複数の条件がすべて TRUE (1) である必要があります。 |
また | いずれかの条件が TRUE(1) であれば、結果も TRUE(1) になります。 |
いいえ | 条件は TRUE (1)、結果は FALSE (0) |
2.2.3 ケースデモンストレーション
- 英語で不合格となった生徒とその英語スコア (< 60)
select name,english from exam_result where english<60;
- 中国語の得点が[80、90]の生徒とその中国語の得点
mysql> select name,chinese from exam_result where chinese>=80 and chinese<=90;
+-----------+---------+
| name | chinese |
+-----------+---------+
| 孙悟空 | 87 |
| 猪悟能 | 88 |
| 曹孟德 | 82 |
+-----------+---------+
或者
mysql> select name,chinese from exam_result where chinese between 80 and 90;
- 数学の点数が 58 または 59 または 98 または 99 の生徒とその数学の点数
select name,math from exam_result where math=58 or math=59 or math=98 or math=99;
+-----------+------+
| name | math |
+-----------+------+
| 唐三藏 | 98 |
| 猪悟能 | 98 |
+-----------+------+
或者:
select name,math from exam_result where math in(58,59,98,99);
- サンという名前のクラスメートとサンという名前のクラスメート
mysql> select name from exam_result where name like '孙%';
+-----------+
| name |
+-----------+
| 孙悟空 |
| 孙权 |
+-----------+
2 rows in set (0.00 sec)
mysql> select name from exam_result where name like '孙_';
+--------+
| name |
+--------+
| 孙权 |
+--------+
- 英語の成績よりも中国語の成績が高い生徒
select name,chinese,english from exam_result where chinese>english;
+-----------+---------+---------+
| name | chinese | english |
+-----------+---------+---------+
| 唐三藏 | 67 | 56 |
| 孙悟空 | 87 | 77 |
| 曹孟德 | 82 | 67 |
| 刘玄德 | 55 | 45 |
| 宋公明 | 75 | 30 |
+-----------+---------+---------+
- 合計スコアが200点以下の生徒
select name,chinese+math+english as total from exam_result where chinese+math+english<200;
+-----------+-------+
| name | total |
+-----------+-------+
| 刘玄德 | 185 |
| 宋公明 | 170 |
+-----------+-------+
注: 実行順序の関係で、次のように記述するとエラーが報告されます。
select name,chinese+english+math total from exam_result where total<200;
ERROR 1054 (42S22): Unknown column 'total' in 'where clause'
- 中国語のスコアが 80 点以上で、姓が孫ではない学生
select name,chinese from exam_result where chinese>80 and name not like '孙%';
+-----------+---------+
| name | chinese |
+-----------+---------+
| 猪悟能 | 88 |
| 曹孟德 | 82 |
+-----------+---------+
- 学生の太陽、そうでない場合は、合計スコアが 200 を超え、中国語のスコアが数学のスコア未満、英語のスコアが 80 を超える必要があります。
select name,chinese,math,english,chinese+math+english total from exam_result where name like '孙_' or
+-----------+---------+------+---------+-------+
| name | chinese | math | english | total |
+-----------+---------+------+---------+-------+
| 猪悟能 | 88 | 98 | 90 | 276 |
| 孙权 | 70 | 73 | 78 | 221 |
+-----------+---------+------+---------+-------+
- NULLクエリ
mysql> select * from exam_result where name is null;
Empty set (0.00 sec)
2.4 並べ替え ---- 並べ替え
-- ASC 为升序(从小到大)默认为升序
-- DESC 为降序(从大到小)
-- 默认为 ASC
SELECT ... FROM table_name [WHERE ...]
ORDER BY column [ASC|DESC], [...];
クラスメートの名前と数学の成績。数学の成績が低い順に表示されます。
select name,math from exam_result order by math asc;
+-----------+------+
| name | math |
+-----------+------+
| 宋公明 | 65 |
| 孙权 | 73 |
| 孙悟空 | 78 |
| 曹孟德 | 84 |
| 刘玄德 | 85 |
| 唐三藏 | 98 |
| 猪悟能 | 98 |
+-----------+------+
生徒の名前と各科目の成績を照会し、数学の降順、英語の昇順、中国語の昇順で表示します。
mysql> select name,math,english,chinese from exam_result order by math desc,english desc,chinese asc;
+-----------+------+---------+---------+
| name | math | english | chinese |
+-----------+------+---------+---------+
| 猪悟能 | 98 | 90 | 88 |
| 唐三藏 | 98 | 56 | 67 |
| 刘玄德 | 85 | 45 | 55 |
| 曹孟德 | 84 | 67 | 82 |
| 孙悟空 | 78 | 77 | 87 |
| 孙权 | 73 | 78 | 70 |
| 宋公明 | 65 | 30 | 75 |
+-----------+------+---------+---------+
注: ここでのソート状態は、数学の降順 > 英語の昇順 > 中国語の昇順です。
姓が Sun または姓が Cao の学生の数学のスコアをクエリすると、結果は数学のスコアの降順に表示されます。
mysql> select name,math from exam_result where name like '孙%' or name like '曹%' order by math desc;
+-----------+------+
| name | math |
+-----------+------+
| 曹孟德 | 84 |
| 孙悟空 | 78 |
| 孙权 | 73 |
+-----------+------+
クラスメートと合計スコアをクエリする実行順序
、低い順から高い順にソートするのは
データを取得した後に実行されるため、こことは異なります、エイリアスを使用できます
select name,math+chinese+english as total from exam_result order by total;
+-----------+-------+
| name | total |
+-----------+-------+
| 宋公明 | 170 |
| 刘玄德 | 185 |
| 唐三藏 | 221 |
| 孙权 | 221 |
| 曹孟德 | 233 |
| 孙悟空 | 242 |
| 猪悟能 | 276 |
+-----------+-------+
フィルタのページング結果を制限する
– データ表示の開始添字は 0
– s から開始 (添字は 0 から開始)、n 件の結果をフィルタリング SELECT
... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT s, n – –
0から開始
、n 件の結果をフィルタリング
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT n;
–
– s から開始、n 件の結果をフィルタリング、2 番目の使用法と比較 より明確にするには、SELECT ... を使用することをお勧めします。 FROM table_name [WHERE ...] [ORDER BY ...] LIMIT
n OFFSET s;
位置 s から開始し、n 位置ずつオフセットします
mysql> select * from exam_result limit 3;
+----+-----------+---------+------+---------+
| id | name | chinese | math | english |
+----+-----------+---------+------+---------+
| 1 | 唐三藏 | 67 | 98 | 56 |
| 2 | 孙悟空 | 87 | 78 | 77 |
| 3 | 猪悟能 | 88 | 98 | 90 |
+----+-----------+---------+------+---------+
3 rows in set (0.00 sec)
mysql> select * from exam_result limit 1,3;
+----+-----------+---------+------+---------+
| id | name | chinese | math | english |
+----+-----------+---------+------+---------+
| 2 | 孙悟空 | 87 | 78 | 77 |
| 3 | 猪悟能 | 88 | 98 | 90 |
| 4 | 曹孟德 | 82 | 84 | 67 |
+----+-----------+---------+------+---------+
3 rows in set (0.00 sec)
mysql> select * from exam_result limit 3 offset 0;
+----+-----------+---------+------+---------+
| id | name | chinese | math | english |
+----+-----------+---------+------+---------+
| 1 | 唐三藏 | 67 | 98 | 56 |
| 2 | 孙悟空 | 87 | 78 | 77 |
| 3 | 猪悟能 | 88 | 98 | 90 |
+----+-----------+---------+------+---------+
3 rows in set (0.00 sec)
3. 変更操作 ----更新
UPDATE table_name SET column = expr [, column = expr ...]
[WHERE ...] [ORDER BY ...] [LIMIT ...]
孫悟空の数学の点数を80点に変更する
mysql> update exam_result set math=80 where name='孙悟空';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select name,math from exam_result;
+-----------+------+
| name | math |
+-----------+------+
| 唐三藏 | 98 |
| 孙悟空 | 80 |
| 猪悟能 | 98 |
| 曹孟德 | 84 |
| 刘玄德 | 85 |
| 孙权 | 73 |
| 宋公明 | 65 |
+-----------+------+
曹孟徳の数学の得点を60点に、中国語の得点を70点に変更
update exam_result set math=60,chinese=70 where name='曹孟德';
mysql> select name,math,chinese from exam_result;
+-----------+------+---------+
| name | math | chinese |
+-----------+------+---------+
| 唐三藏 | 98 | 67 |
| 孙悟空 | 80 | 87 |
| 猪悟能 | 98 | 88 |
| 曹孟德 | 60 | 70 |
| 刘玄德 | 85 | 55 |
| 孙权 | 73 | 70 |
| 宋公明 | 65 | 75 |
+-----------+------+---------+
合計スコアが低い上位 3 人の生徒の数学スコアに 30 ポイントを追加します。
注: ここで更新する場合、制限 0、3 は使用できません。
mysql> select name,math+chinese+english total from exam_result order by total limit 0,3;
+-----------+-------+
| name | total |
+-----------+-------+
| 宋公明 | 170 |
| 刘玄德 | 185 |
| 曹孟德 | 197 |
+-----------+-------+
--update exam_result set math=math+30 order by math+chinese+english asc limit 0,3;
--ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '3' at line 1
mysql> update exam_result set math=math+30 order by math+chinese+english asc limit 3;
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3 Changed: 3 Warnings: 0
mysql> select name,math+chinese+english total from exam_result order by total limit 0,3;
+-----------+-------+
| name | total |
+-----------+-------+
| 宋公明 | 200 |
| 刘玄德 | 215 |
| 唐三藏 | 221 |
+-----------+-------+
3 rows in set (0.00 sec)
mysql> select name,math+chinese+english total from exam_result order by total;
+-----------+-------+
| name | total |
+-----------+-------+
| 宋公明 | 200 |
| 刘玄德 | 215 |
| 唐三藏 | 221 |
| 孙权 | 221 |
| 曹孟德 | 227 |
| 孙悟空 | 244 |
| 猪悟能 | 276 |
+-----------+-------+
7 rows in set (0.00 sec)
すべての生徒の中国語のスコアを元の 2 倍に更新します
mysql> update exam_result set chinese=chinese*2;
Query OK, 7 rows affected (0.00 sec)
Rows matched: 7 Changed: 7 Warnings: 0
mysql> select * from exam_result;
+----+-----------+---------+------+---------+
| id | name | chinese | math | english |
+----+-----------+---------+------+---------+
| 1 | 唐三藏 | 134 | 98 | 56 |
| 2 | 孙悟空 | 174 | 80 | 77 |
| 3 | 猪悟能 | 176 | 98 | 90 |
| 4 | 曹孟德 | 140 | 90 | 67 |
| 5 | 刘玄德 | 110 | 115 | 45 |
| 6 | 孙权 | 140 | 73 | 78 |
| 7 | 宋公明 | 150 | 95 | 30 |
+----+-----------+---------+------+---------+
四、削除 - 削除
DELETE FROM table_name [WHERE ...] [ORDER BY ...] [LIMIT ...]
孫悟空のテストスコアを削除する
mysql> delete from exam_result where name='孙悟空';
Query OK, 1 row affected (0.01 sec)
mysql> select * from exam_result;
+----+-----------+---------+------+---------+
| id | name | chinese | math | english |
+----+-----------+---------+------+---------+
| 1 | 唐三藏 | 134 | 98 | 56 |
| 3 | 猪悟能 | 176 | 98 | 90 |
| 4 | 曹孟德 | 140 | 90 | 67 |
| 5 | 刘玄德 | 110 | 115 | 45 |
| 6 | 孙权 | 140 | 73 | 78 |
| 7 | 宋公明 | 150 | 95 | 30 |
+----+-----------+---------+------+---------+
テーブル全体を削除する
mysql> CREATE TABLE for_delete (
-> id INT PRIMARY KEY AUTO_INCREMENT,
-> name VARCHAR(20)
-> );
mysql> INSERT INTO for_delete (name) VALUES ('A'), ('B'), ('C');
mysql> select * from for_delete;
+----+------+
| id | name |
+----+------+
| 1 | A |
| 2 | B |
| 3 | C |
+----+------+
mysql> delete from for_delete;
mysql> select * from for_delete;
mysql> INSERT INTO for_delete (name) VALUES ('D');
mysql> select * from for_delete;
+----+------+
| id | name |
+----+------+
| 4 | D |
+----+------+
注意: テーブル全体を削除すると、DML 言語に属するデータのみが削除されます。テーブル内のデータを削除した後、AUTO_INCREMENT の値はリセットされず、前のデータに沿って増加し続けます。
4.1 切り捨てられたテーブル ----TRUNCATE
- テーブル全体に対してのみ操作でき、DELETE のような部分的なデータに対しては操作できません。
- 実際、MySQL はデータを操作しないため、DELETE よりも高速ですが、TRUNCATE はデータを削除するときに実際の操作を行わないため、ロールバックできません
- AUTO_INCREMENT 項目をリセットします
TRUNCATE [TABLE] table_name
テストは上記の削除と同じです
mysql> CREATE TABLE for_truncate (
-> id INT PRIMARY KEY AUTO_INCREMENT,
-> name VARCHAR(20)
-> );
mysql> INSERT INTO for_truncate (name) VALUES ('A'), ('B'), ('C');
mysql> select * from for_truncate;
+----+------+
| id | name |
+----+------+
| 1 | A |
| 2 | B |
| 3 | C |
+----+------+
mysql> TRUNCATE for_truncate;
mysql> show create table for_truncate\G
*************************** 1. row ***************************
Table: for_truncate
Create Table: CREATE TABLE `for_truncate` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
mysql> INSERT INTO for_truncate (name) VALUES ('D');
mysql> select * from for_truncate;
+----+------+
| id | name |
+----+------+
| 1 | D |
+----+------+
mysql> show create table for_truncate\G
*************************** 1. row ***************************
Table: for_truncate
Create Table: CREATE TABLE `for_truncate` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
4.2 削除と切り捨ての違い
削除操作の違いは次のとおりです。
- DELETE ステートメントは、テーブル内のデータ レコードを行ごとに削除するために使用されます。実行時に条件を指定し、条件を満たす行のみを削除できるトランザクション操作です。DELETE 操作はロールバックできるため、テーブル データに対する削除操作を元に戻すことができます。
TRUNCATE ステートメントは、テーブル内のすべてのデータを迅速に削除するために使用されます。これは、テーブル内のすべての行を削除し、削除された行を返さない DDL (データ定義言語) 操作です。TRUNCATE 操作はロールバックできないため、一度実行するとデータを回復できません。
効率とパフォーマンス:
- 一般に、TRUNCATE 操作は、特に大きなテーブルを扱う場合、DELETE 操作よりも高速です。TRUNCATE はすべての削除操作をログに記録するのではなく、DDL 操作を記録するため、実行が速くなります。
DELETE 操作はデータベース ログに対応するログ レコードを生成し、関連するトリガーや制約チェックをトリガーする可能性があるため、TRUNCATE 操作よりも比較的遅くなります。
スペースとインデックス:
DELETE 操作では、テーブル内のデータ行が削除されるだけで、これらの行に関連付けられた記憶領域は解放されません。これは、テーブル内に削除された行が多数ある場合、記憶域スペースの断片化が発生する可能性があることを意味します。
TRUNCATE 操作は、テーブル内のデータ行を削除するだけでなく、テーブルに関連付けられた記憶領域も解放します。これにより、データ ファイルのサイズが削減され、記憶領域が空になります。
DELETE 操作ではテーブルの自動インクリメント ID 値はリセットされません。TRUNCATE 操作ではテーブルの自動インクリメント ID 値が初期値にリセットされます。
要約すると、DELETE と TRUNCATE は両方ともデータの削除に使用できますが、DELETE の方がより柔軟で制御可能であり、必要に応じて削除条件を指定でき、操作をロールバックできます。TRUNCATE はテーブル全体のデータを迅速に削除するのに適しており、実行速度が速く効率的ですが、操作をロールバックすることはできません。どのアクションを使用するかは、特定のニーズと状況によって異なります。