目次
データベースの概要
データをさまざまな形式のファイルに直接保存するのではなく、データベースを使用して保存するのはなぜでしょうか? たとえば、name='zs'、age=20 を保存したい場合、データベースを使用してテーブルを構築し、.txt ファイルを使用してそれを保存できます。
数据库管理系统
ファイルを直接操作する場合と比較して、データベースを使用すると、データ管理の効率が大幅に向上し、より多くのデータを保存し、データの一貫性、完全性、セキュリティを確保しながら、データの冗長性を減らし、データ共有を容易にします。- たとえば、上記のデータに含まれる「zs」という名前の人物全員の年齢をクエリしたい場合、Java を使用してデータベースを操作する必要があり、SQL を記述して一定のプロセスを使用してクエリを実行するだけでよく、ファイル ストレージを使用する必要があります。 IO ストリームはデータを読み取ったり、データを走査して判断したりするため、非常に面倒で非効率ですが、数千のデータの場合、これは単純に大きな違いです。
データベース ストレージには非常に多くの利点があるため、すべてのテキスト ファイルを保存するためにデータベースを使用しないのはなぜでしょうか。あるいは、ファイル システムの代わりに DBMS システムを使用してみてはいかがでしょうか?
- ファイルはさまざまな形式のデータをサポートしますが、データベースにはデータに対する制約が多すぎます
- データベースはファイル システムにも依存します
- ファイルの読み込みは他のミドルウェアの関与を必要とせず、比較的独立しており、容量が少なく、形式が多様で、頻繁な操作を必要としないデータの保存に適しています。たとえば、ソフトウェアの構成情報をファイル形式で保存すると、すべてのソフトウェアの起動時に指定したデータベースに接続してデータを読み込んだり、データを構築したりすることができません。
データベース、データベース管理システム、構造化クエリ言語(DB、DBMS、SQL)
数据库
:データを整理して保管するデータ保管倉庫数据库管理系统
:ウェアハウスが指定されたところで、ウェアハウスにデータを入れる方法と、ウェアハウスから条件に応じてデータを取得する方法を教えてください。これには管理が必要です软件
。菜鳥駅と同様に駅全体の棚が倉庫として利用されているが、速達の受け取りや取り出しには管理システムが必要である。Mysql、Oracle などの日常的なデータベースはデータベース管理システムを指します。结构化查询语言
: 構造化クエリ言語、つまりデータベース管理システムを通じてすべての間で循環されSQL
ます。これはリレーショナル データベースの大きな利点でもあり、 、、などのさまざまなリレーショナル データベースをSQL という言語を使用して操作でき、小さな箇所を変更するだけで済みます。关系型数据库
操作数据库的编程语言
Oracle
MySQL
SQL Server
SQLとNoSQLの比較
数据结构化
: SQL のデータ ストレージは、指定されたフィールド、指定されたデータ型などの境界によって制限されますが、NoSQL は、V のデータ構造を必要としない、redis キーと値のペアのストレージなどの非常に緩やかな形式です。数据关联性
: SQL テーブルとテーブルの間には、1 対多、1 対多、多対多などの関係が存在する可能性があり、通常はデータの整合性が考慮されます。NoSQL では、各データは独立して存在し、このデータを削除する際に、他のデータがこのデータに依存しているかどうかを考慮する必要はありません。查询方式
: SQL データベースには統一されたクエリ言語がありますが、各 NoSQL ベンダーは独自の言語を持っています存储方式
: SQL で操作するデータのほとんどはディスクに保存され、NoSQL で操作するデータのほとんどはメモリに保存され、ディスクはバックアップ データの保存に使用されます。
リレーショナル データベースは、行と列の形式でデータを格納し、 1 つの を形成します。最大の利点は、、 、二维表
をサポートしていることです。复杂的查询
方便维护
支持事务
リレーショナル データベース管理システムの一般的な例
市場シェア別ランキング
Oracle
: 1972 年に誕生し、大型
データベースに適した初の商用データベースとなりました。同社は社名も Oracle Corporation に変更しました。2009 年に Sun (MySQL を含む) が買収されたため、Oracle は現在Oracle
データベース (收费
) とMySQL
データベース (分为社区版和商业版
) の両方を所有しています。MySQL
免费
:データベースに適したオープンソース中小型
データベースで、1995年に開発され、2008年にSunに買収され、2009年にOracleに買収されたため、現在はOracleに属しています。Oracle は MySQL を無料のコミュニティ エディションと有料の商用エディションに分割していますSQL Server
: Microsoft によって開発された中型
データベース。C# および .NET で一般的に使用されます。PostgreSQL
: オープンソースの無料の中小規模データベースDB2
: IBMの大規模課金データベース製品で、銀行でよく使用されています。SQLLite
: 携帯電話でよく使用される組み込みマイクロデータベースMariaDB
: オープンソースで無料の中小規模データベース MySQL の創設者は、MySQL 買収後、クローズドソースのリスクを懸念し、MySQL と互換性の高い MySQL ブランチ プロジェクト MariaDB を作成しました。
MySQL
導入
- MySQL は現在
Oracle
同社の所有物です (過去にも現在にも導入されているため、ここでは繰り返しません)。 - これは、オープンソースで無料のカスタマイズ可能なデータベース管理システムです。
- 大規模なデータベースの管理
千万条数据的
、32 ビット システムに対する最大のテーブル ファイルのサポート4GB
、および 64 ビット システムに対する最大のテーブル ファイルのサポートをサポートします。8TB
- 標準
SQL数据语言
- 複数のシステムで実行でき、C、C++、Java、Python、Php、Ruby などの複数の言語をサポートします。
MySQL8.0
機能が大幅に強化されたマイルストーン バージョンが 2016 年にリリースされました。
利点:
- オープンソースで無料、低コストで使用可能
- 優れたパフォーマンスと安定したサービス
- 小型で使いやすい
- 確立された活発なコミュニティ
インストール
Win 版と Linux 版はインストール方法が異なります。ここではバージョン 8 を例に説明します。
Win 版の場合は、ファイルをクリックして次のステップに進むだけで、msi
インストール時に连接的端口
、root用户密码
、服务名称
、を指定できます是否自启动
。インストール後、どこでも SQL コマンドを使用できるように、環境変数を忘れずに構成してください。
Linux バージョンrpm -ivh
Linux バージョンのダウンロードしたパッケージを解凍し、パッケージ内のファイルを段階的にインストールし、最後に MySQL サービスを開始する必要がありますsystemctl start mysqld
。MySQL には、初回起動時にデフォルトでパスワードが設定されています。起動ログで生成されたデフォルトのパスワードを照会する必要があります。root としてログインしたgrep 'temporary password' /var/log/mysqld.log
後パスワードを変更するには、MySQL のデフォルトのパスワードは厳密モードです。つまり、数字と文字を含む 8 桁以上の数字が必要です。
これを行いたくない場合は、MySQL のグローバル変数を変更できます。たとえば
、弱いモードを使用する場合は、必要なパスワードの数字を 4 桁以上に変更します。
set global validate_password.policy = 0;
set global validate_password.length = 4;
root ユーザーのデフォルトのホスト名は localhost です。これは、このマシンのみを使用して接続できます。つまり、他のデバイスを使用してログインして接続することはできず、ユーザーの対応するログイン IP を変更する必要があることを意味します。
update user set host='%' where user ='root'; 使用通配符% 改为了任意连接ip
ここまで設定したら再起動します
データベース接続
-
开启
データベース サービス:net start mysql80
インストール時に自動的に開始されます。サービス名が変更されていない場合は sql80 です。変更する場合は独自のサービスを使用する必要があります。 -
关闭
データベース サービス:net stop mysql80
コマンド ライン -
cmd ウィンドウに次のように入力します: mysql [-h
主机地址
] [-P端口
] -u用户名(通常为root)
-p (パスワード モードを指定): データベースがローカル マシン上にあり、ポートが変更されていない場合、[] 内の内容は省略できます。安全のため、-p のパスワードはコマンドに直接入力されませんが、コマンドを入力して Enter キーを押し、パスワードを入力して
クライアントに接続します。 -
スクリョグ
- ナビゲート: (個人的なお気に入り)
- データグリップ:
Ideaの接続データベースプラグインも簡単接続可能
SQL
SQL は構造データベースの統一データ言語であり、リレーショナル データベースを運用するための統一標準を定義したもので、機能の違いにより 4 種類に分類されます。
クラス名 | 説明する |
---|---|
DDL | データベース定义语言 、ライブラリの作成、ライブラリの変更、ライブラリの削除、テーブルの作成、テーブルの変更 (つまり、フィールドの変更)、テーブルの削除など。簡単に言うと、構造的な制約を設けてデータの挿入を待つというものです。 |
DML | Data 操作语言 、テーブル内のデータに対する操作により、增、删、改 構造内のデータが変更されます |
DQL | データ查询语言 : データを変更せずに、テーブル内のデータに対してさまざまな操作を実行します查 。 |
DCL | データ权限控制语言 、データの特定のアクセス許可を制御し、データ システムのセキュリティを確保します。 |
一般的な構文:
- 複数の SQL ステートメント
;
を区切るために使用します win版
大文字と小文字は区別Linux版大小写敏感
されませんが(設定可能)、大文字と小文字を区別して開発し、キーワード、関数名、変数名を使用し大写
、データベース名、テーブル名、フィールド名を使用します。小写
阿里开发公约【强制】
表名、字段名必须使用小写字母或数字 ,
禁止出现数字开头,禁止两个下划线中间只 出现数字。
数据库字段名的修改代价很大,因为无法进行预发布,所以字段名称需要慎重考虑。
- ノート:
- 単一行:
#
または--
- 複数行:
/*注释内容*/
- 単一行:
DDL
データベース操作
- お問い合わせ
- すべてのデータベースをクエリする
show DATABASES;
- 現在のデータベースをクエリするには、関数を使用します。
SELECT DATABASE();
- すべてのデータベースをクエリする
- 増加
- データベースを作成します
CREATE DATABASE 数据库名
。データベースが存在するとエラーが報告されます。 - データベースの場合
不存在再创建
:CREATE DATABASE IF NOT EXISTS 数据库名
- データベースを作成するとき、
字符集
:を指定しCREATE DATABASE 数据库名 DEFAULT CHARSET utf8mb4
、データベース作成ステートメントの後にデフォルトの文字エンコーディングを追加しますutf8mb4
。エンコーディングが使用されます。このエンコーディングは含まれますutf8
が、モバイル端末の表現を格納できるように、4 バイトのエンコーディングも格納できます。 、など。
- データベースを作成します
- 消去
- データベースの削除
DROP DATABASE 【IF EXISTS】 数据库名
: -その他: - データベース切り替え:
USE 数据库名
: データを操作する場合、必ずデータベースに切り替えてください。
- データベースの削除
データテーブルの操作
- お問い合わせ
- 現在のクエリ
库所有表
:SHOW TABLES;
- ビュー
表结构
:DESC 表名
- 指定されたテーブルのテーブル作成ステートメントをクエリします。
SHOW CREATE TABLE 表名
- 現在のクエリ
- 建表 CREATE
- テーブルを作成する
CREATE TABLE 表名(字段1 类型 【comment 字段注释】,字段2 类型 【comment 字段注释】)【comment 表注释】
表的数据类型
- 数値
- テーブルを作成する
タイプ | バイト | 符号付き範囲 |
---|---|---|
tinyInt |
1 | 負の値 (2( 8 -1) 乗除 2) ~ 正の ((2( 8 -1) 乗除 2)-1) |
smallInt | 2 | 負の値 (2( 16 -1) 乗除 2) ~ 正の ((2( 16 -1) 乗除 2)-1) |
中整数 | 3 | 負の値 (2( 24 -1) 乗除 2) ~ 正の ((2( 24 -1) 乗除 2)-1) |
int |
4 | 負の値 (2( 32 -1) 乗除 2) ~ 正の ((2( 32 -1) 乗除 2)-1) |
bigInt | 8 | 負の値 (2( 64 -1) 乗除 2) ~ 正の ((2( 64 -1) 乗除 2)-1) |
浮く | 4 | |
ダブル | 8 | |
10進数(M,D) | M+2バイト | 固定小数点数は精度とスケールを手動で指定します。精度 = 小数点以下の桁数 + 整数の桁数 = 小数点以下の桁数十分精准,但占用空间 |
数値型の場合は符号ビットに注意してください。整数型の場合は符号ビットとして使用されるビットがあります。符号を使用しない場合は(0,2からビット数の乗まで)の範囲を意味します。 - 1). 浮動小数点数の符号なしタイプは符号付きのみです
。0 と正の数字、实际范围并未扩大
は小数部分を省略するだけです。
- 文字タイプ
タイプ | バイトサイズ | 説明 |
---|---|---|
文字 | 0~255 | 固定長文字列。長さを指定する必要がある指定多长,就占用多少字符空间 が効率が高い |
可変長文字 | 0~65535 | 可変長文字列。最大長を指定する必要があります。占用多少字符空间,与具体存储有关 Char よりも柔軟ですが、効率は劣ります |
文章 | 0~65535 | 長文に適したデータ |
char より効率的な固定長の使用機能 |
- 日付時刻
タイプ | 占有バイト数 | 説明 |
---|---|---|
日にち | 3 | 日付値 YYYY-MM-DD |
時間 | 3 | 時間値 HH:MM:ss |
年 | 1 | 年の値 YYYY 範囲 1901 ~ 2155 |
日付時刻 | 8 | 日付と時刻の値 YYYY-MM-DD HH:MM:SS の範囲は 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 |
タイムスタンプ | 4 | 日付と時刻の値 YYYY-MM-DD HH:MM:SS1970-01-01 00:00:01 から 2038-01-19 03:14:07 はタイムスタンプとして保存され、現在のタイムゾーンに従って自動的に変換されます |
テーブル変更 ALTER
- フィールドを追加します
ADD
。ALTER TABLE 表名 ADD 字段名 类型 【注释】【约束】
- フィールドタイプを変更します
MODIFY
:ALTER TABLE 表名 MODIFY 字段名 类型
- フィールド名とフィールド タイプを変更します
CHANGE
。ALTER TABLE 表名 CHANGE 旧字段 新字段 类型 【注释】【约束】
- フィールドの削除
DROP
:ALTER TABLE 表名 DROP 字段名
- テーブル名を変更します
RENAME
。ALTER TABLE 表名 RENAME TO 新表名
削除 DROP
- 删除表
: DROP TABLE 【IF EXISTS】表名
- 削除後にテーブルを作成します。これは、截断
:を実行するのと同じです。TRUNCATE TABLE 表名
DML
データの追加 INSERT
VALUE と VALUES には大きな違いはなく、混合することができます。
指定字段
データを追加するにはINSERT INTO 表名(字段1,字段2,字段3) VALUES(字段1的值,字段2的值,字段3的值)
- すべてのフィールドにデータを追加する
- すべてのフィールドを書き込みます
INSERT INTO 表名(字段1,字段2,字段3) VALUES(字段1的值,字段2的值,字段3的值)
- フィールド名を省略してテーブル名を直接書きます
INSERT INTO 表名 VALUES(字段1的值,字段2的值,字段3的值)
- すべてのフィールドを書き込みます
- データをバッチで追加しても前と後ろは変わりません
VALUES(第一组值),(第二组值),(第三组值)...
注:
- VALUES の値の順序は、データ テーブルのフィールド (フィールドが指定されていない場合) または指定された順序と同じである必要があります。
字段顺序一一对应
- 文字列日付関数には
''
符号を追加する必要があります - 挿入されるデータ サイズは、設定されたデータ型の範囲に準拠している必要があります
データを削除する
- データの削除:
DELETE FROM 表名 【WHERE 条件】
データの削除では 1 行のみ削除できますが、特定のフィールドのデータは削除できません。DDL ステートメントを使用してフィールド データ全体を削除しALTER TABLE 表名 DROP 字段名
たり、フィールドの特定の値を削除したりできます。UPDATE语句将其置空
データ変更 UPDATE
- データ変更:
UPDATE 表名 SET 字段1=值1,字段2=值2... FROM 表名 【WHERE 条件】
; 条件を書かない場合はテーブル全体のデータを変更します; 条件を指定する場合はシンボル条件のデータのみを変更します
DQL
単一テーブルクエリ
クエリ文の構造
SELECT 字段列表 FROM 表名 WHERE 条件 GROUP BY 分组条件 HAVING 分组后的条件 ORDER BY 根据哪些字段排序 LIMIT 分页参数
単純なクエリ
- 複数のフィールドのクエリ
SELECT 字段1、字段2 FROM 表名 WHERE 条件
はクエリ効率が低いSELECT * FORM 表名..
ため推奨されません*
- フィールドのテーブル名を設定します
- クエリ対象のフィールドの後のスペースの後にエイリアスを直接追加できます。
SELECT 字段1 别名1
- クエリするフィールドの後に追加します
SELECT 字段1 AS 别名1
- クエリ対象のフィールドの後のスペースの後にエイリアスを直接追加できます。
- クエリ時に重複レコードを削除する
SELECT DISTINCT 字段列表 FROM 表名
知らせ
_
一致する单
文字を表します、%
一致する任意个
文字を表します- 使用および表現する
IS NULL
ために空か空でないかIS NOT NULL
BETWEEN x AND y
範囲インクルード関数x
とy
集計関数は
フィールド全体を全体として扱います纵向计算
関数名 | 効果 |
---|---|
カウント() | フィールド内の縦方向データの数をカウントします。 |
最大() | このフィールド (列) をカウントします。最大的值 |
分() | このフィールド (列) をカウントします。最小的值 |
平均() | このフィールド (列) をカウントします。平均值 |
和() | このフィールド (列) をカウントします。总和 |
分组查询
把where
条件查询后的数据 跟据某一字段按照相同值进行分组,分组后的数据可以使用HAVING
进行过滤
HAVING
与WHERE
的区别
- 执行的先后顺序不一样,HAVING执行在分组后,分组又在
WHRER
查询后 HAING
可以使用聚合函数进行再一次过滤
分组字段数据相同的有几组,结果就会显示几条数据
注意:
1、分组查询的字段应为聚合函数和用来分组的字段 ,否则无意义
要在每个分组中只能查询出一行数据,和聚合函数是对每组数据进行压缩成一个数据,每组字段每组也只有一个
例:统计男女生人数 :按照性别进行分组,最后只会有两行数据 在字段中使用聚合函数的COUNT(*)将每组数据进行统计个数
最后显示两行数据,一行是分组的男生数据,另一行是女生数据 。 字段只适合符合分组条件,例如字段加上一个姓名,男生组中出现一个姓名,女生组出现一个姓名 ,只有两行数据毫无意义
2、可以根据多个字段进行分组 GROUP BY 字段1 ,字段2 ,最后数据个数为 字段1*字段2
3、HAVING必须要跟在GROUP By之后
排序方式
-
ASC 升序 (默认)
-
DESC 降序
-
按照某个字段1进行
升序
排序,顺序相同时,在按照字段2进行降序排序ORDER BY 字段1 ASC,字段2 DESC
分页查询
SELECT 字段列表FROM 表名 LIMIT 起始索引,数据条数
注意
1、若不指定起始索引,默认为0
2、起始索引=(页数-1)* 每页显示条数
3、LIMIT是MySQL的方言,不同的数据库分页有不同的实现方法
例如:查询第三页人员的姓名,每页显示5条数据
这里第三页起始页数,根据起始索引=(起始页数-1) * 每页的大小
,每页的大小为5 即可获取起始索引,所以在查询语句后面添上LIMI 起始索引,每页大小
总结
执行顺序:
先要知道从哪张表查,数据条件过滤,要查询哪些字段?将查询的出的数据按照什么顺序排列?要几个数据?
例
多表查询
利用表与表的关系,通过一条SQL语句查询多张表的数据
多表关系
一对一
表中一条数据对应另一张表的一条数据,
那么为什么不合为一张表呢?
- 将单表进行拆分,既能提升查询效率 也方便管理。例如将用户表分为用户基础信息表和用户详情表,这样在可以根据需求进行不同粒度的查询,提升效率
怎样实现一对一的关系呢?
- 一张表的字段关联着另一张表的主键,且子表的该字段唯一,这样就能确保一张表中只有一条数据与另一张表中的一条数据相对应
使用外键是确定表中数据间的关系从而确保数据完整性,使用唯一约束是确保只有一条数据(唯一)对应另一条数据(主键唯一)
多对一、一对多
这种比较常见,比如图书一个管理员要保管多个图书,一个部门对应多个员工,如果把他们放在一张表,那么多的一方字段会大量的冗余。
怎样实现多对一的关系呢?
多对一和一对多是同一种关系,只是主体不同罢了。实现使用多
的一方外建于一
的一方的主键,并保存一
的一方的主键。
这样就能确保数据完整性的同时,也能通过多的一方找到一的一方。
例如,员工表保存部门的id。
- 查询员工的部们信息时,通过其字段保存的部门主键去部门表中查找对应数据即可
- 查询此部门对用所有的员工信息,也同样去员工表查询保存部们的字段=此部门id即可
多对多
一张表的多数据可能对应另一张的多条数据,没有一
的一方了,这时就需要一张表单独去保存他们的对应关系。例如课程
与学生
,一个学生对应多个课程,一个课程也对应多个学生,这时就不需要这两张表建立关联,只需要再去创建一张学生课程关系表
去记录哪一学生有哪一门课
例如:
连接查询
如果直接去查询两张表,那么将会形成笛卡尔积
两张表没有关系的数据内容也会在一条数据显示
例
那么怎样解决呢? 过滤!
在将这些数据按照条件就行过滤,条件就是这两张表的关系 。例如在语句后面添加上WHERE tbl_cla.id= tbl_stu.class_id
,这样就成功查出了学生信息与其对应的班级信息
而这种两张表连接的方式也叫隐式内连接
,此外还有多种不同的方式
连接分类
在表连接时建议给表起别名,但一但起别名就不能使用原表名。在指定两张表的连接条件时,不能使用字段的别名,要使用表名/表的别名.字段原名
,因为根据SQL的执行顺序,在执行WHERE语句时还没有执行到SELECT,对于字段的别名来说是未知的
内连接 JOIN
内连接相当于求两张表的交集部分
例如:有员工表和部门表,那么通过内连接能够查询出每一个员工对应的部门,对于有部门没有员工和有员工没有部门的将会被舍去
隐式内连接
SELECT 字段列表 FROM 表1 ,表2 WHERE 连接条件
把两张表的数据全部查取出来,再通过字段共同部分进行过滤,从而查取出两张表中每条关联的数据。没有关联的数据将会被过滤掉,所以是两张表的交集
显式内连接
SELECT 字段 FROM 表1 (INNER)JOIN 表2 ON 连接条件
求两张表的交集部分的另一种写法
外连接
左外连接 LEFT JOIN
例如 ,同样是员工表和部门表,如果员工表左外连接部门表,则会查询所有
员工以及对应的部门,当然这样就会包含
没有部门的员工,会省略
没有员工的部门
SELECT 字段 FROM 表1 LEFT(OUTER)JOIN 表2 ON 连接条件
右外连接 RIGHT JOIN
同左外连接,只是这次是去查询右表与左表的公共部分
例 :员工表和部门表,如果员工表右外连接查询部门表,则查询的数据是每个部门包含的员工信息,也包括
没有员工的部门,省略
没有部门的员工
SELECT 字段 FROM 表1 RIGHT (OUTER)JOIN 表2 ON 连接条件
左外连接和右外连接可以通过改变表的连接顺序实现转换,例如:上面的例子也可以通过部门表左外连接员工表实现
,多数时使用的是左外连接
自连接 JOIN
同一张表再次连接自己,查询一张表中数据有关联的部分。例如,一张员工表,表中记录着员工的信息和领导的id,而领导也在这张表。一张表中数据和数据存在关联部分,通过自连接即可查询到每一个领导对应的员工的信息等
自连接一定要给表起别名,否则都是一张表怎样去区分是哪张表呢?
SELECT 字段 FROM 表1 别名 JOIN 表1 别名 ON 表中数据关系部分
,自连接的语法同内连接,只是同一张表间的连接
联合查询 UNION
联合查询相当于把两次查询的数据进行纵向的拼接,条件是表的字段列数以及类型
必须一一对应,否则纵向拼接怎样对齐数据呢?分为两种方式,一种是允许重复即允许一条数据多次显示 关键字UNION ALL
;一种是拼接后进行去重 ,关键字UNION
同样是员工表,我想要查询员工年龄大于30 的,在查询工资大于1万的,将查询的数据进行纵向拼接,则可能会出现年龄既大于30工资又大于1万的重复显示,忽视则UNION ALL
,去重则UNION
查询的语法就像条SQL通过一个关键字UNION
/UNION ALL
进行连接
SELECT 字段 FORM 表
UNION
SELECT 字段 FROM 表
为什么不使用一条语句呢?因为是要求的是查询字段类表即类型相同,而不是表的所有字段,这样就会出现不同的表,每张表满足不同的条件进行相同字段的连接
同样是员工表与部门表,要查询员工表人数大于20 的部门的id和位置在北京的部门id,两张不同表通过不同的条件查询出相同的字段进行拼接即可得出 位置在北京同时人数大于20的部门id
子查询
SQL语句中将另一条SQL的查询结果作为条件进行查询,SQL嵌套
标量子查询
返回的数据为单个值
常用的查询条件:= <> > >= < <=
例如:查询A班级的所有学生信息 。 学生表中存放的是班级的id字段,通过班级id作为条件,就要查询A班级对应的id,只能有一个数据所以是标量子查询
列子查询
查询一列数据,即一个字段的多条数据,通常是作为一个字段的条件范围
常用的查询条件:IN 、NOT IN 、 ANY 、SOME 、 ALL
例如:查询班级编号为A和B的所有学生信息。A和B会查询出两条id数据,只要在查询学生表时要求学生的班级id在这班级id范围内即可
行子查询
查询一行的可能多个字段的数据
常用的查询条件:= 、<> 、IN 、NOT IN
用于要查询的数据需要多个有关子查询的条件
例如 有两张表,要查询A部门的员工家庭住址和A部门所在地相同的员工信息
要先查询A部门对应的部门id,和A部门的地址。子查询是一行有多个字段的数据作为条件,这就是 行子查询
语句就为 SELECT * FROM emp WHERE (dep_id,addr)=(SELECT id,addr FROM dpt WHERE name='A')
表子查询
行子查询有多条数据或者说列子查询有多个字段,多条数据多个字段,子查询查询出的即是一张表
例如:查询所有 员工的家庭地址与其所在部门地址相同的员工信息
首先就要查询所以部门的id以及地址,多个字段多条数据相当于一张表 作为查询员工表的条件。
常用的查询条件:in
语句就为 SELECT * FROM emp WHERE (dep_id,addr) in (SELECT id,addr FROM dpt)
DCL
数据库权限管理语句,对系统的管理不止可以使用语句,还可以使用命令行,由于对于开发,这里只做了解,只介绍部分使用语句的情况
认证管理
系统中所有的用户信息(用户名、密码等)也放在了一张表中,此表在系统数据库,库名为mysql
,库表为user
查询
- 查询此系统中的所有用户:查询所有用户即要查询
user
表中所有的数据SELECT * FROM mysql.user
添加
-
注册一个用户:
注意
注册用户并不是向表中添加一条数据,而是由专门的语句CREATE USER '用户名'@'登录时指定的ip' IDENTIFIED BY '密码'
- 值的注意的是
- 主机ip使用来限制用户可以从哪台主机进行登录,可以使用通配符
%
,代表任意主机 - 用户登录要满足三个条件,
用户名正确
,在指定的ip登录
,密码正确
- 用户创建完成后,没有任何权限,需要后面的赋值操作,否则登录后只会显示一张表
information_schema
- 主机ip使用来限制用户可以从哪台主机进行登录,可以使用通配符
- 值的注意的是
修改
- 修改用户密码:
ALTER USER '用户名'@'主机ip' IDENTIFIED WITH mysql_native_password BY '新密码'
也可修改主机名、用户名,这里不再介绍
删除
- 删除用户
DROP USER '用户名'@'主机名'
授权管理
除了root用户其他用户注册后必须还有为其授权权限,否则没有只能登录,登录后只能看到一张系统的表,上面已经介绍过。
权限是精确到表的
权限都有哪些常见的、可供授予的呢?
权限名称 | 描述 |
---|---|
SELECT | 查询权限 |
INSERT | 插入权限 |
UPDATE | 修改数据 权限 |
DELETE | 删除权限 |
CREATE | 创建库表 权限 |
ALTER | 修改表 权限 |
DROP | 删除表、库、视图 权限 |
ALL, ALL PRIVILEGES | 所有权限 |
查询谁哪些权限 SHOW GRANTS FOR '用户名'@‘主机名’
授权谁哪些权限 GRANT 权限1 , 权限2 .. ON 数据库名.表名 TO ‘用户名’@‘主机名’
撤销谁哪些权限REVOKE 权限1 , 权限2 .. ON 数据库名.表名 FROM ‘用户名’@‘主机名’
数据库和数据表可以使用通配符*
代表所有,所有权限可以使用ALL
, ALL PRIVILEGES
总结
函数
函数是SQL数据库管理系统中自己封装的一段SQL语句,可以直接调用其去执行相应的功能
这里列举一些常见函数
字符串函数
对字符串类型的数据进行处理,最后返回一个字符串
-
CONTANT(‘a1’,‘a2’,‘a3’):
字符串拼接
,放在参数列表中的各个参数将会按照先后顺序被拼接成一个字符串返回
- 例:
- 例:
-
LOWER(‘xxx’) :
全部转为小写
将参数中所有字母
全部转为小写返回- 例
- 例
-
UPPER(‘xxx’):
全部转为大写
,将函数参数列表中所有字母
全部转为大写- 例
- 例
-
LPAD(‘str’,n,‘xxx’):
字符串左填充
,参数列表分别是 要进行填充的字符串、一共要达到的个数、用什么填充 ,最后返回一个处理后的字符串- 例:
- 例:
-
RLAD(‘str’,n,‘xxx’):
字符串右填充
,与上面不同的是,当原字符串没有满足指定的个数时,将会从右边进行填充
-
TRIM(‘str’):
去除左右两边的空格
,注意是不能去除中间空格的- 例
- SUBSTRING(‘str’,startNum,截取长度):
指定从哪个位置截取几个字符
,注意:是从1开始查到startNum,截取包含startNum位置的字符- 例
- 例
- 例
数值型函数
-
CEIL(num):
向上取整,小数一律进一法取整
CEIL翻译为:天花板- 例
- 例
-
FLOOR(num):
向下取整
,只要整数部分 FLOOR翻译为:地板- 例
- 例
-
MOD(x,y):
取模运算
,相当于将x/y
,取模即取前者除以后者的余数
- 例
- 表示除法不用去使用函数,直接使用运算法即可
- 例
-
RAND():
生成0~1之间的随机数
rand 翻译为:胡乱的,随机的- 例
- 例
-
ROUND(num,y):
将小数进行四舍五入
,y指的是小数要保留的小数
位数- 例
练习小案例:通过数据库的函数,生成一个六位数的随机验证码。
随机数乘上1000000,会取得6位数的整数和一堆小数,采用ROUD()进行四舍五入或 CEIL()进一、或FLOOR()取整 等。总之要去掉小数 考虑到可能会有 0.0xxxxxxxx 通过乘和去小数后变为 0xxxxx,0又会自动省略,造成最后不满足6位,所以要对生成的整数进行填充。 使用LPAD()、RPAD()都可以。 SELECT LPAD(ROUND(RAND()*1000000),6,'0')
- 例
日期函数
-
CURDATE():
获取当前日期
CUR即current(翻译为 当前的)的简写,拼上DATE即日期- 例
- 例
-
CURTIME() :
获取当前时间
同理,CUR+TIME- 例
- 例
-
NOW():
当前的日期和时间
,相当于 CURDTAE()+CURTIME()- 例
- 例
-
YEAR(date)、MONTH(date)、DAY(date):
根据日期获取年份、月份、天数
- 例
- 例
- 例
时间类型的计算函数
- DATE_ADD(date,INTERVAL num 时间单位):
计算指定间隔后的日期/时间
INTERVAL 是固定的 后面接上 值 和 单位- 计算日期 则第一个参数传递的是 DATE型, 时间单位有
YEAR
,MONTH
,DAY
,返回的是DATE类型- 例
- 例
- 计算日期 则第一个参数传递的是 DATE型, 时间单位有
- 计算时间 则第一个参数传递的是
DATETIME
型或TIME
型, 单位还可以为HOUR
、MINUTE
、SECOND
- 例
- 例
- DATEDIFF(date1,date2):
计算时间间隔
,返回天数 是前面的日期-后面日期的天数- 例
- 例
- TIMEDIFF(time1,time2):同理,返回的是时分秒
- 例:
- 例:
流程函数
- IF(bool,v1,v2): 如果
bool
如果为true,则返回v1,false则返回v2。相当于一个三目运算- 例
- IFNULL(v1,v2):
如果为v1不为空则返回v1,反之返回v2
- 例:
- 例:
- 例
- CASE 字段 WHEN ‘值1’ THEN ‘返回值1’ WHEN ‘值2’ THEN ‘返回值2’…ELSE ‘返回值3’ END
当这个字段的值等于某个值时,返回什么值,如果都前面的值都不符合,就返回一个ELSE中的值
- 例
- 例
- CASE WHEN(bool)THEN ‘返回值1’ WHEN (bool) THEN ‘返回值2’ ELSE ‘返回值3’ END
满足哪个条件就返回哪个值,都不满足返回false
与前者的不同之处是,前者是用一个字段去挨个与WHEN去比较,这个要比较的值在一个CASE中可以不是固定的,它的特点是可以比较灵活,字段也可以多个
总结
约束
约束用来限制某个字段中应该插入什么样的数据(作用单位是字段),确保表中数据的正确性(如检查约束
、非空约束
、唯一约束
),完整性(如 外键约束
、默认约束
),
约束类型
约束名称 | 描述 |
---|---|
主键约束 primary key |
每一行数据的标识 非空且唯一 |
唯一约束 unique |
在一张表中该字段所有数据不能重复 |
非空约束 not null |
该字段不能为null (可以为空格) |
默认约束 default |
如果不指定值,则自定填土设定好的默认值 |
检查约束 check 该功能在sql8.0.16 版本后才有 |
该字段的数据要满足的一定的条件 |
外键约束 foreign key |
建立表与表之间的联系 ,字表的某个字段的数据要在父表某个字段数据的范围内 |
主键添加时机
- 可以在创建表时,在
字段类型
后面指定约束 。例如创建一张表,将id设定为主键,将姓名设置为唯一
create TABLE tbl_user (id int primary key comment '编号',name varchar(20) unique comment '姓名')
- 创建表时在末尾补上
create Table tbl_user (id int comment '编号',name varchar(20) unique comment '姓名' ,primary key(id))
- 在创建表后,进行修改表添加字段约束 。
alter table tbl_user add primary key
主键删除时 alter table tbl_user drop primary
外键
外键使得两张表之间数据完整性。例如有一个班级表,有一个学生表,学生表中有一个字段时学生的班级,其字段值的范围肯定要在班级编号的范围内。所以建立外键约束,在插入时要检查学生表的班级id字段是否在班级id字段范围内。其中班级表就为父表
,学生表就为字表
外键添加时机
- 在创建表的末尾 指明此表的哪个字段要外键与哪张表的哪个字段
create table tbl_stu (id int PRIMARY KEY auto_increment ,class_id int ,FOREIGN KEY(id) REFERENCES tbl_class(id))
- 修改表 时添加外键
ALTER TABLE tbl_stu Add constraint 外键名称 FOREIGN KEY(id) REFERENCES 主表 (外键的字段)
外键的删除
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称
删除表外键的时候要指定外键的名称,而在创建外键时如果不指定外键名称,系统会自动生成,但生成的不知道是啥,那怎么删除呢?(不使用客户端工具情况下)
使用一个命令那就查看建表语句,在语句中会显示外键的名称show create table 表名
冒頭の例を使用すると、student テーブルの class フィールドはクラス テーブルの id フィールドに外部キー設定されているため、クラス テーブルが削除された場合、student テーブルの class フィールドはどうなるでしょうか。親テーブルが削除され、子テーブルが変更されないままの場合、子テーブルのこのフィールドに対応する情報が見つからず、データが不完全になります。
では、どうすれば解決できるでしょうか?
親テーブルの削除/更新動作が子テーブルに及ぼす影響
ストラテジー | 説明 |
---|---|
NO ACTION RESTRICT mySQLのデフォルト |
親テーブルを変更/削除するときに、このデータが他の子テーブルによって外部キーとして制約されている場合、親テーブルのデータは削除できません (解決策: 対応する子テーブルのデータを削除します)。 |
カスケード | 親テーブルを削除すると、対応する子テーブルのデータも削除されますが、上記の方法とは異なり、子テーブルのみを削除してから親テーブルを削除することができます。そして、これは、親テーブルが最初に削除され、次に子テーブルに対応するデータが削除されることです |
NULL を設定 | 親テーブルを削除しても、子テーブルの対応するデータ全体は削除されませんが、対応するフィールドの値は空白になります。 |
デフォルトを設定Innodb不支持 |
上記との違いは、空白のままではなくデフォルト値として指定できることですが、データベースエンジンInnodb不支持 |
どちらを選択するかは外部キーの設定時に指定できます。指定する場合は変更と削除に分かれます。指定しない場合はデフォルトになります。NO ACTION
例:ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段)REFERENCES 主表名(字段) ON UPDATE xxx ON DELETE xxx