[mysqld] basedir=D:\environment\mysql-5.7.31\ datadir=D:\environment\mysql-5.7.31\data\ port=3306 skip-grant-tables character-set-server=utf8
cd /d D:\environment\mysql-5.7.31\bin mysqld -install
mysqld --initialize-insecure --user=mysql
net start mysql
mysql -u root -p
update mysql.user set authentication_string=password('123456') where user='root' and Host='localhost';
flush privileges;
[mysqld] basedir=D:\environment\mysql-5.7.31\ datadir=D:\environment\mysql-5.7.31\data\ port=3306 #skip-grant-tables character-set-server=utf8
# 退出mysql exit # 關閉mysql net stop mysql # 啓動mysql net start mysql
C:\Users\Administrator>mysql -u root -p Enter password: ****** Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 15 Server version: 5.7.29 MySQL Community Server (GPL) Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>
utf8_unicode_ci和utf8_general_ci對中、英文來講沒有實質的差異。
utf8_general_ci 校對速度快,但準確度稍差。
utf8_unicode_ci 準確度高,但校對速度稍慢。
若是你的應用有德語、法語或者俄語,請必定使用utf8_unicode_ci。通常用utf8_general_ci就夠了。
ci是 case insensitive, 即 "大小寫不敏感", a 和 A 會在字符判斷中會被當作同樣的;
bin 是二進制, a 和 A 會別區別對待。
例如你運行:
SELECT * FROM table WHERE txt = 'a'
那麼在utf8_bin中你就找不到 txt = 'A' 的那一行, 而 utf8_general_ci 則能夠。
utf8_general_ci 不區分大小寫,這個你在註冊用戶名和郵箱的時候就要使用。
utf8_general_cs 區分大小寫,若是用戶名和郵箱用這個 就會照成不良後果
utf8_bin:字符串每一個字符串用二進制數據編譯存儲。 區分大小寫,並且能夠存二進制的內容java
每個SQLyog的執行操做,本質就是對應了一個SQL語句,均可以在軟件的歷史記錄中查看。
如:建立數據庫,在歷史記錄中以下,本質是執行語句:CREATE DATABASE schoolCHARACTER SET utf8 COLLATE utf8_general_ci;mysql
CREATE DATABASE `school`CHARACTER SET utf8 COLLATE utf8_general_ci;
對應語句以下算法
CREATE TABLE `school`.`student` ( `id` INT(10) NOT NULL COMMENT '學員ID', `name` VARCHAR(100) NOT NULL COMMENT '學員姓名', `age` INT(3) NOT NULL COMMENT '學員年齡', PRIMARY KEY (`id`) ) ENGINE=INNODB CHARSET=utf8 COLLATE=utf8_general_ci;
INSERT INTO `school`.`student` (`id`, `name`, `age`) VALUES ('1003', 'zhwj', '66');
單行註釋:--
多行註釋:/* */sql
mysql -u root -p --鏈接數據庫 exit; --退出鏈接 update mysql.user set authentication_string=password('123456') where user='root' and Host='localhost'; --修改用戶密碼 flush privileges; --刷新權限 -------------------------------------------------- show databases; --查看全部的數據庫 use school; --切換數據庫 show tables; --查看數據庫中全部的表 describe student; --查看錶的結構 describe student id; --查看錶中字段id的信息 create database westos; --建立數據庫 CREATE DATABASE `school`CHARACTER SET utf8 COLLATE utf8_general_ci; --建立數據庫
SQL語言共分爲四大類:數據查詢語言DQL,數據操縱語言DML,數據定義語言DDL,數據控制語言DCL。
數據庫
utf8_unicode_ci和utf8_general_ci對中、英文來講沒有實質的差異。
utf8_general_ci 校對速度快,但準確度稍差。
utf8_unicode_ci 準確度高,但校對速度稍慢。
若是你的應用有德語、法語或者俄語,請必定使用utf8_unicode_ci。通常用utf8_general_ci就夠了。
ci是 case insensitive, 即 "大小寫不敏感", a 和 A 會在字符判斷中會被當作同樣的;
bin 是二進制, a 和 A 會別區別對待。
例如你運行:
SELECT * FROM table WHERE txt = 'a'
那麼在utf8_bin中你就找不到 txt = 'A' 的那一行, 而 utf8_general_ci 則能夠。
utf8_general_ci 不區分大小寫,這個你在註冊用戶名和郵箱的時候就要使用。
utf8_general_cs 區分大小寫,若是用戶名和郵箱用這個 就會照成不良後果
utf8_bin:字符串每一個字符串用二進制數據編譯存儲。 區分大小寫,並且能夠存二進制的內容安全
utf8_unicode_ci和utf8_general_ci對中、英文來講沒有實質的差異。
utf8_general_ci 校對速度快,但準確度稍差。
utf8_unicode_ci 準確度高,但校對速度稍慢。
若是你的應用有德語、法語或者俄語,請必定使用utf8_unicode_ci。通常用utf8_general_ci就夠了。
ci是 case insensitive, 即 "大小寫不敏感", a 和 A 會在字符判斷中會被當作同樣的;
bin 是二進制, a 和 A 會別區別對待。
例如你運行:
SELECT * FROM table WHERE txt = 'a'
那麼在utf8_bin中你就找不到 txt = 'A' 的那一行, 而 utf8_general_ci 則能夠。
utf8_general_ci 不區分大小寫,這個你在註冊用戶名和郵箱的時候就要使用。
utf8_general_cs 區分大小寫,若是用戶名和郵箱用這個 就會照成不良後果
utf8_bin:字符串每一個字符串用二進制數據編譯存儲。 區分大小寫,並且能夠存二進制的內容服務器
CREATE DATABASE IF NOT EXISTS westos; CREATE DATABASE IF NOT EXISTS westos1 CHARACTER SET utf8 COLLATE utf8_general_ci;
DROP DATABASE IF EXISTS westos1;
USE school; --切換數據庫 USE `school`; --若是表名或字段名是一個特殊字符,須要加反引號,如:`school`
SHOW DATABASES; --查看全部數據庫
SHOW CREATE DATABASE `school`; --查看建立數據庫的語句 --查詢結果 CREATE DATABASE `school` /*!40100 DEFAULT CHARACTER SET utf8 */
類型 | 字節數 | 含義 | 備註 | 對應java |
---|---|---|---|---|
tinyint | 1個字節 | 十分小的數 | Integer | |
smallint | 2個字節 | 較小的數 | Integer | |
mediumint | 3個字節 | 中等的數 | Integer | |
int | 4個字節 | 整數 | 經常使用 | Long |
bigint | 8個字節 | 較大的數 | BigInteger | |
float | 4個字節 | 浮點數 | 不經常使用,會精度丟失 | Float |
double | 8個字節 | 浮點數 | 不經常使用,會精度丟失 | Double |
decimal | 字符串形式的浮點數 | 金融計算時經常使用 | BigDecimal |
類型 | 長度 | 含義 | 備註 | 對應java |
---|---|---|---|---|
char | 0~255 | 固定大小字符串 | String | |
varchar | 0~65535 | 可變字符串 | 經常使用 | String |
tinytext | 2^8 - 1 | 微型文本 | String | |
text | 2^16 - 1 | 文本串 | 經常使用,保存大文本 | String |
類型 | 格式 | 含義 | 備註 | 對應java |
---|---|---|---|---|
date | YYYY-MM-DD | 日期 | Date | |
time | HH:mm:ss | 時間 | Time | |
datetime | YYYY-MM-DD HH:mm:ss | 日期+時間 | 經常使用 | Timestamp |
timestamp | 時間戳,1970.1.1到如今的毫秒數 | 經常使用 | Timestamp | |
year | YYYY | 年份 | Date |
-- 若是表名或者字段名是一個特殊字符,須要加反引號(tab鍵上面的符號),如:`student` -- AUTO_INCREMENT 自增,默認+1 CREATE TABLE IF NOT EXISTS `student` ( `id` INT(10) NOT NULL AUTO_INCREMENT COMMENT '學號', `name` VARCHAR(30) NOT NULL DEFAULT '匿名' COMMENT '姓名', `pwd` VARCHAR(20) NOT NULL DEFAULT '123456' COMMENT '密碼', `sex` VARCHAR(1) NOT NULL DEFAULT '女' COMMENT '性別', `birthday` DATE DEFAULT NULL COMMENT '出生日期', `address` VARCHAR(100) DEFAULT NULL COMMENT '地址', `email` VARCHAR(50) DEFAULT NULL COMMENT '郵箱', PRIMARY KEY (`id`) ) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT '學員';
-- 格式 CREATE TABLE [IF NOT EXISTS] `表名` ( `字段名` 列類型 [屬性] [索引] [註釋], ...... `字段名` 列類型 [屬性] [索引] [註釋], PRIMARY KEY (`字段名`) ) [表類型] [字符集] [校對規則] [表註釋];
DROP TABLE IF EXISTS `student`;
SHOW TABLES; --查看全部表
DESCRIBE `student`; DESC `student`;
SHOW CREATE TABLE `student`; --查看建立數據表的語句 --查詢結果 CREATE TABLE `student` ( `id` int(10) NOT NULL AUTO_INCREMENT COMMENT '學號', `name` varchar(30) NOT NULL DEFAULT '匿名' COMMENT '姓名', `pwd` varchar(20) NOT NULL DEFAULT '123456' COMMENT '密碼', `sex` varchar(1) NOT NULL DEFAULT '女' COMMENT '性別', `birthday` date DEFAULT NULL COMMENT '出生日期', `address` varchar(100) DEFAULT NULL COMMENT '地址', `email` varchar(50) DEFAULT NULL COMMENT '郵箱', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='學員'
-- ALTER TABLE `舊錶名` RENAME AS `新表名`; ALTER TABLE `student` RENAME AS `student1`;
-- ALTER TABLE `表名` ADD `字段名` 數據類型 [約束] [註釋]; ALTER TABLE `student1` ADD `phone` INT(11) DEFAULT NULL COMMENT '電話';
-- ALTER TABLE `表名` CHANGE `舊字段名` `新字段名` 字段類型 [約束] [註釋]; ALTER TABLE `student1` CHANGE `phone` `tel` VARCHAR(11) NOT NULL DEFAULT '' COMMENT '聯繫方式';
-- ALTER TABLE `表名` MODIFY `字段名` 字段類型 [約束] [註釋]; ALTER TABLE `student1` MODIFY `tel` INT(11) DEFAULT NULL COMMENT '電話';
-- ALTER TABLE `表名` DROP `字段名`; ALTER TABLE `student1` DROP `tel`;
INNODB 5.5及以後默認使用數據結構
MYISAM 5.5以前默認使用
| | MYISAM | INNODB |
| --- | --- | --- |
| 事務支持 | 不支持 | 支持 |
| 數據行鎖定 | 不支持 (表鎖) | 支持 (行鎖) |
| 外鍵約束 | 不支持 | 支持 |
| 全文索引 | 支持 | 不支持 |
| 表空間的大小 | 較小 | 較大,約爲2倍 |數據庫設計
常規使用操做ide
全部的數據庫文件都存在data目錄下,一個目錄對應一個數據庫,本質仍是文件的存儲。
mysql引擎在物理文件上的區別
CHARSET=utf8 character-set-server=utf8
-- 建立年級表 CREATE TABLE IF NOT EXISTS `grade` ( `id` INT(10) NOT NULL AUTO_INCREMENT COMMENT 'id', `name` VARCHAR(100) NOT NULL COMMENT '名稱', PRIMARY KEY (`id`) ) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT '年級'; -- 建立學生表,學生表的grade_id字段引用年級表的id字段 -- 定義外鍵key -- 給這個外鍵添加約束(執行引用(reference)) CREATE TABLE IF NOT EXISTS `student` ( `id` INT(10) NOT NULL AUTO_INCREMENT COMMENT 'id', `name` VARCHAR(100) NOT NULL COMMENT '名稱', `grade_id` INT(10) NOT NULL COMMENT '年級id', PRIMARY KEY (`id`), KEY `FK_grade_id` (`grade_id`), CONSTRAINT `FK_grade_id` FOREIGN KEY (`grade_id`) REFERENCES `grade` (`id`) ) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT '學員';
-- 建立年級表 CREATE TABLE IF NOT EXISTS `grade` ( `id` INT(10) NOT NULL AUTO_INCREMENT COMMENT 'id', `name` VARCHAR(100) NOT NULL COMMENT '名稱', PRIMARY KEY (`id`) ) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT '年級'; -- 建立學員表 CREATE TABLE IF NOT EXISTS `student` ( `id` INT(10) NOT NULL AUTO_INCREMENT COMMENT 'id', `name` VARCHAR(100) NOT NULL COMMENT '名稱', `grade_id` INT(10) NOT NULL COMMENT '年級id', PRIMARY KEY (`id`) ) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT '學員'; -- 添加外鍵 -- ALTER TABLE `表名` ADD CONSTRAINT `FK_grade_id` FOREIGN KEY (`grade_id`) REFERENCES `grade` (`id`); ALTER TABLE `student` ADD CONSTRAINT `約束名` FOREIGN KEY (`做爲外鍵的字段名`) REFERENCES `被引用表名` (`被引用字段名`);
-- insert into 表名(字段1,字段2,字段3) values(值1,值2,值3) -- 主鍵自增,能夠不寫 INSERT INTO `grade`(`name`) VALUES('大一'); -- 插入一條數據,部分字段 INSERT INTO `grade`(`name`) VALUES('大二'); -- 插入一條數據,所有字段 INSERT INTO `grade`(`id`,`name`) VALUES(11,'大三'); -- 插入多條數據時,values後面的值,須要用括號和逗號隔開,如:values(),(),() -- 插入多條數據,部分字段 INSERT INTO `grade`(`name`) VALUES('大四'),('大五'),('大六'); -- 插入多條數據,所有數據 INSERT INTO `grade`(`id`,`name`) VALUES(100,'大旗'),(200,'大壩'),(300,'大酒');
-- update `表名` set 字段名1=值/其它字段值/變量,字段名2=值 where 條件 -- 修改一個字段的值 UPDATE `grade` SET `name`='小一' WHERE `id`=1; -- 修改一個字段的值爲其它字段的值 UPDATE `grade` SET `name`=`id` WHERE `id`=11; -- 修改多個字段的值 UPDATE `grade` SET `id`=20,`name`='小二' WHERE `id`=2;
-- delete from `表名` where 條件 DELETE FROM `grade` WHERE `id`=1;
-- truncate table `表名` TRUNCATE TABLE `grade`;
運算符 | 含義 |
---|---|
= | 等於 |
<> 或 != | 不等於 |
> | 大於 |
< | 小於 |
>= | 大於等於 |
<= | 小於等於 |
between ... and ... | 在某個範圍內 類型是數字時,包括頭和尾 類型是date時,包括頭和尾 類型是datetime時,帶時分秒,包括頭和尾;不帶時分秒,包頭不包尾 |
and | 與 |
or | 或 |
-- 查詢所有字段 SELECT * FROM `grade`; -- 查詢指定字段 SELECT `name` FROM `grade`; -- 別名 AS,字段和表均可以用別名 SELECT `name` AS `名稱` FROM `grade`;
-- 函數 concat(a,b,c) 拼接abc,能夠拼接字符串或字段值 SELECT CONCAT('名稱:',`name`) AS `名稱` FROM `grade`; SELECT CONCAT(`id`,':',`name`) AS `id:名稱` FROM `grade`; -- 關鍵字 distinct 去重 -- 去除select查詢出來的結果中重複的數據,重複的數據只顯示一條 -- 去重通常配合count使用,用來統計數量,由於distinct不能顯示其它不去重的字段 -- 單個字段去重 SELECT DISTINCT `name` FROM `grade`; -- 多個字段去重 SELECT DISTINCT `id`,`name` FROM `grade`; -- 配合count使用,用來統計數量 SELECT COUNT(DISTINCT `name`) AS `count` FROM `grade`;
數據庫中的表達式:文本值、列、null、函數、計算表達式、系統變量......
-- select 表達式 [from 表名] -- 查詢系統版本(函數) SELECT VERSION(); SELECT VERSION(),`name` FROM `grade`; -- 用來計算(計算表達式) SELECT 123*3-12 AS `結果`; SELECT 123*3-12 AS `結果`,`name` FROM `grade`; -- 數字類型的字段計算,其它類型不能夠 SELECT `id`/100 FROM `grade`; -- 查詢自增的默認步長(變量) -- @a用戶變量,@@a系統變量 SELECT @@auto_increment_increment AS '自增步長'; SELECT @@auto_increment_increment AS '自增步長',`name` FROM `grade`;
運算符儘可能使用英文字母
運算符 | 語法 | 描述 |
---|---|---|
and && | a and b a && b | 邏輯與 |
or | ||
not ! | not a ! a | 邏輯非 |
-- 查詢成績95到100分的學員 select `name`,`score` from `result` where `score`>=95 and `score`<=100; select `name`,`score` from `result` where `score` between 95 and 100; -- 查詢成績不是100分的學員 select `name`,`score` from `result` where `score`!=100; select `name`,`score` from `result` where not `score`=100;
運算符 | 語法 | 描述 |
---|---|---|
is null | a is null | 爲null |
is not null | a is not null | 不爲null |
between ... and ... | a between b and c a betwwen 5 and 10 |
在某個範圍內 類型是數字時,包括頭和尾 類型是date時,包括頭和尾 類型是datetime時,帶時分秒,包括頭和尾;不帶時分秒,包頭不包尾 |
like | a like b a like 'b' a like '%b' a like 'b%' a like '%b%' a like '_b' alike 'b' |
a匹配b 通配符,只能用在like中 %表明0到任意個字符,_表明一個字符 |
in | a in (a1,a2,a3...) | a是否在括號中的值中 |
-- 通配符,只能用在like中 %表明0到任意個字符,_表明一個字符 select 'name' like '%me'; select 'name' like 'na%'; select 'name' like '%am%'; select 'name' in ('name','na','me');
操做 | 描述 |
---|---|
inner join | 兩個表都必須匹配 |
left join | 左表爲主表,左表所有,右表沒有補null |
right join | 右表爲主表,右表所有,左表沒有補null |
-- 自鏈接:能夠把一張表當作兩張同樣的表 select a.`id` as '父', b.`id` as '子' from `menu` as a,`menu` as b where a.`id`=b.`pid`
-- 排序 order by -- 升序 asc -- 降序 desc order by `number` desc -- 分頁 limit 起始下標,條數 -- 起始下標從0開始 limit 0,5 -- 第一頁 limit 0,5 -- 第二頁 limit 5,5 -- 第三頁 limit 10,5 -- 第n頁 limit (n-1) * pageSize, pageSize -- n:當前頁 pageSize:條數
group by 分組 having 過濾
-- 子查詢 select id,name from student where grade_id=(select id from grade where name='大二')
-- 數學運算 SELECT ABS(-8); -- 絕對值 SELECT CEILING(9.4); -- 向上取整 SELECT FLOOR(9.4); -- 向下取整 SELECT RAND(); -- 返回一個0到1的隨機數 SELECT SIGN(-10); -- 判斷一個數的符號 -- 字符串函數 SELECT CHAR_LENGTH('走在路上。。。'); -- 返回字符串長度,以字符爲單位 SELECT LENGTH('走在路上。。。'); -- 返回字符串長度,以字節爲單位 SELECT CONCAT('走','在','路','上'); -- 拼接字符串 SELECT INSERT('我在路上',1,2,'你好嗎') ; -- 插入替換,從某個位置開始替換指定長度 SELECT LOWER('Hello'); -- 轉小寫 SELECT UPPER('hello'); -- 轉大寫 SELECT INSTR('helloworld','l'); -- 返回第一次出現子串的索引 SELECT REPLACE('hello','ll','ss'); -- 替換出現的指定字符串 SELECT SUBSTR('helloworld',2,5); -- 返回指定的子字符串(源字符串,截取的位置,截取的長度) -- 時間和日期函數 SELECT CURDATE(); -- 獲取當前日期 SELECT CURTIME(); -- 獲取當前時間 SELECT NOW(); -- 獲取當前日期和時間 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(); -- 查詢版本
函數名稱 | 描述 |
---|---|
count() | 計數 |
sum() | 求和 |
avg() | 平均值 |
max() | 最大值 |
min() | 最小值 |
...... |
-- 聚合函數 SELECT COUNT(`name`) FROM student; -- count(字段),會忽略全部的null值,字段是主鍵時,效率最高 SELECT COUNT(*) FROM student; -- count(*),不會忽略null值,本質是計算行數 SELECT COUNT(1) FROM student; -- count(1),不會忽略null值,本質是計算行數
-- 測試MD5加密 CREATE TABLE `testmd5`( `id` INT(4) NOT NULL, `name` VARCHAR(100) NOT NULL, `pwd` VARCHAR(50) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci; -- 明文加密 INSERT INTO `testmd5` VALUES(1,'zhangs','123456'),(2,'lis','123456'),(3,'wangw','123456'); -- MD5加密 INSERT INTO `testmd5` VALUES(4,'zhaol',MD5('123456')),(5,'maq',MD5('123456')); -- 校驗密碼 SELECT * FROM `testmd5` WHERE `name`='zhaol' AND `pwd`=MD5('123456');
-- 事務 /* mysql默認開啓事務自動提交 set autocommit=0; -- 關閉 set autocommit=1; -- 開啓(默認) */ -- 手動處理事務 SET autocommit=0; -- 關閉自動提交 -- 事務開啓 START TRANSACTION -- 標記一個事務的開始,從這以後的SQL都在同一個事務內 INSERT xx; INSERT xx; -- 提交 commit COMMIT; -- 回滾 rollback ROLLBACK; -- 事務結束 SET autocommit=1; -- 開啓自動提交 -- 瞭解便可 SAVEPOINT 保存點 -- 設置一個事務的保存點 ROLLBACK TO SAVEPOINT 保存點 -- 回滾到保存點 RELEASE SAVEPOINT 保存點 -- 撤銷保存點
-- 轉帳 CREATE DATABASE shop CHARACTER SET utf8 COLLATE utf8_general_ci; USE shop; CREATE TABLE `account`( `id` INT(3) NOT NULL AUTO_INCREMENT, `name` VARCHAR(30) NOT NULL, `money` DECIMAL(9,2) NOT NULL, PRIMARY KEY (`id`) )ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci; INSERT INTO `account`(`name`,`money`) VALUES('A','2000'),('B','10000'); -- 模擬轉帳:事務 SET autocommit=0; -- 關閉自動提交 START TRANSACTION -- 開啓一個事務 UPDATE `account` SET `money`=`money`-500 WHERE `name`='A'; -- A減500 UPDATE `account` SET `money`=`money`+500 WHERE `name`='B'; -- B加500 COMMIT; -- 提交 ROLLBACK; -- 回滾 SET autocommit=1; -- 開啓自動提交 SELECT @@autocommit; -- 查詢自動提交狀態
MySQL官方對索引的定義爲: 索引(Index)是幫助MySQL高效獲取數據的數據結構。提取句子主幹,就能夠獲得索引的本質:索引是數據結構。
-- 顯示全部索引 SHOW INDEX FROM `student`; -- 索引的建立 -- 1.在建立表的時候給字段增長索引 -- 2.建立完畢後,alter增長索引 -- 3.建立完畢後,create增長索引 -- 索引命名:id_表名_字段名 -- 添加索引:create index 索引名 on 表名 (字段名); CREATE INDEX `id_user_name` ON `user` (`name`); -- 15.772 sec -- 增長一個全文索引 索引名(列名) ALTER TABLE `student` ADD FULLTEXT INDEX `studentName` (`studentName`); -- EXPLAIN 分析SQL執行的情況 EXPLAIN SELECT * FROM `student`; -- 非全文索引 EXPLAIN SELECT * FROM `student` WHERE MATCH(`studentName`) AGAINST('劉'); -- 全文索引
CREATE TABLE `user`( `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(50) NOT NULL, `phone` VARCHAR(20) NOT NULL, `pwd` VARCHAR(50) NOT NULL, PRIMARY KEY (`id`) )ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci; -- 插入100萬數據 DELIMITER $$ -- 寫函數以前必需要寫,標誌 CREATE FUNCTION mock_data() RETURNS INT BEGIN DECLARE num INT DEFAULT 1000000; DECLARE i INT DEFAULT 0; WHILE i<num DO -- 插入語句 INSERT INTO `user`(`name`,`phone`,`pwd`) VALUES(CONCAT('用戶',i),CONCAT('18',FLOOR(RAND()*1000000000)),UUID()); SET i=i+1; END WHILE; RETURN i; END; SELECT mock_data(); SELECT COUNT(`id`) FROM `user`;
SELECT * FROM `user` WHERE `name`='用戶9999'; -- 0.748 sec SELECT * FROM `user` WHERE `name`='用戶9999'; -- 0.689 sec SELECT * FROM `user` WHERE `name`='用戶9999'; -- 0.765 sec EXPLAIN SELECT * FROM `user` WHERE `name`='用戶9999'; -- 索引命名:id_表名_字段名 -- 添加索引:create index 索引名 on 表名 (字段名); CREATE INDEX `id_user_name` ON `user` (`name`); -- 15.772 sec SELECT * FROM `user` WHERE `name`='用戶9999'; -- 0.052 sec SHOW INDEX FROM `user`; ALTER TABLE `user` DROP INDEX `id_user_name`;
建立索引前查詢
建立索引後查詢
索引在小數據量的時候,用處不大,可是在大數據量的時候,區別十分明顯。
-- 建立用戶 CREATE USER 用戶名 IDENTIFIED BY '密碼'; CREATE USER qing IDENTIFIED BY '123456'; -- 修改當前用戶密碼 SET PASSWORD=PASSWORD('123456'); -- 修改指定用戶密碼 SET PASSWORD FOR qing=PASSWORD('123456'); -- 重命名 RENAME USER 原用戶名 TO 新用戶名; RENAME USER qing TO qing2; -- 用戶受權 GRANT ALL PRIVILEGES ON 庫.表 TO 用戶名; -- ALL PRIVILEGES 除了給人受權外的其餘權限 -- *.* 全部庫和表 GRANT ALL PRIVILEGES ON *.* TO qing2; -- 查詢權限 SHOW GRANTS FOR qing2; -- 查看指定用戶的權限 -- qing2權限 GRANT ALL PRIVILEGES ON *.* TO 'qing2'@'%' SHOW GRANTS FOR root@'%'; -- root權限 GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION -- 撤銷權限 REVOKE ALL PRIVILEGES ON 庫.表 FROM 用戶名; REVOKE ALL PRIVILEGES ON *.* FROM qing2; -- 刪除用戶 DROP USER qing2;
# 導出表 # mysqldump -h IP -u 用戶名 -p 密碼 數據庫 表名 >盤符/文件名 C:\Users\Administrator>mysqldump -hlocalhost -uroot -p123456 school student >d:/a.sql mysqldump: [Warning] Using a password on the command line interface can be insecure. # 導出多個表 mysqldump -h192.168.10.226 -uroot -p123456 school grade >d:/a.sql # 導出庫 mysqldump -h192.168.10.226 -uroot -p123456 school >d:/a.sql # 導入 # 登陸的狀況下,切換到指定的數據庫 # source 備份文件 source d:/a.sql D:\>mysql -uroot -p123456 mysql: [Warning] Using a password on the command line interface can be insecure. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> use school; Database changed mysql> source d:/a.sql; Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) # 或者 mysql -u用戶名 -p密碼 庫名< 備份文件
原子性:保證每一列不可再分
前提:知足第一範式
每張表只描述一件事情
前提:知足第一範式和第二範式
確保數據表中的每一列數據都和主鍵直接相關,而不能間接相關。
關聯查詢的表不得超過三張表
程序經過數據庫驅動,和數據庫打交道。
CREATE DATABASE jdbcStudy CHARACTER SET utf8 COLLATE utf8_general_ci; USE jdbcStudy; CREATE TABLE users( `id` INT(10) NOT NULL, `name` VARCHAR(100) NOT NULL, `pwd` VARCHAR(100) NOT NULL, `email` VARCHAR(100), `birthday` DATE, PRIMARY KEY (`id`) )ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci; INSERT INTO `users`(`id`,`name`,`pwd`,`email`,`birthday`) VALUES(1,'zhangsf','123456','zhangsf@163.com','1988-03-13'), (2,'zhangwj','123456','zhangwj@163.com','1983-04-03'), (3,'zhangyq','123456','zhangtj@163.com','1989-05-23');
package com.qing.demo01; import java.sql.*; /** * 第一個JDBC程序 */ public class Demo01 { public static void main(String[] args) throws ClassNotFoundException, SQLException { //1.加載驅動 Class.forName("com.mysql.jdbc.Driver"); //2.用戶信息和url //useUnicode=true 支持中文編碼 //characterEncoding=utf8 設定中文字符集編碼爲utf8 //useSSL=true 使用安全的鏈接,若是服務器沒有SSL證書會報錯,使用false String url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false"; String user = "root"; String password = "123456"; //3.鏈接成功,獲取數據庫對象Connection Connection connection = DriverManager.getConnection(url,user,password); //4.建立執行SQL的對象 Statement statement = connection.createStatement(); //5.執行SQL,若是有返回結果,查看返回結果 String sql = "SELECT * FROM users"; ResultSet resultSet = statement.executeQuery(sql); while (resultSet.next()) { System.out.println("id=" + resultSet.getObject("id")); System.out.println("name=" + resultSet.getObject("name")); System.out.println("pwd=" + resultSet.getObject("pwd")); System.out.println("email=" + resultSet.getObject("email")); System.out.println("birthday=" + resultSet.getObject("birthday")); System.out.println("====================================="); } //6.釋放鏈接 resultSet.close(); statement.close(); connection.close(); } }
//驅動管理 //DriverManager.registerDriver(new Driver()); //加載驅動,建議使用,Driver類中的靜態代碼塊就是執行的上面的方法 Class.forName("com.mysql.jdbc.Driver"); //鏈接數據庫 Connection connection = DriverManager.getConnection(url,user,password); //Connection表明數據庫對象,能夠執行數據庫層面的操做 //數據庫設置自動提交 connection.setAutoCommit(false); connection.setAutoCommit(true); //事務提交 connection.commit(); //事務回滾 connection.rollback();
//數據庫鏈接信息 String url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false"; //String url = "jdbc:mysql://主機地址:端口號/數據庫名?參數1&參數2&參數3";
//執行SQL的對象 boolean execute = statement.execute("");//執行任何SQL,但須要判斷,效率最低 ResultSet resultSet = statement.executeQuery();//執行查詢,返回查詢結果集 int i = statement.executeUpdate();//執行更新、插入、刪除,返回受影響的行數
插入示例
刪除示例
更新示例
查詢示例
resultSet.close(); statement.close(); connection.close();//耗資源,用完關掉
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false user=root password=123456
package com.qing.demo02.utils; import java.io.IOException; import java.io.InputStream; import java.sql.*; import java.util.Properties; /** * JDBC工具類 */ public class JdbcUtils { private static String driver = null; private static String url = null; private static String user = null; private static String password = null; static { try { InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties"); Properties properties = new Properties(); properties.load(in); driver = properties.getProperty("driver"); url = properties.getProperty("url"); user = properties.getProperty("user"); password = properties.getProperty("password"); //1.驅動只須要加載一次 Class.forName(driver); } catch (Exception e) { e.printStackTrace(); } } //獲取鏈接 public static Connection getConnection() throws SQLException { return DriverManager.getConnection(url,user,password); } //釋放鏈接資源 public static void release(Connection connection, Statement statement, ResultSet resultSet) { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
package com.qing.demo02; import com.qing.demo02.utils.JdbcUtils; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /** * 測試插入 */ public class TestInsert { public static void main(String[] args) { Connection conn = null; Statement st = null; ResultSet rs = null; try { //獲取鏈接 conn = JdbcUtils.getConnection(); //獲取執行SQL的對象 st = conn.createStatement(); //執行SQL String sql = "insert into `users`(`id`,`name`,`pwd`,`email`,`birthday`) values(4,'zhangyq','123456','zhangyq2163.com','1988-09-09')"; int i = st.executeUpdate(sql); if (i > 0) { System.out.println("插入成功!"); } } catch (SQLException e) { e.printStackTrace(); } finally { //釋放鏈接資源 JdbcUtils.release(conn,st,rs); } } }
package com.qing.demo02; import com.qing.demo02.utils.JdbcUtils; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /** * 測試更新 */ public class TestUpdate { public static void main(String[] args) { Connection conn = null; Statement st = null; ResultSet rs = null; try { //獲取鏈接 conn = JdbcUtils.getConnection(); //獲取執行SQL的對象 st = conn.createStatement(); //執行SQL String sql = "update `users` set `name`='zhangtj' where `id`=3"; int i = st.executeUpdate(sql); if (i > 0) { System.out.println("更新成功!"); } } catch (SQLException e) { e.printStackTrace(); } finally { //釋放鏈接資源 JdbcUtils.release(conn,st,rs); } } }
package com.qing.demo02; import com.qing.demo02.utils.JdbcUtils; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /** * 測試刪除 */ public class TestDelete { public static void main(String[] args) { Connection conn = null; Statement st = null; ResultSet rs = null; try { //獲取鏈接 conn = JdbcUtils.getConnection(); //獲取執行SQL的對象 st = conn.createStatement(); //執行SQL String sql = "delete from `users` where `id`=4"; int i = st.executeUpdate(sql); if (i > 0) { System.out.println("刪除成功!"); } } catch (SQLException e) { e.printStackTrace(); } finally { //釋放鏈接資源 JdbcUtils.release(conn,st,rs); } } }
package com.qing.demo02; import com.qing.demo02.utils.JdbcUtils; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /** * 測試查詢 */ public class TestSelect { public static void main(String[] args) { Connection conn = null; Statement st = null; ResultSet rs = null; try { //獲取鏈接 conn = JdbcUtils.getConnection(); //獲取執行SQL的對象 st = conn.createStatement(); //執行SQL String sql = "select * from `users` where `id`=3"; rs = st.executeQuery(sql); while (rs.next()) { System.out.println(rs.getString("name")); } } catch (SQLException e) { e.printStackTrace(); } finally { //釋放鏈接資源 JdbcUtils.release(conn,st,rs); } } }
//執行SQL String id = "3 or 1=1"; String sql = "select * from `users` where `id`=" + id; rs = st.executeQuery(sql);
String sql = "select * from user_table where username= ' "+userName+" ' and password=' "+password+" '"; --當輸入了上面的用戶名和密碼,上面的SQL語句變成: SELECT * FROM user_table WHERE username= '’or 1 = 1 -- and password='’ """ --分析SQL語句: --條件後面username=」or 1=1 用戶名等於 」 或1=1 那麼這個條件必定會成功; --而後後面加兩個-,這意味着註釋,它將後面的語句註釋,讓他們不起做用,這樣語句永遠都--能正確執行,用戶輕易騙過系統,獲取合法身份。 --這仍是比較溫柔的,若是是執行 SELECT * FROM user_table WHERE username='' ;DROP DATABASE (DB Name) --' and password='' --其後果可想而知… """
由於sql語句是預編譯的,並且語句中使用了佔位符,規定了sql語句的結構。用戶能夠設置"?"的值,可是不能改變sql語句的結構,所以想在sql語句後面加上如「or 1=1」實現sql注入是行不通的。
實際開發中,通常採用PreparedStatement訪問數據庫,它不只能防止sql注入,仍是預編譯的(不用改變一次參數就要從新編譯整個sql語句,效率高),此外,它執行查詢語句獲得的結果集是離線的,鏈接關閉後,仍然能夠訪問結果集。
package com.qing.demo03; import com.qing.demo02.utils.JdbcUtils; import java.sql.*; /** * 測試查詢 */ public class TestSelect { public static void main(String[] args) { Connection conn = null; PreparedStatement st = null; ResultSet rs = null; try { //獲取鏈接 conn = JdbcUtils.getConnection(); //使用?佔位符代替參數 String sql = "select * from `users` where `id`=?"; //預編譯,先寫SQL,而後不執行 st = conn.prepareStatement(sql); //手動給參數賦值 st.setString(1,"3"); //執行 rs = st.executeQuery(); while (rs.next()) { System.out.println(rs.getString("name")); } } catch (SQLException e) { e.printStackTrace(); } finally { //釋放鏈接資源 JdbcUtils.release(conn,st,rs); } } }
package com.qing.demo04; import com.qing.demo02.utils.JdbcUtils; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; /** * 測試事務 */ public class TestTransaction { public static void main(String[] args) { Connection conn = null; PreparedStatement st = null; try { conn = JdbcUtils.getConnection(); //開啓事務:關閉數據庫自動提交,會自動開啓事務 conn.setAutoCommit(false); String sql1 = "update `account` set `money`=`money`-100 where `name`='A'"; st = conn.prepareStatement(sql1); st.executeUpdate(); String sql2 = "update `account` set `money`=`money`+100 where `name`='B'"; st = conn.prepareStatement(sql2); st.executeUpdate(); //提交事務 conn.commit(); System.out.println("成功!"); } catch (SQLException e) { //顯式回滾,也能夠不寫,默認失敗自動回滾 // try { // conn.rollback(); // } catch (SQLException e1) { // e1.printStackTrace(); // } e.printStackTrace(); } finally { JdbcUtils.release(conn,st,null); } } }
使用了這些數據庫鏈接池以後,咱們在項目開發中就不須要編寫鏈接數據庫的代碼了!