MySQL
注: この記事は Java Crazy God が書いたメモを見るためのものです。興味のある方は URL をクリックしてください:
https://www.bilibili.com/video/BV1NJ411J79W?from=search&seid=1914316698934444374&spm_id_from=333.337.0.0
データベースとは何ですか
略称:DB(データベース)
概念: データ ウェアハウス、オペレーティング システム (Windows、Linux、Mac) にインストールされ、主に SQL を学習し、大量のデータを保存できるソフトウェア。
役割: データの保存、データの管理
データベースが物理空間に存在する場所
すべてのデータベース ファイルはデータ ディレクトリに保存され、フォルダーはデータベースに対応します。
本質的には、依然としてファイルストレージです
データベースの分類
リレーショナルデータベース: (SQL)
- MySQL、Oracle、SQL、DB2、SQLlite
- データは、テーブルとテーブル、行と列の間の関係を通じて保存されます。
非リレーショナル データベース: (NoSQL-----SQL だけではありません)
- Redis、MongDB
- オブジェクトストレージを介して、オブジェクト自体の属性によって決定されます
DBMS(データベース管理システム)
- データベース管理ソフトウェア、科学的かつ効果的な管理、保守、データ収集
MySQL
- リレーショナル データベース管理システム、
- 最高の RDBMS アプリケーション ソフトウェアの 1 つ
- オープンソースのデータベース ソフトウェア
- 小型、高速、低コスト
MySQL は cmd ウィンドウを通じて起動およびシャットダウンします。
閉鎖:
net stop mysql (これはサービス名です)
オンにする
net start mysql (上記と同じ)
サービス名のクエリ:
- このコンピュータを右クリックします
- 管理
- サービスとアプリケーション
- 仕える
- mysql (またはその他、通常は mysql+...) を検索します。
データベースに接続する
mysql -u root -p(密码) ————cmd连接数据库
update mysql.user set authentication_string=password('密码') where user='root' and Host = 'localhost';
————修改用户密码
————————————————————————————————————————————————
1. 在cmd中,使用数据库的所有语句必须使用";"结尾
2. show databases; ————查看所有数据库
3. 输入: user school ————切换数据库 user 数据库名
下一行跳出: Database changed
4. show tables; ————查看数据库所有表
5. describe *****(表的名字)————显示数据库中表的所有信息
6. cerate database ****(数据库的名字)————创建一个数据库
7. exit; ————退出连接
8. "--" 单行注释
9. "/**/" 多行注释
データベースを操作する
**mysql キーワードは大文字と小文字を区別しません**
データベースを作成する
CREATE DATABASE [IF NOT EXISTS] ***(库名) []内的是可选的
データベースを削除する
DROP DATABASE [IF EXISTS] ****(库名)
データベースを使用する
-- "`",tab键的上面,如果表明或者字段名是一个特殊字符,需要带"`" USER `***(库名)`
データベースを見る
SHOW DATABASES 查看所有的数据库
データベース内の列の種類
価値:
- tinyint ——— 1 バイトを占める非常に小さなデータ
- smallint ———— 2 バイトを占める小さいデータ
- mediaint ——— 中サイズのデータ、3 バイトを占有
- int ——— 標準整数、4 バイト
- big ———— 8 バイトを占める大きなデータ
- float ——— 4バイトを占める浮動小数点数
- double ——— 8バイトを占める浮動小数点数
- 10 進数 ———— 財務計算でよく使用される文字列形式の浮動小数点数
弦:
- char ——— 文字列固定サイズ (0 ~ 255)
- varchar ——— 変数文字列 (0 ~ 65535)、一般的に使用される変数文字列
- tinytext ----- 小さなテキスト、2^8-1
- text ——— テキスト文字列、2^16-1、大きなテキストを保存
日時:
- 日付 ————YYYY-MM–DD、日付形式
- 時間 ——— HH:mm:ss、時間形式
- 日付 ————YYYY-MM-DD-HH:mm:ss、最も一般的に使用される時刻形式
- タイムスタンプ ——— タイムスタンプ、1970.1.1 から現在までのミリ秒数! (世界的に統一)、より一般的に使用されます
- 年 - 年
ヌル:
- 値なし、不明
- ==注意、計算に NULL を使用しないでください。そうでない場合、結果は NULL になる必要があります。
データベースフィールドのプロパティ
署名を外す
- 未署名の証明書
- 列を負の値として宣言できないことを宣言します。
ゼロフィル
- 0フィル
- 足りない桁は0、int(3[ここは長さを示します])、5——>005で埋められます。
自己増加
- 通常は自己増分として理解され、前のレコードに基づいて自動的に 1 を加算します (デフォルト)
- 通常、一意の主キー (整数型である必要があるインデックス) を設計するために使用されます。
- 主キーの自動インクリメントを含む開始値とステップ サイズをカスタマイズできます。
空ではありません (NUll は null ではありません)
- null 以外に設定されているとします。値が割り当てられていない場合、エラーが報告されます。
- NUll、未入力の場合、デフォルトは null
デフォルト
- デフォルトを設定する
- 例: 性別、デフォルトは男性です。この列の値を指定しない場合は、デフォルト値が使用されます。
各テーブルには以下の 5 つのフィールド (項目) が必要です。
- id-----主キー
- "
version
" -------- 楽観的ロック- is_delect------疑似削除
- gmt_create-----作成時間
- gmt_update------変更時刻
データベーステーブルを作成する
テーブル名: 学生
学籍番号: int、名前: varchar、性別、生年月日、誕生日
CREATE TABLE IF NOT EXISTS `student` (
`ID` INT(15) NOT NULL AUTO_INCREMENT COMMENT '学号',
`NAME` VARCHAR(30) NOT NULL DEFAULT '匿名' COMMENT '姓名',
`sex` VARCHAR(2) NOT NULL DEFAULT '女' COMMENT '性别',
`birthday` DATETIME DEFAULT NULL COMMENT '出生日期',
PRIMARY KEY(`ID`)
)ENGINE`student`=INNODB DEFAULT CHARSET=utf8
フォーマット:
格式:
CREATE TABLE [IF NOT EXISTS] `表名`(
`字段名` 列类型 [属性] [索引] [注释],
`字段名` 列类型 [属性] [索引] [注释],
······
`字段名` 列类型 [属性] [索引] [注释]
)[表类型] [字符集设置][注释]
共通コマンド
SHOW CREATE DATABASE ****(数据库名称)-- 查看创建数据库的语句
SHOW CREATE TABLE ****(表名) --查看student数据表的定义语句
DESC ****(表名) -- 显示表的结构
データベーステーブルの種類について
データベースのエンジンについて
INNODB
- デフォルトで使用する
- スペースを節約する
- もっと早く
MYISAM (初期に使用)
- 以前に使用されていた
- 高いセキュリティ
- トランザクション処理、マルチテーブルマルチユーザー操作
ミサム | INNODB | |
---|---|---|
トランザクションサポート | サポートしません | サポート |
データ行のロック | サポートされていません (テーブルロック) | サポート |
外部キー | サポートしません | サポート |
全文インデックス | サポート | サポートしません |
テーブルスペースのサイズ | 小さい | MYISAMの約2倍の大きさ |
物理ファイルのMYSQLエンジンの違い
- INNODB のデータベース テーブルには *.frm が 1 つだけあり、ibdata ファイルは上位ディレクトリにあります。
- MYISAM対応ファイル
- *.frm – テーブル構造定義ファイル
- *.MYD データファイル (データ)
- *.MYL インデックス ファイル (インデックス)
データベーステーブルの文字セットエンコーディングを設定します。
CHARSET=UTF8
- 設定されていない場合は、mysql のデフォルトの文字セット エンコーディングになります — (中国語はサポートされていません)
- MySQL のデフォルトのエンコーディングは Latin1 であり、中国語はサポートされていません。
- my.ini でデフォルトのエンコーディングを構成する
文字 -set-server= utf8
テーブルの変更、削除
改訂
- テーブル名を変更する
ALTER TABLE 旧表名 RENAME AS 新表名
- テーブルフィールドの追加
ALTER TABLE 表名 ADD 字段名 列属性
- テーブルフィールドの変更 (名前変更、制約の変更!)
ALTER TABLE *****(表名) MODIFY **(字段名) **(列属性) ---修改约束 ALTER TABLE *****(表名) CHANGE ***(旧名字) ***(新名字) ***(列属性) --字段重命名
結論:
CHANGE はフィールドの名前を変更するために使用されます。フィールドのタイプと制約は変更できません
MODIFY はフィールドでは使用できません。フィールド タイプと制約のみを変更できます。
- テーブルフィールドを削除する
ALTER TABLE ***(表名) DROP ***(列属性)
- テーブルの削除
DROP TABLE IF EXISTS ****(表名) 创建和删除操作尽量加上判断,以免报错
注意点
- `` フィールド名、ラップするために使用します
- コメント: " - "、/**/
- SQLの大文字と小文字を区別しない
- 記号はすべて英語です
MySQL データ管理
外部キー (物理外部キー - データベース レベル)
方法 1
テーブル作成時に制約を追加する(面倒、複雑)
CREATE TABLE `grade`(
`gradeid` INT(10) NOT NULL AUTO_INCREMENT COMMENT '年级id',
`gradename` VARCHAR(50) NOT NULL COMMENT '年级名称',
PRIMARY KEY(`gradeid`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
CREATE TABLE `student`(
`ID` INT(15) NOT NULL AUTO_INCREMENT COMMENT '学号',
`NAME` VARCHAR(30) NOT NULL DEFAULT '匿名' COMMENT '姓名',
`SEX` VARCHAR(2) NOT NULL DEFAULT '女' COMMENT '性别',
`BIRTHDAY` DATETIME DEFAULT NULL COMMENT '出生日期',
`gradeid` INT(10) NOT NULL COMMENT '学生的年级',
PRIMARY KEY(`ID`),
KEY `FK_gradeid` (`gradeid`),
CONSTRAINT `FK_gradeid` FOREIGN KEY (`gradeid`) REFERENCES `grade`(`gradeid`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
外部キー関係を持つテーブルを削除する場合は、まず他を参照しているテーブル (スレーブ テーブル) を削除し、次に参照されているテーブル (プライマリ テーブル) を削除する必要があります。
方法2
テーブルが正常に作成されたら、外部キー制約を追加します。
创建表是没有外键,后续添加外键关系公式:
ALTER TABLE 表 ADD CONSTRAINT 约束名 FOREIGN KEY(作为外键的列) REFERENCES `哪一个表名`(`哪个字段`)
ベストプラクティス:
- データベースは単純なテーブルであり、データを格納するためにのみ使用され、行 (データ) と列 (データ) のみが含まれます。
- 複数のテーブルのデータを利用したい、外部キーを利用したい(プログラム経由で実現)
DML言語
追加
定義: データ操作言語
-- 插入语句语法:
INSERT INTO 表名([字段名1,字段2,字段3])VALUES('值1'),('值2'),('值3')
予防:
- フィールドはカンマで区切られます
- フィールドは省略可能ですが、以下の値は 1 対 1 に対応している必要があります
- 複数のデータを同時に挿入できます。VALUES 以降の値は英語の括弧で囲む必要があり、括弧は英語のカンマ S で区切る必要があります
改訂
アップデートで誰が変更するのか? (条件) 古い値 = 新しい値を設定します
-- 语法:
UPDATE `表名` SET COLNUM_NAME = VALUE,[COLNUM_NAME=VALUE....] WHERE [条件]
条件: where 句演算子。例: ID が特定の値に等しい、特定の値より大きい、特定の範囲内で変更されている...
演算子はブール値を返します
オペレーター | 意味 | 範囲 | 結果 |
---|---|---|---|
= | 同等 | 5=6 | 間違い |
<> または != | 等しくない | 5<>3 | 真実 |
> | 以上 | 5>3 | 真実 |
< | 未満 | 5<3 | 間違い |
<= | 以下 | 2<=3 | 真実 |
>= | 以上 | 3>=2 | 真実 |
…との間 | 一定の範囲内で | [2,5] | |
と | && (私とあなた) | 5>1と1>2 | 間違い |
また | ||(私かあなた) | 5>1または1>2 | 真実 |
予防:
- Colnum_name はデータベースの列です。「」を持ってくるようにしてください。
- 条件、フィルター条件: 指定しない場合、すべての列が変更されます
- value は特定の値ですが、変数にすることもできます
- 複数の設定の属性間はカンマで区切ります
消去
削除コマンド
文法:
DELETE FROM ***(テーブル名) [WHERE条件]
TRUNCATEコマンド
文法:
TRUNCATE ***(テーブル名)
効果:
データベース テーブルを完全にクリアしても、テーブルの構造とインデックスの制約は変更されません。
DELETE と TRUNCATE の違い
- 同じ点:
- 前回のデータは削除できます
- どちらもテーブルの構造を削除しません
- 違い
- TRUNCATE は自己インクリメント列をリセットし、カウンターは 0 に戻ります。
- TRUNCATE はトランザクションに影響を与えません
CREATE TABLE `teacher`(
`id` INT(8) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(20) NOT NULL,
PRIMARY KEY(id)
)ENGINE=INNODB DEFAULT CHARSET=utf8
INSERT INTO `teacher`(`name`) VALUE('1'),('2'),('3')
DELETE FROM `teacher` --不会影响自增
TRUNCATE TABLE `teacher` --自增归0
DELETE削除の問題とデータベースの再起動現象:
- INNODB、自己インクリメント列は 1 から始まります (メモリに保存され、電源がオフになると失われます)
- MyISAM、最後の自己インクリメントから開始し続けます (ファイル内に存在し、失われません)
DQL
DQLクエリデータ
お問い合わせ
- すべてのクエリ操作でそれが使用されます
- 単純なクエリと複雑なクエリの両方を完了できます
- データベース内のコア言語とステートメント
- 最も頻繁に使用されるステートメント
查询全部字段:
SELECT * FROM *****(表名)
查询指定字段
SELECT ` * `(表中字段),` * `,.... FROM ***(表名)
别名,给结果起一个名字(字段或表)
SELECT ` * `(表中字段) AS ***(别名),` * ` AS ***(别名),.... FROM ***(表名) AS ****(别名)
函数 CONCAT(A,B)
SELECT CONCAT('**(连接的字符串)',****(表中字段)) AS ***(别名) FROM ****(表名)
注意:
起别名只在自己展示界面窗口那边展示别名,但是重新打开表后,展示的不是别名而是自己刚开始定义的变量名;也就是说,别名只是我们在查询的时候看的。
CONCAT中的A,使用英文单引号框起来的,不是``!。
语法:
SELECT ***(字段) .....FROM ****(表)
有的时候,列名字不是那么见名知意,我们起别名 AS: 字段名 AS 别名 表名 AS 别名
重複排除が遠い
作用:
去除SELECT查询结果中重复的数据
语法:
SELECT DISTANCT `表中字段` FROM `表名`
SELECT * FROM `result` --查询全部
SELECT `studentno` FROM result --查询某一列
SELECT DISTINCT `studentno` FROM result --去重
数据列的表达式:
SELECT VERSION() --查询系统版本(函数)
SELECT 100*3-1 AS 计算结果 --用于计算(表达式)
SELECT @@AUTO_INCREMENT_INCREMENT --查询自增步长
SELECT `表中字段`+1 AS '别名' FROM 表名
データベース内の式:
- テキスト値
- リスト
- ヌル
- 関数
- 計算式
- システム変数
SELECT + 式
where 条件節
役割: データ内の適格な値を取得する
検索結果は 1 つ以上の式で構成されます。結果ブール値
論理演算子:
オペレーター | 文法 | 説明 |
---|---|---|
と && | A と B A&&B | 論理 AND、両方が true、結果は true |
または || | A または BA||B | 論理和。どちらかが true の場合、結果は true |
いいえ ! | ではありません!A | 論理的否定、true は false、false は true |
ファジークエリ
比較演算子
オペレーター | 文法 | 説明 |
---|---|---|
無効である | A は NULL です | 演算子が NULL の場合、結果は true になります |
NULL ではありません | A は NULL ではありません | 演算子が NULL でない場合、結果は true になります |
間 | B と C の間の A | A が B と C の間にある場合、結果は true になります。 |
好き | BのようなA | SQL が一致し、A が B と一致する場合、結果は true |
の | A IN(A1、A2、A3…) | a が a1 または a2 のいずれかの値にあると仮定すると、結果は true になります。 |
' **% ** ' _ ':
- %: 任意の文字に対して 0 を表します
- _: 文字を表します
SELECT `表中字段`, `表中字段` ,....FROM `表名`
WHERE `表中字段` LIKE '*(模糊查询的内容)%'
注:出现的内容为以*开头,后面的长度不限
SELECT `表中字段`, `表中字段` ,....FROM `表名`
WHERE `表中字段` LIKE '*(模糊查询的内容)_'
注:出现的内容以*开头,后面只有一个字符,如果后面又两个字符则用两个__,或者用%
说明:
_ % 可以放在模糊查询的前面,也可以放在后面,根据自己的需求进行代码的书写。
イン:
- 1 つ以上の特定の値が続きます
SELECT `表中字段`, `表中字段` FROM `表名` WHERE `表中字段` IN ('***(查询的具体内容)',`****`.....);
NULL ではありません NULL
查询表中字段1为空的值 SELECT `表中字段`, `表中字段` FROM `表名` WHERE 表中字段1='' OR 表中字段1 IS NULL 查询表中字段1不为空的值 SELECT `表中字段`, `表中字段` FROM `表名` WHERE 表中字段1 IS NOT NULL
テーブル結合クエリ
操作する | 説明 |
---|---|
内部結合 | テーブル内に少なくとも 1 つの一致がある場合は、行を返します。 |
左結合 | 右のテーブルに一致するものがない場合でも、左のテーブルからすべての値を返します |
右結合 | 左側のテーブルに一致するものがない場合でも、右側のテーブルからすべての値を返します |
JOIN(結合テーブル) ON(判定条件) – 結合クエリ
WHERE -- 同等のクエリ
自己参加
定義: 自分自身を自分のテーブルに接続する
コア: テーブルを 2 つの同一のテーブルに分割する
カテゴリID | カテゴリ名 |
---|---|
2 | 情報技術 |
3 | ソフトウェア開発 |
5 | アートデザイン |
ピド | カテゴリID | 種別名 |
---|---|---|
3 | 4 | データベース |
2 | 8 | オフィス情報 |
3 | 6 | ウェブ開発 |
5 | 7 | psテクノロジー |
Frey の対応するサブクラス間の関係をクエリします。
父親 | サブクラス |
---|---|
情報技術 | オフィス情報 |
ソフトウェア開発 | データベース |
ソフトウェア開発 | ウェブ開発 |
SELECT 構文:
SELECT [ALL | DISTINCT] { * | TABLE.* | [TABLE.FIELD1[AS ALIAS1][,TABLE.FIELD2[AS ALIAS2]][,......]] FROM TABLE_NAME [AS TABLE_ALIAS] [LEFT | RIGHT | INNER JOIN TABLE_NAME2] [WHERE....] ---指定结果需满足的条件 [GROUP BY ....] ---指定结果按照那几个字段来分组 [HAVING] --- 过滤分组的记录必须满足的次件 [ORDER BY.....] --指定查询记录按一个或多个条件排序 [LIMIT { [OFFSET,]ROW_COUNTOFFSET OFFSET}]; --指定查询记录从那条到那条 } 上述顺序不能变
注: []: オプションを示し、{}: 必須を示します
重要なクエリのテーブル名からフィールドへの SELECT (テーブルとフィールドの別名を付けることができます)
XX JOIN 等価性判定で結合するテーブル
where (特定の値、サブクエリ文)
group by (そのフィールドごとにグループ化)
持つ (グループ化された情報をフィルタリング、条件は where と同じですが、場所が異なります)
order by ... (そのフィールドで並べ替え) [昇順/降順]
startindexのページサイズを制限する
--测试代码:
CREATE TABLE `test`(
`categoryid` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`pid` INT(10) NOT NULL,
`categoryName` VARCHAR(50) NOT NULL,
PRIMARY KEY (`categoryid`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
SELECT t.`categoryName`, s.`categoryName`
FROM `test` AS t, `test` AS s
WHERE s.pid=t.categoryid
ページネーションと並べ替え
並び替え:
**昇順:**ASC
**降順:**DESC
文法:
ORDER BY `表中字段` ASC[DESC]
ページネーション:
役割: データベースのプレッシャーを軽減し、人々により良いエクスペリエンスを提供し、ウォーターフォール フローを回避します。
文法:
LIMIT 起始值, 页面大小(pageSize) 计算: --【pageSize:页面大小】 --【(n-1)*passageSize:起始值】 --【n:当前页】 --【数据总数/页面大小=总页数】
サブクエリ
WHERE (这个值是计算出来的)
本质:
在WHERE语句中嵌套一个子查询语句
WHERE(SELECT FROM *)
由里及外
MySQL函数
常用函数
**常用函数:** 数学运算: SELECT ABS(-8) --取绝对值 SELECT CEILING(9.4) --向上取整 SELECT FLOOR(9.4) --向下取整 SELECT RAND() --返回一个0-1之间的随机数 SELECT SIGN(0) --判断一个数的符号,负数返回-1,正数返回1 字符串函数 SELECT CHAR_LENGTH('*****') --字符串长度 SELECT CONCAT('**','**','**') --拼接字符串 SELECT INSERT('****',1,2,'***') --查询,从某个位置开始替换某个长度 SELECT LOWER('ADSAFSF') --转换成小写 SELECT UPPER('qadaddf') --转换成大写 SELECT INSER('***','*') --返回第一次出现的子串的索引、 SELECT REPLACE('*****','****1','****2') --替换出现的指定字符串 SELECT SUBSTR('******',4(开始位置),2(截取长度)) --截取原字符串 SELECT REVERSE('********') --反转 时间和日期函数: SELECT CURRENT_DATE() --获取当前日期 SELECT CURDATE() --获取当前日期 SELECT NOW() --获取当前时间 SELECT LOCALTIME() --返回本地时间 SELECT SYSDATE() --返回系统时间 SELECT YEAR(NOW()) SELECT MONTH(NOW()) SELECT DAY(NOW()) SELECT HOUR(NOW()) SELECT MINUTE(NOW()) SELECT SECOND(NOW()) 系统: SELECT SYSTEM_USER() SELECT USER() SELECT VERSION()
聚合函数
函数名称 | 描述 |
---|---|
SUM() | 求和 |
COUNT() | 计数 |
AVG() | 平均数 |
MAX() | 最大值 |
MIN() | 最小值 |
… | 其他 |
SELECT COUNTz(指定列,表中字段) FROM ***(表名) --会忽略所有的null值
SELECT COUNT(*) FROM ***(表名) --不会忽略null值,本质:计算行数
SELECT COUNT(1) FROM ***(表名) --不会忽略所有的null值,本质:计算行数
数据库级别的MD5加密
MD5:增强算法复杂度和不可逆性
破解原理:网站后有一个字典,MD5加密后的值,加密的前值
CREATE TABLE `test`(
`id` int(4) NOT NULL,
`name` VARCHAR(20) NOT NULL,
`pwd` VARCHAR(20) NOT NULL,
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
--明文密码
INSERT INTO test VALUES(1,'张','123456'),(2,'李','123456'),
(3,'王','123456')
--加密
UPDATE test SET pwd=MD5(pwd) WHERE id=1
UPDATE test SET pwd=MD5(pwd)---加密全部的密码
--插入时加密
INSERT INTO test VALUES(4,'XX',MD5('123456'))
-- 校验:将用户传递的密码进行MD5加密,然后比对加密后的值
SELECT * FROM test WHERE `name`='XX' AND pwd=MD5('123456')
事务
什么是事务:要么都成功,要么都失败
事务原则:
- ACID原则(如下)
- 原子性:两个步骤一起成功或者一起失败,不能只发生其中一个动作(要么都成功,要么都失败)
- 一致性:针对一个事务操作前与操作后的状态一致
- 隔离性:多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰
- 持久性:事务结束后数据不会随着外界原因导致数据丢失,事务没有提交,便恢复到原状;事务提交便持久化到数据库中。事务一旦提交不可逆。
脏读:
定义:一个事务读取了另外一个事务未提交的数据
不可重复读:
定义:在一个事务内读取表中的某一行数据,多次读取结果不同(不一定错,场合不对)
虚读(幻读):
定义:一个事务内读取到别的事务插入的数据,导致前后读取不一致
MySQL默认开启事务自动提交
SET autocommit = 0 /*关闭*/
SET autocommit = 1 /*开启*/
--手动处理事务
START TRANSACTION --标记一个事务的开始,从这个之后的sql都在同一个事务当中
INSERT XX
INSERT XX
(上面两行都成功才算成功,否则是失败的)
--提交:持久化(成功!)
COMMIT
--回滚:回到原来的样子(失败!)
ROLLBACK
--事务结束
SET autocommit = 1 --开启自动提交
SAVEPOINT 保存点名 --设置一个事物的保存点
ROLLBACK TO SAVEPOINT 保存点名 --回滚到保存点
RELEASE SAVEPOINT 保存点名 --撤销保存点
索引
定义:帮助MySQL高效获取数据的数据结构,提取句子主干,九二一获得索引的本质:索引就是数据结构
索引的分类:
- 主键索引:PRIMARY KEY
- 唯一标识,不可重复,只能有一个列作为主键
- 唯一索引:UNIQUE KEY
- 避免重复的列出现,可以重复,多个列都可以标识位唯一索引
- 常规索引:KEY/INDEX
- 默认的,index、key关键字来设置
- 全文索引:FULLTEXT
- 在特定的数据库引擎下才有,MyISAM
- 快速定位数据
--显示所有的索引信息:
SHOW INDEX FROM ***(表名)
--增加一个全文索引
ALTER TABLE ***(库名).****(表名) ADD FULLTEXT INDEX `******(索引名)`(`****(列名)`)
--EXPLAIN 分析sql执行状况
EXPLAIN SELECT * FROM ****(表名) --非全文索引
EXPLAIN SELECT * FROM ***(表名) WHERE MATCH(****(列名)) AGAINST('全文索引')
索引测试
索引在小数据量师,用处差别不大,在大数据时差别很明显。
索引原则
- 索引不是越多越好
- 不要对经常变动的数据加索引
- 小数据量的表不需要加索引
- 索引一般用来常用来查询的字段上!
索引的数据机构:
- Hash类型的索引
- Btree:INNODB的默认数据结构
权限管理和备份
用户管理
SQL命令操作:
用户表:mysql.user
本质:对这张表进行增删改查
--创建用户 CREATE USER ***(用户名) IDENTIFIED BY '密码' --修改当前用户的密码 SET PASSWORD = PASSWORD('******(密码)') --修改指定用户的密码 SET PASSWORD FOR *****(用户名)= PASSWORD('******(密码)') --用户重命名 RENAME USER ****(原名) TO *****(新名) --用户授权命令,授予全部的权限,库.表(一般不用,用勾选),不能给别人授权 GRANT ALL PRIVILEGES ON *.* --查询权限(指定用户) SHOW GRANTS FOR ****(用户名) SHOW GRANTS FOR root@localhost --撤销权限 REVOKE 那些权限 在那个库 给谁撤销 REVOKE ALL PRIVILEGES ON *.*(指定的,否则是全局的) FROM ****(用户名) --删除用户 DROP USER ****(用户名)
数据库的备份
- 保证重要数据不丢失
- 数据转移A–>B
MySQL数据库备份的方式:
- 拷贝物理文件
- 在可视化工具中手动导出
- 在想要导出的库/表,右键选择备份
- 使用命令行导出(mysqldump)
mysqldump -hlocalhost -uroot -p******(密码) **(库名) **(表名)>D:/...(导出位置)
mysqldump -h(主机) -u(用户名) -p(密码) 数据库 表1 表2 表3 ... >物理磁盘位置/文件名
#不加表名就是导出数据库
#导入
#登录的情况下,切换到指定的数据库
source ****(备份文件)
mysql -u用户名 -p密码 库名< 备份文件
数据库的设计
糟糕的数据库:
- 数据冗余,浪费空间
- 数据库插入和删除比较复杂,容易出现异常(屏蔽使用物理外键)
- 程序的性能差
良好的数据库设计:
- 节省内存空间、
- 保证数据的完整性
- 方便开发系统
三大范式
为什么:
- 信息重复
- 更新异常
- 插入异常
- 无法正常显示异常
- 删除异常
- 丢失有效信息
三大范式
- 第一范式
- 原子性:保证每一列不可再分
- 第二范式
- 前提满足第一范式
- 每张表只描述一件事情
- 第三范式
- 前提满足第二范式
- 确保数据表中每一列数据和主键直接相关,而不能间接相关
规范和性能的问题:
关联查询的表不能超过3张表
- 考虑商业化的需求和目标(成本和目标体验),数据库的性能更重要
- 在规范性能的问题的时候,适当考虑一下规范性
- 故意增加某些表的冗余字段(从多张表查询变成单表查询)
- 故意增加一些计算列(从大数据量降低为小数据量的查询:索引)
JDBC操作
定义:java数据库的连接,是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。JDBC时Sun Microsystem的商标。通常说JDBC是面向关系型数据库的。
第一个JDBC程序
import java.sql.*;
public class test {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver"); //固定写法,加载驱动
//2.用户信息和url school:这个是数据库
String url="jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=utf8&useSSL=true";
String username="root";
String password="123456";
//3.连接成功,数据库对象,Connection 代表数据库
Connection connection=DriverManager.getConnection(url,username,password);
//4.执行SQL的对象statement 执行sql的对象
Statement statement=connection.createStatement();
//5.执行SQL对象
String sql="SELECT * FROM test";
ResultSet resultSet=statement.executeQuery(sql);//返回结果集
while(resultSet.next()){
System.out.println("categoryid="+resultSet.getObject("categoryid"));
System.out.println("pid="+resultSet.getObject("pid"));
System.out.println("categoryName="+resultSet.getObject("categoryName"));
}
}
}
步骤总结:
- 加载驱动
- 连接数据库DriverManager
- 获得执行sql对象 Statement
- 获得返回的结果集
- 释放连接
DriverManager:
//DriverManager.registerDriver(new com.mysql.jdbc.Driver()); //不推荐,这样的话会注册两次
Class.forName("com.mysql.jdbc.Driver"); //固定写法,加载驱动
//connection:代表数据库
connection.rollback();
connection.commit();
connection.setAutoCommit();
URL
String url="jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=utf8&useSSL=true";
//mysql 默认端口号:3306
//jbdc:mysql(协议)://主机地址:端口号/数据库名?参数1&参数2&参数3
//oralce 默认端口号:1521
//jbdc:oracle:thin:@localhost:1521:sid
Statement执行SQL的对象 PrepareStatement执行SQL对象
String sql="SELECT * FROM test";//编写SQL statement.excuteQuery();//查询操作,返回一个ResultSet(结果集) statement.excute();//执行任何SQL statement.executeUpdate();//更新、插入、删除、都用这个,返回一个受影响的函数
ReseltSet查询结果集:封装了所有的查询结果
获得指定的数据类型:
resultset.getobject();//在不知道的情况下使用
//如果知道列的类型使用指定的类型
resultset.getString();
resultset.getInt();
resultset.getFloat();
resultset.getDate();
...
//遍历,指针
resultSet.beforeFirst(); // 移动到最前面
resultSet.afterLast(); // 移动到最后面
resultSet.next(); // 移动到下一个数据
resultSet.previous(); // 移动到前一行
resultSet.absolute(row); // 移动到指定行
释放资源
//释放连接
resultSet.close();
statement.close();
connection.close();//耗费资源,用完关闭
Statement对象
定义:jdbc中的statement对象用于向数据库发送SQL语句,想完成对数据库的增删改查,只需要通过这个对象向数据库发送增删改查语句即可。
ステートメントオブジェクトのメソッド:
- executeUpdate() は、データベースへの追加、削除、および変更のための SQL ステートメントを送信するために使用されます。executeUpdate() が実行されると、整数が返されます (つまり、追加、削除、および変更ステートメントにより、データベース内の複数の行のデータが変更されました)データベース)。
- executeQuery() は、データベースにクエリ ステートメントを送信するために使用されます。executeQuery メソッドは、クエリ結果を表す ResultSet オブジェクトを返します。
- executeUpdate(String sql) メソッドを使用して、データ追加操作を完了します。
statement st=connection.creatstatement();
String sql="insert into user(...) values(...)";
int num=st.executeUpdate(sql);
if(num>0){
System.out.println("success");
}
- データ削除操作を完了するには、executeUpdate(String sql) メソッドを使用します。
statement st=connection.creatstatement();
String sql="delect from user where id=1";
int num=st.executeUpdate(sql);
if(num>0){
System.out.println("success");
}
- データ変更操作を完了するには、executeUpdate(String sql) メソッドを使用します。
statement st=connection.creatstatement();
String sql="update user set name='***' where name='***'";
int num=st.executeUpdate(sql);
if(num>0){
System.out.println("success");
}
- executeUpdate(String sql) メソッドを使用して、データ クエリ操作を完了します。
statement st=connection.creatstatement();
String sql="select * from user where id=1";
ResultSet re=st.executeQuery(sql);
where(rs.next()){
//根据获取的数据类型,分别调用rs相应方法映射到java对象中。
}
//插入
public class TestInsert {
public static void main(String[] args) throws SQLException {
Connection conn=null;//获取数据库的连接
Statement st=null;//获取sql的执行对象
ResultSet rs=null;
try {
conn=JdbcUtils.getConnection();
st=conn.createStatement();
String sql="INSERT INTO test(categoryid,pid,categoryName)" +
"VALUES (10,4,'美术')";
int i=st.executeUpdate(sql); //受影响的行数
if(i>0){
System.out.println("Success");
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
JdbcUtils.release(conn,st,rs);
}
}
}
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=utf8&useSSL=true
username=root
password=123456
SQLインジェクション
SQL には抜け穴があり、それが攻撃されてデータ漏洩を引き起こす可能性があり、SQL が接続されます。
PreparedStatement オブジェクト
SQL インジェクション防止の本質: 渡されたパラメータを文字として扱い、文字が含まれている場合は直接エスケープされ、SQL インジェクションを効果的に回避できます。