記事ディレクトリ
基本的なデータベース操作コマンド
命名規則
- フィールド名は文字で始める必要があります
- 長さは 30 文字を超えることはできません (データベースやバージョンが異なると異なります)。
- SQLの予約語は使用できません
- 使用できる文字は、a ~ z、AZ、0 ~ 9、$ などです。
- MySQL はすべて小文字を使用します
- アンダースコアで区切られた複数の単語
図書館運営
注文 | 説明する |
---|---|
データベースを表示します。 | すべてのデータベースにクエリを実行する |
create database 库名; | データベースの作成 |
ライブラリ名を使用します。 | ライブラリを使用する |
データベースライブラリ名を削除します。 | データベースの削除 |
テーブル操作
注文 | 説明する |
---|---|
テーブルを表示します。 | すべてのテーブルをクエリする |
create table テーブル名(フィールド名 1 フィールドタイプ 1 (長さ), フィールド名 2 フィールドタイプ 2 (長さ),...); | テーブルの作成 |
テーブルテーブル名をドロップします。 | テーブルの削除 |
alter table テーブル名 add 列フィールド名 フィールドタイプ (長さ) | テーブルの変更 |
記述テーブル名。 | テーブル構造を表示する |
- テーブルを作成するとき、複数のフィールドを「,」カンマで区切る必要がありますが、最後のフィールドを「,」カンマで区切る必要はありません。
操作をテーブルに記録する
注文 | 説明する |
---|---|
select フィールド名 1、フィールド名 2、フィールド名 3... from テーブル名; / select * from テーブル名; | フィールド名に基づいてテーブル内のすべてのデータをクエリまたはクエリします |
テーブル名に挿入 値 (フィールド 1 の値、フィールド 2 の値、...) / テーブル名 (フィールド名) に挿入 値 (フィールド値)、(フィールド値) | テーブルにデータを追加/指定したフィールドにデータを追加 |
テーブル名を更新 フィールド名 = 新しい値を設定 (フィールド名 = フィールド値) | テーブル内のデータを変更すると、フィールド全体が変更され、後で条件付きクエリが実行されます。 |
テーブル名から削除; | テーブル内のデータを削除する |
gbk という名前を設定します。 | 中国語の文字化けを解決する |
テーブル名に挿入 (フィールド名 1、フィールド名 2、...) 値 (フィールド 1 の値、フィールド 2 の値、...)、(フィールド 1 の値、フィールド 2 の値、...) |
主キーと自動インクリメント
- 主キー AUTO_INCREMENT
テーブル構造のインポート
1. データベースの選択
2. SQL、ソース xxx.sql のインポート
DQL (データクエリ)
テーブルやフィールドを作成するときにコメントを追加する
create table test(id int comment 'id号',name varchar(255) comment '名字')comment='测试表';
クエリ作成テーブル情報
show create table test;
11. 単純なクエリ
。SQL ステートメントはすべて「;」で終わります。SQL
ステートメントは大文字と小文字が区別されませんが、テーブルに格納されるデータは Oracle では異なるサイズに分割されます。MySQL は区別しません。Oracle はより厳密で、MySQL は区別されません。より緩やかです。
フィールドは、as エイリアスを使用して数学的演算に参加でき
、as キーワードは省略できます。エイリアスに中国語がある場合は、
SQL ステートメント内の文字列を一重引用符で囲みます。文字列は一重引用符で囲む必要があります。
複数のフィールドをクエリするには、「 ,」を使用
します。クエリ内のすべてのフィールドを区切るには、「*」を使用します。実際の開発では、効率が低下するため、「 * 」の使用はお勧めしません。
12. 条件付きクエリ
select
フィールド、フィールド...
from
テーブル名
where
条件;
実行順序: from、where、select
between…and…: 閉じた間隔 [1100 - 3000]
between…and…: 使用する場合、左側は小さく、右側は大きくする必要があります
between…and…: 数値と文字列で使用できます。文字的には左側が閉じていますが、右開き[A~C)
NULL はデータベース内の値ではなく、何も意味せず、空です。
空虚は値ではなく、等号で測ることはできません。
null であるか null ではないを使用する必要があります
and は or よりも優先度が高い場合、「()」括弧を使用して優先度の問題を解決できます。
in の後の値は間隔ではなく、特定の値です
ファジー クエリで、「_」を含むコンテンツをクエリする場合は、転送文字「\」、「\_」を使用するだけです。
13.フィールド asc/desc によるソート(昇順、降順)
デフォルトは、昇順
asc 昇順
desc 降順
です。複数のフィールドを同時に区切るには、「,」を使用します。
前のフィールドが主導的な役割を果たすことができます。前のフィールドが並べ替えを完了できない場合にのみ、後のフィールドが有効になります。 。(前のフィールドが等しい場合、次のフィールドが実行されます。)
フィールド番号で並べ替えたり、フィールド番号 (フィールド番号はクエリで使用されるフィールドです) に従って並べ替えたりすることもできますが、お勧めしません。 Java プログラムで使用するため、日常の練習に使用できます。
select
field
from
surface
where
条件
order by
...
実行順序: from、where、select、order by
注: order by は最後に実行されます。
14. グループ化関数
count count
sum sum
avg 平均値
max 最大値
min 最小値
注: すべてのグループ化関数は特定のデータ セットに対して動作し、
グループ化関数は合計 5 つあります。
グループ化関数は別名、複数行処理機能です。
複数行処理機能の特徴: 複数行入力、最終的な出力結果は 1 行です。
グループ化関数は NULL を自動的に無視します
。すべてのグループ化関数は自動的に NULL を無視します。 where 条件に追加する必要はありません 上記のフィルタ条件は null ではありません
select sum(comm) from emp; sum 関数は自動的に NULL を無視します
SQL 文には構文規則があります グループ化関数は直接使用できませんwhere句の中で?
理由: where が実行された後に group by が実行されるためです。
実行順序: where、group by、group 関数 (group by を使用しないと group 関数は使用できません)。したがって、where 句で group 関数を使用することはできません。
count( * ) と count(特定のフィールド) の違いは何ですか?
count(*): あるフィールドのデータ数を数えるのではなく、あるフィールドとは関係のないレコードの総数を数える count(あるフィールド): データの総数を数えるという
意味特定のフィールドが NULL ではない。
グループ化関数は、「 , 」で区切って組み合わせることもできます。
グループ化関数は NULL を無視しますが、数式は NULL を無視しません。NULL を含む数式の結果はすべて NULL でなければなりません。
15. 単一行処理関数は、
1 行を入力し、1 行を出力します
注: データベースでは、数式内に NULL が出現する限り、結果は NULL となり、数式内で NULL は無視されません。
解決策: ifnull() null 処理関数。単一行処理関数
ifnull に属します (NULL データを何として扱うべきか)
16. group by と have
group by: 特定のフィールドごとにグループ化します。
have: は、再度グループ化した後にデータをフィルタリングすることです。
注: group by と Have はパートナーです。Having を使用したい場合は、group by を使用する必要があります。
実行順序: from、group by、select (グループ化関数)
注: グループ化関数は通常、group by と組み合わせて使用されます。どのグループ化関数も、group by ステートメントが実行されるまで実行されません。
SQL ステートメントに group by がない場合、テーブル全体のデータが独自のグループを形成します。実際、その中にはデフォルトの group by が存在します。
ステートメント内に group by がある場合、select の後に記述できるフィールドとパラメーターのグループ化関数のみがここに記述されます。その他は許可されません。MySQL では実行できますが、意味がありません。Oracle で実行すると、エラーが報告されます。
複数フィールド グループ クエリは、
複数のフィールドを 1 つのフィールドとして扱うだけです。deptno,job によってempグループからdeptno, job,max(sal)
を選択します。
where フィルタリングはフィルタリングを行うよりも高いため、
可能であれば where を使用することをお勧めします。
17. 完全な DQL ステートメントを要約する
5 つのクエリ フィールドを選択
...
1 つのクエリ テーブルから
...
2 つの条件フィルタ
...
3 つのグループごとにグループ
...
4 つの条件フィルタを持つ
...
6 つの並べ替え
...
1. 重複レコードを
個別に削除します。
select distinct job from emp;
select distinct deptno,job from emp;
distinct はすべてのフィールドの先頭にのみ指定でき、重複を排除するために複数のフィールドが結合されます。
ジョブの数を数えますか?
select count(distinct job) from emp;
2. 接続クエリの
概要:
実際の開発では、ほとんどのデータは単一のテーブルでクエリされるのではなく、通常は複数のテーブルの結合クエリになります。
テーブル内のフィールドが多すぎるため、大量のデータが繰り返され、データの冗長性が生じます。
3. 分類:
内部結合: 2 つのテーブル AB は等しい関係にあり、主テーブルと副テーブルの区別はありません
等価結合
. 非等価結合
自己結合
. 外部結合 : 2 つのテーブル AB は主テーブルに分割されますテーブルとセカンダリ テーブル。メイン テーブルがチェックされます。左結合は右結合として記述でき、右結合は左結合として記述できます。左外部結合
(左結合)
、右外部結合 (右結合)、
および完全結合: ほぼ使われたことがない。2 つのテーブル内のすべてのデータを検索するには、左結合と右結合の両方があります。
4. デカルト積現象(デカルト積現象):
テーブルエイリアスについて:
実行効率が高く
可読性が高い
14×4=56エントリ
select e.ename,d.dname from emp e,dept d;
デカルト積現象を回避します。一致の数は 56 のままですが (一致の数は減りません)、有効なレコードのみが表示されます。
各従業員の部署名を調べて、従業員名と部署名を表示するように要求します。
select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno; # SQL92,以后不用
5.
内部結合と等価結合の最大の特徴は、条件が同値関係であることです。
各従業員の部署名を調べて、従業員名と部署名を表示するように要求します。
SQL92: (使用されません)
select
e.ename,d.dname
from
emp e,dept d
where
e.deptno=d.deptno; # SQL92,以后不用
SQL99: (一般的に使用されます)
select
e.ename,d.dname
from
emp e
join
dept d
on
e.deptno=d.deptno;
inner: 内部の接続を示します。inner は省略できます。inner の目的は読みやすさを向上させることです。
select
e.ename,d.dname
from
emp e
inner join
dept d
on
e.deptno=d.deptno;
...接続条件の結合
B where ...構造がより明確になり、テーブルの接続条件が後続の where 条件から分離されます。
6.
内部結合における非等価結合の最大の特徴は、結合条件の関係が非等価であることです。
各従業員の給与等級を確認するには、従業員名、給与、給与等級を表示する必要があります。
select
e.ename,e.sal,s.grade
from
emp e
join
salgrade s
on
e.sal between s.losal and s.hisal;
7.
自己結合の最大の特徴は、1 つのテーブルを 2 つのテーブルとみなし、それらを結合することです。
テーブルの自己結合は等しい場合もあれば、等しくない場合もあります。
empno: 従業員番号
ename: 従業員名とリーダー名
mgr: リーダー番号
select empno,ename,mgr from emp;
emp a 员工表
±-----±----------±-----+
| エンプノ | エネーム | マネージャー |
±-----±----------±-----+
| 7369 | スミス | 7902 |
| 7499 | アレン | 7698 |
| 7521 | 区 | 7698 |
| 7566 | ジョーンズ | 7839 |
| 7654 | マーティン | 7698 |
| 7698 | ブレイク | 7839 |
| 7782 | クラーク | 7839 |
| 7788 | スコット | 7566 |
| 7839 | キング | NULL |
| 7844 | ターナー | 7698 |
| 7876 | アダムス | 7788 |
| 7900 | ジェームス | 7698 |
| 7902 | フォード | 7566 |
| 7934 | ミラー | 7782 |
±-----±----------±-----+
select empno,ename from emp;
emp b リーダーシップテーブル
±------±----------±
| empno | ename |
±------±----------+
| 7566 | JONES |
| 7698 | BLAKE |
| 7782 | クラーク |
| 7788 | スコット |
| 7839 | キング |
| 7902 | フォード |
±------±------+
各従業員の上位リーダーを検索し、従業員名と対応するリーダー名を表示するように要求します。
select
a.ename as '员工名',b.ename as '领导名'
from
emp a
inner join
emp b
on
a.mgr = b.empno;
8. 外部結合 (よく使われる)
内部結合と外部結合の違いは何ですか?
内部結合:
テーブル A と B が接続されているとします。内部結合を使用すると、テーブル A とテーブルの間で一致するすべてのレコードをクエリできます。これは内部結合です。
プライマリ テーブル AB とセカンダリ テーブル AB の間に区別はなく、2 つのテーブルは同等です。
外部結合:
テーブル A と B が接続されているとします。外部結合を使用する場合、2 つのテーブル AB のうちの 1 つがメイン テーブルになり、もう 1 つがセカンダリ テーブルになります。メイン テーブルのデータは主にクエリされ、セカンダリ テーブルのデータはクエリされます。テーブルはセカンダリ テーブルとしてクエリされます。のデータはメイン テーブルのデータと一致しないため、セカンダリ テーブルはそれに一致するように NULL を自動的にシミュレートします。
外部結合分類:
左外部結合 (左結合): 左側のテーブルがメインテーブルであることを示します。
右外部結合 (右結合): 右側のテーブルがメインテーブルであることを示します。
左結合は右結合の形式で記述され、右結合も対応する左結合形式で記述されます。
各従業員の上司が誰であるかを調べますか? (すべての従業員を照会する必要があります)
左外部結合 (テーブル a が主テーブル、テーブル b が副テーブル)
外部結合 外部結合は省略できます。内部結合と外部結合を区別する方法は、左と右が外部結合です。
select
a.ename as '员工名',b.ename as '领导名'
from
emp a
left outer join
emp b
on
a.mgr = b.empno;
右外部結合 (テーブル a がメインテーブル、テーブル b がセカンダリテーブル)
select
a.ename as '员工名',b.ename as '领导名'
from
emp b
right outer join
emp a
on
a.mgr = b.empno;
外部接続はよく使用されますが、
外部接続の最も重要な機能は、メイン テーブル内のすべてのデータを無条件でクエリできることです。
どの部門に従業員がいないかを調べます。
select
d.*
from
emp e
right join
dept d
on
e.deptno=d.deptno
where
e.empno is null;
9. 3 つのテーブル間のクエリを結合して、
各従業員の部門名と給与等級を調べます。
従業員テーブル
mysql> select empno,ename,sal,deptno from emp;
+-------+--------+---------+--------+
| empno | ename | sal | deptno |
+-------+--------+---------+--------+
| 7369 | SMITH | 800.00 | 20 |
| 7499 | ALLEN | 1600.00 | 30 |
| 7521 | WARD | 1250.00 | 30 |
| 7566 | JONES | 2975.00 | 20 |
| 7654 | MARTIN | 1250.00 | 30 |
| 7698 | BLAKE | 2850.00 | 30 |
| 7782 | CLARK | 2450.00 | 10 |
| 7788 | SCOTT | 3000.00 | 20 |
| 7839 | KING | 5000.00 | 10 |
| 7844 | TURNER | 1500.00 | 30 |
| 7876 | ADAMS | 1100.00 | 20 |
| 7900 | JAMES | 950.00 | 30 |
| 7902 | FORD | 3000.00 | 20 |
| 7934 | MILLER | 1300.00 | 10 |
+-------+--------+---------+--------+
14 rows in set (0.00 sec)
部門テーブル
mysql> select * from dept;
+--------+------------+----------+
| DEPTNO | DNAME | LOC |
+--------+------------+----------+
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
+--------+------------+----------+
4 rows in set (0.00 sec)
サラグラードの給与等級
mysql> select * from salgrade;
+-------+-------+-------+
| GRADE | LOSAL | HISAL |
+-------+-------+-------+
| 1 | 700 | 1200 |
| 2 | 1201 | 1400 |
| 3 | 1401 | 2000 |
| 4 | 2001 | 3000 |
| 5 | 3001 | 9999 |
+-------+-------+-------+
5 rows in set (0.00 sec)
A
が結合
BがCに
結合
これは、テーブル A とテーブル B が最初に接続され、接続後 (接続後の結果)、テーブル A がテーブル C に接続され続けることを意味します。
select
e.ename,d.dname,s.grade
from
emp e
join
dept d
on
e.deptno=d.deptno
join
salgrade s
on
e.sal between s.losal and s.hisal;
+--------+------------+-------+
| ename | dname | grade |
+--------+------------+-------+
| SMITH | RESEARCH | 1 |
| ALLEN | SALES | 3 |
| WARD | SALES | 2 |
| JONES | RESEARCH | 4 |
| MARTIN | SALES | 2 |
| BLAKE | SALES | 4 |
| CLARK | ACCOUNTING | 4 |
| SCOTT | RESEARCH | 4 |
| KING | ACCOUNTING | 5 |
| TURNER | SALES | 3 |
| ADAMS | RESEARCH | 1 |
| JAMES | SALES | 1 |
| FORD | RESEARCH | 4 |
| MILLER | ACCOUNTING | 2 |
+--------+------------+-------+
14 rows in set (0.00 sec)
各従業員の部門名、給与等級、および上司を調べます。
#e はメインテーブル、e1 はセカンダリテーブルです
select
e.ename '员工',d.dname,s.grade,e1.ename '领导'
from
emp e
join
dept d
on
e.deptno=d.deptno
join
salgrade s
on
e.sal between s.losal and s.hisal
left join
emp e1
on
e.mgr=e1.empno;
+--------+------------+-------+-------+
| 员工 | dname | grade | 领导 |
+--------+------------+-------+-------+
| SMITH | RESEARCH | 1 | FORD |
| ALLEN | SALES | 3 | BLAKE |
| WARD | SALES | 2 | BLAKE |
| JONES | RESEARCH | 4 | KING |
| MARTIN | SALES | 2 | BLAKE |
| BLAKE | SALES | 4 | KING |
| CLARK | ACCOUNTING | 4 | KING |
| SCOTT | RESEARCH | 4 | JONES |
| KING | ACCOUNTING | 5 | NULL |
| TURNER | SALES | 3 | BLAKE |
| ADAMS | RESEARCH | 1 | SCOTT |
| JAMES | SALES | 1 | BLAKE |
| FORD | RESEARCH | 4 | JONES |
| MILLER | ACCOUNTING | 2 | CLARK |
+--------+------------+-------+-------+
14 rows in set (0.00 sec)
3. サブクエリ
1. サブクエリとは何ですか? サブクエリはどこに表示されますか?
select ステートメントは select ステートメント内にネストされており、ネストされた select ステートメントはサブクエリです。
表示される場所:
select
…(選択)
from
…(選択)
wehre
…(選択)
2. where句でサブクエリを使用する
平均給与を超える従業員に関する情報を検索します。
ステップ 1: 平均給与を求めます。
select avg(sal) from emp;
+-------------+
| avg(sal) |
+-------------+
| 2073.214286 |
+-------------+
1 row in set (0.00 sec)
ステップ 2: フィルタリングする場所
select * from emp where sal>2073.214286;
+-------+-------+-----------+------+------------+---------+------+--------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
+-------+-------+-----------+------+------------+---------+------+--------+
| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 |
| 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 |
| 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 |
| 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
| 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |
+-------+-------+-----------+------+------------+---------+------+--------+
6 rows in set (0.00 sec)
ステップ 3: マージ
select * from emp where sal>(select avg(sal) from emp);
+-------+-------+-----------+------+------------+---------+------+--------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
+-------+-------+-----------+------+------------+---------+------+--------+
| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 |
| 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 |
| 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 |
| 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
| 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |
+-------+-------+-----------+------+------------+---------+------+--------+
6 rows in set (0.00 sec)
3. 後ろにネストされたサブクエリ
各部門の平均給与の給与グレードを見つけます。
ステップ1:部門ごとの平均給与を求める(部門番号ごとにグループ化し、平均給与を求める)
select deptno,avg(sal) as avgsal from emp group by deptno;
+--------+-------------+
| deptno | avgsal |
+--------+-------------+
| 20 | 2175.000000 |
| 30 | 1566.666667 |
| 10 | 2916.666667 |
+--------+-------------+
3 rows in set (0.00 sec)
ステップ 2: 上記のクエリ結果を一時テーブル t として扱い、その t テーブルを salgrade s テーブルに接続します。条件は、s.losal と s.hisal の間の t.avgsal です。
select
t.*,s.grade
from
(select deptno,avg(sal) as avgsal from emp group by deptno) t
join
salgrade s
on
t.avgsal between s.losal and s.hisal;
+--------+-------------+-------+
| deptno | avgsal | grade |
+--------+-------------+-------+
| 20 | 2175.000000 | 4 |
| 30 | 1566.666667 | 3 |
| 10 | 2916.666667 | 4 |
+--------+-------------+-------+
3 rows in set (0.00 sec)
各部門の平均給与グレードを見つけます。
ステップ 1: 各従業員の給与等級を確認します。
従業員テーブル
mysql> select ename,sal from emp;
+--------+---------+
| ename | sal |
+--------+---------+
| SMITH | 800.00 |
| ALLEN | 1600.00 |
| WARD | 1250.00 |
| JONES | 2975.00 |
| MARTIN | 1250.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| SCOTT | 3000.00 |
| KING | 5000.00 |
| TURNER | 1500.00 |
| ADAMS | 1100.00 |
| JAMES | 950.00 |
| FORD | 3000.00 |
| MILLER | 1300.00 |
+--------+---------+
14 rows in set (0.00 sec)
サルグレードSグレード表
mysql> select * from salgrade;
+-------+-------+-------+
| GRADE | LOSAL | HISAL |
+-------+-------+-------+
| 1 | 700 | 1200 |
| 2 | 1201 | 1400 |
| 3 | 1401 | 2000 |
| 4 | 2001 | 3000 |
| 5 | 3001 | 9999 |
+-------+-------+-------+
5 rows in set (0.00 sec)
mysql> select e.ename,e.sal,e.deptno,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal;
+--------+---------+--------+-------+
| ename | sal | deptno | grade |
+--------+---------+--------+-------+
| SMITH | 800.00 | 20 | 1 |
| ALLEN | 1600.00 | 30 | 3 |
| WARD | 1250.00 | 30 | 2 |
| JONES | 2975.00 | 20 | 4 |
| MARTIN | 1250.00 | 30 | 2 |
| BLAKE | 2850.00 | 30 | 4 |
| CLARK | 2450.00 | 10 | 4 |
| SCOTT | 3000.00 | 20 | 4 |
| KING | 5000.00 | 10 | 5 |
| TURNER | 1500.00 | 30 | 3 |
| ADAMS | 1100.00 | 20 | 1 |
| JAMES | 950.00 | 30 | 1 |
| FORD | 3000.00 | 20 | 4 |
| MILLER | 1300.00 | 10 | 2 |
+--------+---------+--------+-------+
14 rows in set (0.00 sec)
ステップ 2: 上記の結果に基づいて、部門別のグループ化を続け、平均成績を見つけます。
select
e.deptno,avg(s.grade)
from
emp e
join
salgrade s
on
e.sal between s.losal and s.hisal
group by
e.deptno;
+--------+--------------+
| deptno | avg(s.grade) |
+--------+--------------+
| 20 | 2.8000 |
| 30 | 2.5000 |
| 10 | 3.6667 |
+--------+--------------+
3 rows in set (0.00 sec)
4. 選択後のネストされたサブクエリ
各従業員の部署名を調べて、従業員名と部署名を表示するように要求します。
以下の結果は同じです
select
e.ename,d.dname
from
emp e
join
dept d
on
e.deptno=d.deptno;
select
e.ename,(select d.dname from dept d where e.deptno = d.deptno) as dname
from
emp e;
+--------+------------+
| ename | dname |
+--------+------------+
| SMITH | RESEARCH |
| ALLEN | SALES |
| WARD | SALES |
| JONES | RESEARCH |
| MARTIN | SALES |
| BLAKE | SALES |
| CLARK | ACCOUNTING |
| SCOTT | RESEARCH |
| KING | ACCOUNTING |
| TURNER | SALES |
| ADAMS | RESEARCH |
| JAMES | SALES |
| FORD | RESEARCH |
| MILLER | ACCOUNTING |
+--------+------------+
14 rows in set (0.00 sec)
4.給与職位が営業マンとマネージャーである従業員を検索するためのユニオン (クエリ結果セットを追加できます) 。
最初のタイプ: または
select ename,job from emp where job='MANAGER' or job='SALESMAN';
2 番目のタイプ: で
select ename,job from emp where job in('MANAGER','SALESMAN');
+--------+----------+
| ename | job |
+--------+----------+
| ALLEN | SALESMAN |
| WARD | SALESMAN |
| JONES | MANAGER |
| MARTIN | SALESMAN |
| BLAKE | MANAGER |
| CLARK | MANAGER |
| TURNER | SALESMAN |
+--------+----------+
7 rows in set (0.00 sec)
3 番目のタイプ: 結合
select ename,job from emp where job = 'MANAGER' union select ename,job from emp where job = 'SALESMAN';
+--------+----------+
| ename | job |
+--------+----------+
| JONES | MANAGER |
| BLAKE | MANAGER |
| CLARK | MANAGER |
| ALLEN | SALESMAN |
| WARD | SALESMAN |
| MARTIN | SALESMAN |
| TURNER | SALESMAN |
+--------+----------+
7 rows in set (0.01 sec)
Union: 2 つの関連のないテーブルのデータが結合されて表示されます。
Union: 使用する場合、選択後のフィールドの数が同じである必要があります。
5. ページングクエリ制限の
制限は mysql に固有であり、他のデータベースでは利用できないため、通過しません。(Oracle には rownum と呼ばれる同様のメカニズムがあります)
limit は結果セット内のデータの一部を受け取り、これがその役割です。
構文メカニズム:
limit startIndex、length
startIndex は 0 から始まる開始位置を示し、0 はデータの最初の部分を示し、
length は取得する数を示します。数値を直接記述する場合、デフォルト値は 0 です。
給与の上位 5 人の従業員を取り出します (アイデア: 上位 5 人を降順に取り出します)
select ename,sal from emp order by sal desc;
# 取前5个 limit 0,5
select ename,sal from emp order by sal desc limit 0,5;
+-------+---------+
| ename | sal |
+-------+---------+
| KING | 5000.00 |
| FORD | 3000.00 |
| SCOTT | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
+-------+---------+
5 rows in set (0.00 sec)
# 取前5个,limit 5,直接写一个数字的话,前面默认就是0
select ename,sal from emp order by sal desc limit 5;
+-------+---------+
| ename | sal |
+-------+---------+
| KING | 5000.00 |
| FORD | 3000.00 |
| SCOTT | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
+-------+---------+
5 rows in set (0.00 sec)
limitist は SQL ステートメント実行の最後のステップです
select 5
...
from 1
...
where 2
...
group by 3
...
having 4
...
order by 6
...
limit 7
...
給与ランクが 4 位から 9 位の従業員を見つけますか?
select ename,sal from emp order by sal desc limit 3,6;
+--------+---------+
| ename | sal |
+--------+---------+
| JONES | 2975.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| ALLEN | 1600.00 |
| TURNER | 1500.00 |
| MILLER | 1300.00 |
+--------+---------+
6 rows in set (0.00 sec)
6. 共通の標準ページング SQL?
各ページには 3 つのレコードが表示されます。
ページ 1: 0、3 (0、1、2
) ページ 2: 3、3 (3、4、5)
ページ 3: 6、3 (6、7、8
) ページ 4: 9、 3 (9、10、11)
ページ 5: 12、3 (12、13、14)
ページごとの pageSize レコードの表示:
pageNo: (pageNo - 1) * pageSize, pageSize
pageNo: 表示されるページ
pageSize: 各ページに表示されるレコードの数
java代码{
int pageNo = 2; // 页码2
int pageSize = 10; // 每页显示10条
limit (pageNo - 1) * pageSize, pageSize
limit (2 - 1) * 10, pageSize
limit 10,10
}
6. テーブル
構文形式を作成します。
create table 表名(
字段名1 数据类型,
字段名2 数据类型,
字段名3 数据类型,
......
);
MySQL のフィールドのデータ型については、
int 整数型 (Java では int)、
bigint long 整数型 (Java では long)、
float 浮動小数点型 (Java では float double)、
char 固定長文字列 (String)、
varcharが一般的です。可変長文字列 (StringBuffer StringBuilder) 255
date 日付型 (Java の java.sql.Date 型)
blob バイナリ ラージ オブジェクト (画像やビデオなどのメディア情報のストレージ) (Java のオブジェクト)
clob 文字ラージ オブジェクト (ストレージ ラージ テキスト) 、たとえば、4G 文字列を保存できます) (Java のオブジェクト)
char と varchar のどちらを選択するか?
実際の開発では、性別や誕生日など、あるフィールドのデータ長が変わらない場合は固定長になります。
導入や名前など、フィールドのデータ長が不確かな場合には、varchar が使用されます。
blob 型と clob 型を使用しますか?
IO ストリーミングを使用する必要があります。
メディア タイプは通常、メディア タイプをデータベースに直接配置しません。代わりに、メディア タイプのデータは、通常 char または varchar タイプを使用するパスを通じてデータベースに配置されます。
ムービーテーブル: t_movie
id(int) name(varchar) playtime(date/char) haibao(blob) 履歴(clob)
1 スパイダーマン
2
3
通常、データベース内のテーブル名は t_ または tbl_ で始まることが推奨されます。
学生テーブルの作成:
学生情報には次のものが含まれます:
学生 ID、名前、性別、クラス番号、誕生日
学生 ID: bigint
名前: varchar
性別: char
クラス ID: varchar
誕生日: char
create table t_student(
no bigint,
name varchar(255),
sex char(1),
classno varchar(255),
birth char(10)
);
7. insert ステートメントはデータを挿入します
構文形式:
要件: フィールドの数と値の数が同じであり、データ型が同じである必要があります。
insert into 表名(字段名1,字段名2,字段名3,...) values(值1,值2,值3,...);
insert into t_student(no,name,sex,classno,birth) values(1,'zhangsan','1','gaosan1ban','1950-10-12');
フィールドの順序は変更できますが、前後が対応している必要があります。
insert into t_student(name,sex,classno,birth,no) values('lisi','1','gaosan1ban','1950-10-12',2);
フィールドを書き込むと、残りのすべてのフィールドに NULL が自動的に挿入されます。
insert into t_student(name) values('wangwu');
drop table if names t_student; #このテーブルが存在する場合、
デフォルト値を削除します
create table t_student(
no bigint,
name varchar(255),
sex char(1) default 1,
classno varchar(255),
birth char(10)
);
insert into t_student(name) values('zhangsan');
select * from t_student;
+------+----------+------+---------+-------+
| no | name | sex | classno | birth |
+------+----------+------+---------+-------+
| NULL | zhangsan | 1 | NULL | NULL |
+------+----------+------+---------+-------+
注: Insert ステートメントが正常に実行されると、必然的にテーブルにレコードが 1 行増えます。
このレコード行の一部のフィールドが NULL であっても、後でそれを実行する方法はありません。
insert ステートメントはデータを挿入し、update を使用してのみ更新できます。
フィールドは省略できますが、次の値には数量と順序に関する要件があります。
insert into t_student values(1,'jack','0','gaosan2ban','1986-10-23');
複数のレコードを挿入する
insert into t_student
(no,name,sex,classno,birth)
values
(3,'rose','1','gaosi2ban','1952-12-14'),
(4,'laotie','1','gaosi2ban','1952-12-19');
8. テーブルコピーの
構文:
create table 表面 as select语句;
クエリ結果をテーブルとして作成します。
create table emp1 as select * from emp;
create table emp2 as select empno,ename from emp;
9. クエリ結果をテーブルに挿入します。
フィールドの挿入には要件があり、フィールドの数が一致している必要があります。
insert into dept1 select * from dept;
10. データの変更:
構文形式の更新:
update 表名 set 字段名1=值1,字段名2=值2... where 条件;
注: テーブル全体のすべてのデータが更新されるという条件はありません。
部門 10 の LOC を SHANGHAI に変更し、部門名を RENSHIBU に変更します
update dept1 set loc='SHANGHAI',dname='RENSHIBU' where deptno=10;
すべてのレコードを更新する
update dept1 set loc='x', dname='y';
11. データの
構文形式を削除します。
delete from 表名 where 条件;
注: 無条件ですべて削除します。
10部門のデータを削除しますか?
delete from dept1 where deptno=10;
すべての記録を削除しますか?
delete from dept1;
大きなテーブルを削除するにはどうすればよいですか? (強調)
truncate table emp1; # 表被截断,不可回滚,永久丢失。
12. テーブル構造の変更
ツールを直接使用するだけです 通常の状況では、一度テーブルを設計したら、テーブル構造を変更する必要はほとんどありません。
テーブル構造を変更するステートメントは Java コードには現れず、挿入、削除、更新、選択のみが行われます。これはテーブル内のすべてのデータ操作です。
追加、削除、変更、クエリという用語があります。 CRUD 操作
作成 (追加)
取得 (取得)
更新 (変更)
削除 (削除)
13. 制約 制約
とは何ですか? 一般的な制約は何ですか?
テーブルを作成するときに、テーブルのフィールドに対応する制約を追加できます。制約を追加する目的は、テーブル内のデータの正当性、有効性、整合性を確保することです。
一般的な制約は何ですか?
非 null 制約 (not null): 制約されるフィールドを NULL にすることはできません
一意の制約: 制約されるフィールドを繰り返すことができない主キー制約 (主キー): 制約されるフィールドを NULL にすることも、繰り返すこともできません ( PK
と呼ばれます)。
キー制約 (外部キー):... (FK と呼ばれます)
チェック制約 (チェック): Oracle データベースにはチェック制約がありますが、MySQL にはチェック制約がないことに注意してください。現在、mySQL はこの制約をサポートしていません。
14. 非 null 制約 not null
drop table if exists t_user;
create table t_user(
id int,
username varchar(255) not null,
password varchar(255)
);
insert into t_user(id,username,password) values(1,'lisi','123');
1. 一意制約(ユニーク)
一意制約によって変更されるフィールドは一意であり、重複することはできません。ただし、NULL にすることもできます。
列レベルの制約
表レベルの制約
ケース: 特定の列に一意を追加する
drop table if exists t_user;
create table t_user(
id int,
username varchar(255) unique # 列级约束,可以使用表级约束来添加一个字段,效果一样
);
insert into t_user values(1,'zhangsan');
insert into t_user values(2,'zhangsan'); # ERROR 1062 (23000): Duplicate entry 'zhangsan' for key 'username'(字段重复报错 )
insert into t_user(id) values(2);
insert into t_user(id) values(3);
insert into t_user(id) values(4);
ケース: 2 つ以上の列に一意を追加する
drop table if exists t_user;
create table t_user(
id int,
usercode varchar(255),
username varchar(255),
unique(usercode,username) # 多个字段联合起来添加约束,不能重复,就添加了一个约束(表级约束)
);
insert into t_user values(1,'111','zs');
insert into t_user values(2,'111','ls');
insert into t_user values(3,'222','zs');
insert into t_user values(3,'111','zs'); # ERROR 1062 (23000): Duplicate entry '111-zs' for key 'usercode'
select * from t_user;
drop table if exists t_user;
create table t_user(
id int,
usercode varchar(255) unique,
username varchar(255) unique
);
insert into t_user values(1,'111','zs');
insert into t_user values(2,'111','ls'); # ERROR 1062 (23000): Duplicate entry '111' for key 'usercode'
select * from t_user;
注: not null 制約には列レベルの制約のみがあり、テーブル レベルの制約はありません。
2. 主キー制約
主キー制約をテーブルに追加するにはどうすればよいですか?
drop table if exists t_user;
create table t_user(
id int primary key, // 列级约束
username varchar(255),
email varchar(255)
);
insert into t_user(id,username,email) values(1,'zs','[email protected]');
insert into t_user(id,username,email) values(2,'ls','[email protected]');
insert into t_user(id,username,email) values(3,'ww','[email protected]');
select * from t_user;
insert into t_user(id,username,email) values(1,'jack','[email protected]'); # ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
insert into t_user(username,email) values('jack','[email protected]'); # ERROR 1364 (HY000): Field 'id' doesn't have a default value
概要: id は主キーです。主キー制約が追加されているため、主キー フィールドのデータを NULL にしたり、繰り返したりすることはできません。
主キーの特性: NULL または繰り返し (一意) にすることはできません。
主キーに関する用語:
主キー制約: 主キー
主キーフィールド: ID フィールドに主キーを追加した後の ID を主キーフィールドと呼びます
主キー値: ID フィールドの各値が主キーの値
主キーの役割:
テーブル設計の 3 つのパラダイムには要件があり、最初のパラダイムでは、すべてのテーブルに主キーが必要です。
主キーの役割: 主キー値は、このテーブルに記録されるこの行の一意の識別子です。(人間のID番号のようなもの)
主キーの分類:
主キーフィールドのフィールド数に応じて分類:
単一の主キー (推奨、一般的に使用される)
複合主キー (複数のフィールドを組み合わせて主キー制約を追加) (複合主キーは複合であるため推奨されません)主キーの性質に応じて、主キーは 3 つのパラダイムに違反します)
分割するには:
自然主キー: 主キーの値は、ビジネスに関係のない自然数であることが望ましいです。(推奨、よく使用されます)
ビジネス主キー: 主キーの値はシステムの業務に関連付けられます。たとえば、銀行カード番号を主キーとして使用し、ID カード番号を主キーとして使用します。(推奨されません)
ビジネスにリンクされたフィールドを主キーとして使用しないことをお勧めします。将来的にビジネスが変化すると、主キー値も変更する必要が生じる可能性がありますが、変更によって主キー値が繰り返される可能性があるため、変更する方法がない場合があります。
テーブルには主キー制約を 1 つだけ持つことができます。(覚えておかなければなりません)
テーブルレベルの制約を使用して主キーを定義します。
drop table if exists t_user;
create table t_user(
id int,
username varchar(255),
primary key(id)
);
insert into t_user(id,username) values(1,'zs');
insert into t_user(id,username) values(2,'ls');
insert into t_user(id,username) values(3,'ww');
insert into t_user(id,username) values(4,'cs');
select * from t_user;
insert into t_user(id,username) values(4,'cs'); # ERROR 1062 (23000): Duplicate entry '4' for key 'PRIMARY'
mysql は主キー値の自動インクリメントを提供します: (auto_increment) (強調)
drop table if exists t_user;
create table t_user(
id int primary key auto_increment, # id字段自动维护一个自增的数据,从1开始,以1递增。
username varchar(255)
);
insert into t_user(username) values('a');
insert into t_user(username) values('b');
insert into t_user(username) values('c');
insert into t_user(username) values('e');
insert into t_user(username) values('e');
insert into t_user(username) values('f');
select * from t_user;
ヒント: Oracle は、シーケンス オブジェクトと呼ばれる自動インクリメント メカニズムも提供します。
3. 外部キー制約
関連用語:
外部キー制約: 外部キー、外部キー制約の値は偶然に書き込むことはできません。特定のテーブルのフィールドの値から取得する必要があり、参照されるフィールドは一意である必要があります。
外部キーフィールド: 外部キー制約のあるフィールドを追加します。
外部キー値: 外部キーフィールドの各値
ビジネスの背景:
学生とクラスの情報を管理するデータベース テーブルを設計してください。
最初のオプション: 1 つのテーブルにすべてのデータ番号
(pk) 名が格納されます クラス名 クラス名
1 zs1 101 クラス 1、グレード 3、宜荘市第 2 中学校、大興区経済技術開発区、
北京 2 zs2 101 クラス 1、グレード 3、宜荘市北京市大興区経済技術開発区第 2 中学校
3 zs3 102 2 級、2 級、上級 3、宜庄市 北京市大興区経済技術開発区第 2 中学校 4 zs4
102 2 級、北京、大興区経済技術開発区、宜荘第 2 中学校、上級 3 級 3 級 5 zs5 102 北京、大興区経済技術開発区、宜庄第 2 中学校、上級 3 級 短所:
冗長
性(推奨されません)
第二种方案:两张表(班级表和学生表)
t_class 班级表
cno(pk) cname
101 北京大兴区经济技术开发区亦庄二中高三1班
102 北京大兴区经济技术开发区亦庄二中高三2班
t_student 学生表
sno(pk) sname classno(该字段添加外键约束fk)
1 zs1 101
2 zs2 101
3 zs3 102
4 zs4 102
5 zs5 102
上記テーブルのテーブル作成文を書きます:
t_student の classno フィールドは、t_class テーブルの cno フィールドを参照します このとき、t_student テーブルを子テーブルと呼びます。t_class テーブルは親テーブルと呼ばれます。
順序要件: (最初に親テーブルを追加し、最初に子テーブルを削除します)
データを削除する場合は、最初に子テーブルを削除し、次に親テーブルを削除します。
データを追加するときは、最初に親テーブルを追加し、次に子テーブルを追加します。
テーブルを作成する場合は、最初に親テーブルを作成し、次に子テーブルを作成します。
テーブルを削除する場合は、最初に子テーブルを削除し、次に親テーブルを削除します。
drop table if exists t_student;
drop table if exists t_class;
create table t_class(
cno int,
cname varchar(255),
primary key(cno)
);
create table t_student(
sno int,
sname varchar(255),
classno int,
foreign key(classno) references t_class(cno)
);
insert into t_class values(101,'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
insert into t_class values(102,'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy');
insert into t_student values(1,'zs1',101);
insert into t_student values(2,'zs2',101);
insert into t_student values(3,'zs3',102);
insert into t_student values(4,'zs4',102);
insert into t_student values(5,'zs5',102);
insert into t_student values(6,'zs6',102);
select * from t_class;
select * from t_student;
insert into t_student values(7,'lisi',103); # ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`staff`.`t_student`, CONSTRAINT `t_student_ibfk_1` FOREIGN KEY (`classno`) REFERENCES `t_class` (`cno`))
外部キーには NULL を指定できます。
参照されるフィールドは必ずしも主キーである必要はありませんが、少なくとも一意性制約があり、一般的には主キーを指します。
ストレージエンジン(理解)
1. 完全なテーブル作成ステートメントは次のように記述されます。
CREATE TABLE `t_x` (
`id` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
注: MySQL では、すべての識別子を記号で囲むことができます。普遍的ではないので、使用しないのが最善です。
テーブルを作成するときに、ストレージ エンジンと文字セットを指定できます。
mysql で使用されるデフォルトのストレージ エンジンは InnoDB です。
デフォルトの文字セットは UTF-8 です。
2. ストレージ エンジンは何ですか?
名前ストレージ エンジンは mysql にのみ存在します。(Oracleにも対応する仕組みがありますが、ストレージエンジンとは呼びません。Oracleには特別な名前はありません。テーブルの格納方法です。) ストレージエンジンはテーブルの格納方法です
。
MySQL は多くのストレージ エンジンをサポートしており、各ストレージ エンジンは異なるストレージ方式に対応しています。
各ストレージ エンジンには独自の長所と短所があるため、適切なストレージ エンジンを適切なタイミングで選択する必要があります。
3. MySQL で現在サポートされているストレージ エンジンを確認しますか?
show engines \G
mysql8 でサポートされているストレージ エンジンは 9 つあります
4. 一般的なストレージ エンジン
MyISAMストレージエンジン
Engine: MyISAM
Support: YES
Comment: MyISAM storage engine
Transactions: NO
XA: NO
Savepoints: NO
MyISAM などのストレージ エンジンはトランザクションをサポートしていません。
MyISAM は mysql で最も一般的に使用されるストレージ エンジンですが、このエンジンはデフォルトではありません。
MyISAM は 3 つのファイルを使用してテーブルを編成します:
xxx.frm (フォーマットを保存するファイル)
xxx.MYD (テーブルのデータを保存するファイル)
xxx.MYI (テーブルのインデックスを保存するファイル)
利点: 圧縮可能、保管スペースを節約します。また、読み取り専用テーブルに変換して、検索効率を向上させることもできます。
欠点: トランザクションはサポートされていません。
InnoDB ストレージ エンジン (デフォルトのストレージ エンジン、一般的に使用されます)
Engine: InnoDB
Support: DEFAULT
Comment: Supports transactions, row-level locking, and foreign keys
Transactions: YES
XA: YES
Savepoints: YES
利点: トランザクション、行レベルのロック、外部キーなどをサポートします。このストレージ エンジン内のデータのセキュリティは保証されています。
テーブルの構造は xxx.frm ファイルに保存され、
データは表領域などの表スペース (論理概念) に保存され、圧縮や自己読み取り型への変換はできません。
この InnoDB ストレージ エンジンは、MySQL データベースのクラッシュ後の自動回復メカニズムを提供します。
InnoDB はカスケード削除とカスケード更新をサポートしています。
メモリストレージエンジン
Engine: MEMORY
Support: YES
Comment: Hash based, stored in memory, useful for temporary tables
Transactions: NO
XA: NO
Savepoints: NO
欠点: トランザクションはサポートされていません。停電後はデータが失われます。すべてのデータとインデックスはメモリに保存されるためです。
利点: クエリ速度が最速です。
見る(理解する)
ビュー: データをさまざまな角度から観察します。(同じテーブル内のデータを別の角度から見ることができます)
ビューの作成と削除:
create view myview as select empno,ename from emp;
drop view myview
注意: ビュー・オブジェクトとして作成できるのはDQL文のみです。
ビューの追加、削除、変更、クエリを実行すると、元のテーブル データに影響します。(元のテーブルのデータは、直接操作される元のテーブルではなく、ビューを通じて影響を受けます。)
CRUD 操作はビューに対して実行できます。
ビュー指向の操作:
select * from myview;
+-------+--------+
| empno | ename |
+-------+--------+
| 7369 | SMITH |
| 7499 | ALLEN |
| 7521 | WARD |
| 7566 | JONES |
| 7654 | MARTIN |
| 7698 | BLAKE |
| 7782 | CLARK |
| 7788 | SCOTT |
| 7839 | KING |
| 7844 | TURNER |
| 7876 | ADAMS |
| 7900 | JAMES |
| 7902 | FORD |
| 7934 | MILLER |
+-------+--------+
create table emp_bak as select * from emp;
create view myview1 as select empno,ename,sal from emp_bak;
update myview1 set ename='hehe',sal=1 where empno=7369; # 通过视图修改原表数据
delete from myview1 where empno=7369; # 通过视图删除原表数据
ビューの役割: ビューはテーブルの実装の詳細を隠すことができます。機密性レベルが高いシステムでは、データベースは関連するビューのみを外部に提供し、Java プログラマはビュー オブジェクトに対して CRUD を実行するだけです。
データベースデータのインポートとエクスポート(DBAコマンド)
データベース全体をエクスポートします: dos コマンド ウィンドウで実行します。
mysqldump 数据库>D:\数据库.sql -uroot -p密码
指定したライブラリの下にある指定したテーブルをエクスポートします。 dos コマンド ウィンドウで実行します。
mysqldump 数据库 表名>D:\数据库.sql -uroot -p密码
データのインポート:
create database 数据库;
use 数据库;
source D:\数据库.sql
取引
1. トランザクションとは何ですか?
トランザクションは完全なビジネス ロジック単位であり、それ以上分割することはできません。
たとえば、銀行口座振替では、口座 A から口座 B に 10,000 を転送するには、2 つの更新ステートメントを実行する必要があります。
update t_act set balance=balance-1000 where actno='act-001';
update t_act set balance=balance+1000 where actno='act-002';
上記の 2 つの DML ステートメントは、同時に成功するか失敗する必要があります。一方が成功し、一方が失敗することは許可されません。
上記の 2 つの DML ステートメントが同時に成功するか失敗するかを確認するには、データベースの「トランザクション メカニズム」を使用する必要があります。
2. トランザクションに関連する唯一のステートメントは次のとおりです。 DML ステートメント。(insert delete update)
これら 3 つのステートメントはデータベース テーブルの「データ」に関連しているためです。
トランザクションは、データの整合性とセキュリティを確保するために存在します。
3. すべてのビジネスが 1 つの DML ステートメントを使用して完了できると仮定すると、トランザクション メカニズムは依然として必要ですか?
取引は必要ありません。
しかし、実際の状況はそうではなく、通常、1 つのこと (トランザクション [ビジネス]) では、複数の DML ステートメントを共同で完了する必要があります。
4. 取引の特徴は何ですか?
トランザクションには、次の 4 つの主要な特性があります。 ACID
A: アトミック性: トランザクションは作業の最小単位であり、それ以上分割することはできません。
C: 一貫性: トランザクションは、複数の DML ステートメントが同時に成功または失敗することを保証する必要があります。
I: 分離: トランザクション A とトランザクション B の間には分離があります。
D: 永続性: トランザクションが正常に終了する前に、最終データをハードディスク ファイルに永続化する必要があります。
5. トランザクション間の分離について
トランザクションの分離には分離レベルがあり、理論的には 4 つの分離レベルがあります:
レベル 1: read uncommitted (コミットされていない読み取り)
相手のトランザクションはまだ送信されていません。相手方の未コミットの送信済みデータ。
読み取りがコミットされていない場合、ダーティ読み取り現象が発生します。これは、ダーティ データが読み取られたことを意味します。
レベル 2: Read Committed (リードコミット)
相手のトランザクションが送信された後のデータを当社が読み取ることができます。
この分離レベルにより問題が解決され、ダーティ リード現象がなくなりました。
送信されたデータを読み取る際の問題は、繰り返し読み取ることができないことです。
レベル 3: 反復可能な読み取り (反復可能な読み取り)
この分離レベルは、反復不可能な読み取りの問題を解決します。
この分離レベルの問題は、読み取られるデータがファントムであることです。
4 番目のレベル: シリアル化された読み取り/シリアル化可能な読み取り (シリアル化可能) では、
すべての問題が解決されます。
効率が低い。トランザクションキューイングが必要です。
Oracle データベースのデフォルトの分離レベルは、読み取りコミットです。
MySQL データベースのデフォルトの分離レベルは反復読み取りです。
6. デモトランザクション
MySQL トランザクションはデフォルトで自動的にコミットされます。
(自動送信とは何ですか? DML ステートメントは実行される限り、一度だけ送信されます。) 自動送信をオフにするにはどうすればよいですか? starttransaction;
ポイントを保存したい場合は、保存ポイントまでロールバックします。
テーブルを作成します。
drop table if exists t_user;
create table t_user(
id int primary key auto_increment,
username varchar(255)
);
デモ: mysql のトランザクションは自動的に送信されます。DML が実行される限り、トランザクションは 1 回送信されます。
mysql> insert into t_user(username) values('zs');
Query OK, 1 row affected (0.01 sec)
mysql> select * from t_user;
+----+----------+
| id | username |
+----+----------+
| 1 | zs |
+----+----------+
1 row in set (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from t_user;
+----+----------+
| id | username |
+----+----------+
| 1 | zs |
+----+----------+
1 row in set (0.00 sec)
デモ: トランザクションの自動コミットをオフにするには、トランザクションの開始を使用します。
ロールバック
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t_user(username) values('lisi');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t_user(username) values('wangwu');
Query OK, 1 row affected (0.00 sec)
mysql> select * from t_user;
+----+----------+
| id | username |
+----+----------+
| 1 | zs |
| 2 | lisi |
| 3 | wangwu |
+----+----------+
3 rows in set (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from t_user;
+----+----------+
| id | username |
+----+----------+
| 1 | zs |
+----+----------+
1 row in set (0.00 sec)
提出する
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t_user(username) values('wangwu');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t_user(username) values('reos');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t_user(username) values('jack');
Query OK, 1 row affected (0.00 sec)
mysql> select * from t_user;
+----+----------+
| id | username |
+----+----------+
| 1 | zs |
| 4 | wangwu |
| 5 | reos |
| 6 | jack |
+----+----------+
4 rows in set (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from t_user;
+----+----------+
| id | username |
+----+----------+
| 1 | zs |
| 4 | wangwu |
| 5 | reos |
| 6 | jack |
+----+----------+
4 rows in set (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from t_user;
+----+----------+
| id | username |
+----+----------+
| 1 | zs |
| 4 | wangwu |
| 5 | reos |
| 6 | jack |
+----+----------+
4 rows in set (0.00 sec)
索引
1. インデックスとは何ですか? 用途は何ですか?
索引は書籍の目次に相当し、対応するリソースをすぐに見つけることができます。
データベースに関しては、テーブルにクエリを実行するときに 2 つの取得方法があります:
1 つ目の方法: フル テーブル スキャン、
2 つ目の方法: インデックスに基づく取得 (非常に効率的)
インデックスによって取得効率が向上するのはなぜですか?
実際、最も基本的な原則は、スキャンの範囲を減らすことです。
インデックスによって検索効率は向上しますが、インデックスもデータベース内のオブジェクトであり、データベースの継続的なメンテナンスが必要であるため、インデックスを任意に追加することはできません。維持費がかかります。たとえば、テーブル内のデータが頻繁に変更される場合、データが変更されるとインデックスの順序を変更して維持する必要があるため、インデックスの追加は適していません。
インデックスの追加とは、特定のフィールドまたは複数のフィールドにインデックスを追加することです。
select ename,sal from emp where ename='SMITH';
ename フィールドにインデックスが追加されていない場合、上記の SQL ステートメントはテーブル全体のスキャンを実行し、ename フィールド内のすべての値をスキャンします。
ename フィールドにインデックスが追加されると、インデックスに従って上記の SQL ステートメントがスキャンされ、インデックスが迅速に検索されます。
2. インデックス オブジェクトを作成するにはどうすればよいですか? インデックスオブジェクトを削除するにはどうすればよいですか?
インデックス オブジェクトを作成します。
create index 索引名称 on 表名(字段名);
インデックスオブジェクトを削除します。
drop index 索引名称 on 表名;
3. フィールドへのインデックスの追加を検討する必要があるのはどのような場合ですか? (どんな条件が揃っているのか)
- 膨大なデータ(顧客ニーズやオンライン環境に応じて)
- このフィールドに対する DML 操作はほとんどありません (フィールドを変更する必要があり、インデックスも維持する必要があるため)
- このフィールドは、多くの場合、where 句に表示されます (どのフィールドに基づいてクエリが実行されることが多いか)。
4. 注: 一意制約のある主キーとフィールドには、インデックスが自動的に追加されます。
主キーに基づいてクエリを実行すると、より効率的になります。主キーに基づいて検索してみてください。
5. SQL ステートメント (explain) の実行計画を確認します (
これは MySQL のみにあります)。
mysql> explain select ename,sal from emp where sal = 5000;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | emp | NULL | ALL | NULL | NULL | NULL | NULL | 14 | 10.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
給与 sal フィールドにインデックスを追加します。
create index emp_sal_index on emp(sal);
mysql> explain select ename,sal from emp where sal = 5000;
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+-------+
| 1 | SIMPLE | emp | NULL | ref | emp_sal_index | emp_sal_index | 9 | const | 1 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+-------+
6. インデックスの下部で使用されるデータ構造は次のとおりです: B + Tree
7. インデックスはどのように実装されますか?
スキャン範囲は B ツリーによって狭められ、基礎となるインデックスはソートおよびパーティション化されます。インデックスにはテーブル内のデータの「物理アドレス」が含まれます。最後に、インデックスを通じてデータが取得された後、関連付けられた物理アドレスが次のようになります
。データを取得し、物理アドレスを使用してテーブル内のデータを検索するため、データの効率が最も高くなります。
select ename from emp where ename='SMITH';
通过索引转换为:
select ename from emp where 物理地址=0x3;
8. インデックスの分類は?
単一インデックス: 単一フィールドにインデックスを追加します
複合インデックス: 複数のフィールドにインデックスを追加します
主キーインデックス: 主キーにインデックスが自動的に追加されます
一意インデックス: 一意制約のあるフィールドにインデックスが自動的に追加されます
9. インデックスはいつ期限切れになりますか?
ファジー クエリを実行する場合、最初のワイルドカード文字は % であり、現時点ではインデックスは無効です。
select ename from emp where ename like '%A%';
データベースの 3 つの主要な設計仕様 (主要な内容、面接でよく聞かれる)
1. デザインパラダイムとは何ですか?
テーブル設計の基本は、この 3 つのパラダイムに従って設計されたテーブルにはデータの冗長性がないということです。
2. 3 つのパラダイムとは何ですか?
第 1 正規形: すべてのテーブルには主キーが必要であり、各フィールドはアトミックで既約である必要があります。
第 2 正規形: 第 1 正規形に基づくと、主キー以外のすべてのフィールドは主キーに完全に依存しており、部分的な依存関係を生成することはできません。
多対多、リレーショナル テーブル内の 3 つのテーブル、2 つの外部キー。
t_student学生表
sno(pk) sname
1 张三
2 李四
3 王五
t_teacher讲师表
tno tname
1 王老师
2 张老师
3 李老师
t_student_teacher_relation 学生讲师关系表
id(pk) sno(fk) tno(fk)
1 1 3
2 1 1
3 2 2
4 2 3
5 3 1
6 3 3
第 3 正規形: 第 2 正規形に基づくと、すべての非主キー フィールドは主キーに直接依存し、推移的な依存関係を生成できません。
1 対多、2 つのテーブル、多数のテーブルと外部キー。
班级t_class
cno(pk) cname
1 a
2 b
3 c
4 d
学生t_student
sno(pk) sname classnoo(fk)
101 张1 1
102 张2 1
103 张3 2
104 张4 2
105 张5 2
リマインダー (これは面接中に言っても構いません): 実際の開発では、顧客のニーズを満たすことに重点が置かれており、場合によっては実行速度と引き換えに冗長性が優先されます。
3. 1対1をどのように設計するか?
1 対 1 設計には 2 つのオプションがあります: 主キー共有
t_user_login ユーザー ログイン テーブル
id(pk) username password
1 zs 123
2 ls 456
t_user_detail ユーザー詳細テーブル
id(pk) realname tel
1 张三 111111111
2 李四 111132321
1 対 1 設計には 2 つのオプションがあります: 外部キー 一意の
t_user_login ユーザー ログイン テーブル
id(pk) username password
1 zs 123
2 ls 456
t_user_detail ユーザー詳細テーブル
id(pk) realname tel userid(fk+unique)
1 张三 111111111 2
2 李四 111132321 1
SQLの実行順序
(1) FROM [left_table] 选择表
(2) ON <join_condition> 链接条件
(3) <join_type> JOIN <right_table> 链接
(4) WHERE <where_condition> 条件过滤
(5) GROUP BY <group_by_list> 分组
(6) AGG_FUNC(column or expression),... 聚合/分组
(7) HAVING <having_condition> 分组过滤
(8) SELECT (9) DISTINCT column,... 选择字段、去重
(9) ORDER BY <order_by_list> 排序
(10) LIMIT count OFFSET count; 分页
共通機能
Mysql データベースは、Java のメソッドと同様の豊富な機能を提供します。
lower() 関数
このフィールドはすべて小文字に変換されます
LOWER(Strフィールド名)
select lower(ename) from emp;
upper() 関数
このフィールドはすべて大文字に変換されます
UPPER(Strフィールド名)
length() 関数
クエリフィールドの長さ、1文字は1文字としてカウントされ、1漢字は3文字としてカウントされます
LENGTH(Strフィールド名)
concat() 関数
文字列のつなぎ合わせ
CONCAT(Str フィールド名, Str 連結内容, Str 連結内容...)
substr() 関数
インターセプト文字列
SUBSTR (フィールド名、インターセプトの開始位置、インターセプトの合計長)
**注:**インデックスは 1 から始まります
replace() 関数
交換
REPLACE(Str フィールド名、置き換えられる from_str の内容、to_str の新しい内容)
ifnull() 関数
nullかどうかを判定し、nullの場合は0や1などに置き換えます。
IFNULL(expr1 フィールド名, expr2 置換される新しい内容)
**注意: **計算を実行するとデータベースに NULL が表示されますが、計算には関与せず、常に NULL になります。
Round()関数
小数、四捨五入
ROUND (フィールド名)
ceil()関数
小数点以下は切り上げ、小数点がある場合は整数を削除して 1 を加算します
CEIL (フィールド名)
フロア()関数
小数点以下は切り捨て、小数点がある場合は小数点以下を切り捨てる
FLOOR (フィールド名)
now() 関数
現在の時刻、年、月、日、時、分、秒を問い合わせます
今()
curdate() 関数
年、月、日
コード()
curtime() 関数
時、分、秒
コータイム()
year() 関数
年
YEAR(日付 日付) / YEAR(日付文字列 日付を書き込む)
month() 関数
月
MONTH(日付日付) / MONTH(日付文字列書き込み日付データ)
day() 関数
日
DAY(日付日付) / DAY(日付文字列書き込み日付データ)
時間()関数
時間
HOUR(日付日付) / HOUR(日付文字列書き込み日付データ)
分()関数
ポイント
MINUTE(日付日付) / MINUTE(日付文字列書き込み日付データ)
Second() 関数
秒
SECOND(日付日付) / SECOND(日付文字列書き込み日付データ)
タイムスタンプdiff()関数
2 つの日付間の時差を計算します。年、月、日、時、分、秒、曜日、
timestampdiff (間隔タイプ、前の日付、次の日付) を指定できます。
エスケープ文字
' SQL文の記号として、内容中にアポストロフィが1つも出てくるとめちゃくちゃになってしまうのでエスケープしてください。
方法 1: \ を使用して通常の文字にエスケープします
方法 2: 外側で「 」を使用する
select
ename,
lower(ename),
upper(ename),
length(ename),
concat(ename,'hello',100),
substr(ename,2),
substr(ename,1,3),
replace(ename,'S','666'),
ifnull(comm,0),
round(sal),
ceil(sal),
floor(sal),
now(),
curdate(),
curtime(),
year('1999-02-12'),month(now()),day(now()),hour(now()),minute(curtime()),second('12:22:1')
from
emp;
SQLの最適化
1. 挿入データの最適化
2. 主キーの最適化:
主キーが順序どおりに挿入されない場合、ページ分割が発生する可能性があります。
3. 最適化による順序付け
4. 最適化によるグループ化
5. 制限の最適化
6. カウントの最適化
7. 更新の最適化:
主キー/インデックス フィールドに基づいてデータの更新を試みます
要約する
- * の代わりにフィールド名を使用してみてください。
- テーブルを設計するときは、フィールド タイプとして char ではなく varchar を使用することをお勧めします。
- フィールドの値には、文字列ではなく数値を使用することをお勧めします。
- and は使用できますが、or は使用できません。できるだけ詳細なフィルタ条件を設定してください。
- インデックスのデザイン、最大 5 つのインデックス、多すぎない
- ファジークエリ。インデックスを有効にするために開始要素を決定してください。
- データベースには数値に関する厳密な要件がありません。name=123 インデックスは無効ですが、name='123' インデックスは有効です。
- 役に立たないインデックスはすぐに削除するのが最善です
not int を使用する場合は、必ず次の括弧内の NULL を除外してください。