mysql資料庫學習
文章目錄
資料庫基礎語法
資料庫密碼修改
#第一種 mysqladmin -uroot -pxxx password 'xxx' #第二種 mysql -uroot -p mysql>set passowrd for root@'localhost'=password('xxxxx'); #第三種 mysql -uroot -p mysql>alter user root@'localhost' identified by 'xxxxxx'; #修改密碼策略 mysql -uroot -p mysql>set global validate_password_policy=0; #修改密碼策略等級 #0或LOW為只驗證密碼長度 #1或MEDIUM驗證長度 數字 大小寫和特殊字元 #2或STRONG驗證長度 數字 大小寫和特殊字元 字典檔案 mysql>set global validate_password_length=6; #修改密碼最短長度為6 #檢視資料庫變數 mysql -uroot -p mysql> show variables like '%password%'; #檢索出含有password的變數 +---------------------------------------+-------+ | Variable_name | Value | +---------------------------------------+-------+ | default_password_lifetime | 0 | | disconnect_on_expired_password | ON | | log_builtin_as_identified_by_password | OFF | | mysql_native_password_proxy_users | OFF | | old_passwords | 0 | | report_password | | | sha256_password_proxy_users | OFF | | validate_password_check_user_name | OFF | | validate_password_dictionary_file | | | validate_password_length | 6 | | validate_password_mixed_case_count | 1 | | validate_password_number_count | 1 | | validate_password_policy | LOW | | validate_password_special_char_count | 1 | +---------------------------------------+-------+ #mysql密碼忘了 修改 vim /etc/my.cnf ======================= [mysqld] skip_grant_tables #登入無需驗證密碼 #validate_password_policy=0 #validate_password_length=6 密碼策略相關的要註釋 ===================================== systemctl restart mysqld #重啟服務 mysql #直接進入 直接更新mysql root使用者密碼 >update mysql.user set authentication_string=password('xxxxx') ->where user='root' and host='localhost'; >flush privileges; #重新整理 >exit #退出 vim /etc/my.cnf #修改配置檔案回來 #重新登入 #也可以 mysql flush privileges; #先重新整理許可權 否則會告訴在skip_grant_tables中沒法修改 alter user root@'localhost' identified by 'xxxxxx'; exit #修改配置檔案回來
三類語句
- DDL 建立語句 (create、drop、alter)
- DML 操作資料語句(insert、delete、update、select、truncate)
- DCL 資料控制語句(grant、revoke)
- DTL 資料事務語言 (commit、rollback、savepoint)
建立表
create table tablename(
column_name1 column_type1 constraints,
column_name2 column_type2 constraints
)
- column_name1 列名
- column_type1 列型別(varchar、date、int…)
- constraints 約束條件
查詢表結構
use test; #進入test表
create table emp(ename varchar(10), hiredate date, sal decimal(10,2),deptno int(2));
desc emp; #查看錶emp結構
drop table emp; #刪除表emp
重命名錶名
語法
-
alter table tablename rename newtablename
-
舉例
alter table emp rename emp2; #修改表名 alter table emp2 rename emp; #修改表名 alter table test.emp rename mydb.empcopy; #複製到另一個數據庫中
修改表字段定義
語法
- alter table tablename modify[column] column_definition[first|after col_name]
after | first為mysql在基礎SQL上的擴充套件 不是每個資料庫語法都支援
- 舉例
alter table emp modify ename varchar(20); #修改表emp的ename列的資料型別為varchar(20)
增加表字段
語法
-
alter table tablename add[column] column_definition[first|after col_name]
-
舉例
alter table emp add column age int(3); #新增age列資料型別為int(3)
刪除表字段
語法
-
alter table tablename drop[column] col_name
-
舉例
alter table emp drop column age; #刪除age列
修改欄位定義(包括欄位名)
語法
-
alter table tablename change[column] old_col_name column_definition[first | after col_name]
-
舉例
alter table emp change age agel int(4); #將age列修改為agel列名int(4)資料型別
- change 和modify都可以修改表的定義,但是modify修改不了欄位名,change可以,不過change需要寫兩次欄位名(
廢話不寫兩個怎麼從舊值改新值)
插入記錄
語法
-
insert into tablename(field1,field2,field3…) values(value1,value2,…)
-
舉例
insert into emp(ename,hiredate,sal,deptno)values('zzx1','2000-01-01','2000',1);
insert into emp values('lisa','2003-02-01','3000',2,22),('zs','2001-05-06','4000',3,21);
更新記錄
語法
-
update tablename set field1=value1,field2=value2,…[where condition]
-
舉例
update emp set sal = 4000 where ename = 'lisa'; #修改記錄ename為lisa的sal為4000
刪除記錄
語法
-
delete from tablename[where condition]
-
舉例
delete from emp where ename='dony'; #從emp表中刪除ename為dony的記錄
查詢記錄
語法
-
select * from tablename[where condition] order by fieldn [desc|asc] limit offset_start,row_count
-
處理方式
-
排序
select name,uid from user where id >= 10 and id <= 20 order by uid asc
-
分組
select shell from user group by shell
-
過濾查詢結果
select name,uid from user where id <= 15 having name='zhangsan’
-
聚集函式使用
-
限制查詢結果顯示的行數
-
-
舉例
select * from emp;
select ename,hiredate,sal,deptno from emp;
select * from emp where ename='lisa' and sal=4000; #條件查詢
select * from emp order by sal desc; #根據sal降序排列輸出
select * from emp order by sal asc; #根據sal增序排列輸出
select * from emp order by sal desc limmit 3; #根據sal降序排列輸出3行(從0開始)
select * from emp order by sal desc limit 1,3; #根據sal降序排列輸出1~3行
聚合語法
- select [field1,field2,…] fun_name from tablename where [where_contition] group by field1,field2… with rollup having [where_contition]
聚合語法舉例
select count(1) from emp; #統計emp表記錄數賦予新的欄位名
+----------+
| count(1) |
+----------+
| 4 |
+----------+
select deptno,count(1) from emp group by deptno; #根據deptno分類
+--------+----------+
| deptno | count(1) |
+--------+----------+
| 1 | 2 | #deptno為1的有2個
| 2 | 1 |
| 3 | 1 |
+--------+----------+
select deptno,count(1) from emp group by deptno with rollup; #在上面的基礎上統計總人數
+--------+----------+
| deptno | count(1) |
+--------+----------+
| 1 | 2 |
| 2 | 1 |
| 3 | 1 |
| NULL | 4 |
+--------+----------+
select deptno, count(1) from emp group by deptno having count(1) > 1; #欄位count(1)大於1 #的值
+--------+----------+
| deptno | count(1) |
+--------+----------+
| 1 | 2 |
+--------+----------+
表連線
-
內連線 匹配兩張表中互相匹配的記錄
-
外連線 選出其他不匹配的記錄
- 左連線 包含所有的左邊表中的記錄甚至是右邊表中沒有和它匹配的記錄
- 右連線 包含所有的右邊表中的記錄甚至是左邊表中沒有和它匹配的記錄
-
舉例
select * from emp;
+--------+------------+---------+--------+
| ename | hiredate | sal | deptno |
+--------+------------+---------+--------+
| zzx | 2000-01-01 | 2000.00 | 1 |
| lisa | 2003-02-01 | 4000.00 | 2 |
| bjguan | 2004-05-02 | 5000.00 | 1 |
| dony | 2005-02-05 | 2000.00 | 4 |
+--------+------------+---------+--------+
select * from dept;
+--------+----------+
| deptno | deptname |
+--------+----------+
| 1 | tech |
| 2 | sale |
| 3 | hr |
+--------+----------+
#內連線
select ename,deptname from emp,dept where emp.deptno=dept.deptno; #內連線查詢兩張表中
+--------+----------+ #deptno相同的記錄的ename deptname
| ename | deptname |
+--------+----------+
| zzx1 | tech |
| lisa | sale |
| bjguan | tech |
+--------+----------+
#左連線
select ename,deptname from emp left join dept on emp.deptno=dept.deptno;
+--------+----------+
| ename | deptname |
+--------+----------+
| zzx | tech |
| bjguan | tech |
| lisa | sale |
| dony | NULL |
+--------+----------+
#顯示emp中的欄位 如果dept中沒有 就NULL替代
#右連線顯示右邊表 左邊表NULL替代
select ename,deptname from right join dept on emp.deptno=dept.deptno;
+--------+----------+
| ename | deptname |
+--------+----------+
| zzx | tech |
| lisa | sale |
| bjguan | tech |
| NULL | hr |
+--------+----------+
索引
- 建立表時 index(column_name)
create table tea4(
id char(6) not null,
name varchar(6) not null,
age int(3) not null,
gender enum('boy','girl') default 'boy',
index(id),index(name) #新增普通索引
);
desc tea4;
+--------+--------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+--------------------+------+-----+---------+-------+
| id | char(6) | YES | MUL | NULL | | #kEY為MUL 索引
| name | varchar(5) | YES | MUL | NULL | |
| age | int(3) | YES | | NULL | |
| gender | enum('boy','girl') | YES | | boy | |
+--------+--------------------+------+-----+---------+-------+
- 表建立後
create index age on tea4(age); #為tea4的age欄位建立age索引
Query OK, 0 rows affected (0.01 sec)
desc tea4; #查看錶結構
+--------+--------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+--------------------+------+-----+---------+-------+
| id | char(6) | YES | MUL | NULL | |
| name | varchar(5) | YES | MUL | NULL | |
| age | int(3) | YES | MUL | NULL | | #age欄位有索引了
| gender | enum('boy','girl') | YES | | boy | |
+--------+--------------------+------+-----+---------+-------+
#刪除age索引
drop index age on tea4; #不需要欄位名了
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
show index from tea4\G; #列表形式檢視索引
*************************** 1. row ***************************
Table: tea4
Non_unique: 1
Key_name: id
Seq_in_index: 1
Column_name: id
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE #預設索引為B樹 還有B+樹和hash可以設定
Comment:
Index_comment:
*************************** 2. row ***************************
Table: tea4
Non_unique: 1
Key_name: name
Seq_in_index: 1
Column_name: name
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
2 rows in set (0.00 sec)
主鍵
- 表建立時
create table tea4 (
id int(4) primary key, #單個主鍵 屬性方式新增
name varchar(8)
);
create table tea4(
id int(4),
name varchar(8),
primary key (id) #單個主鍵 函式形式
);
create table tea4(
id int(4),
name varchar(8)
primary key(id, name) #函式形式 複合主鍵
);
- 表建立後
alter table tea4 drop primary key; #刪除tea4主鍵 alter drop
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
alter table tea4 modify id int(4) primary key; #給id新增主鍵 change 也行
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
alter table tea4 drop primary key;
alter table tea4 add primary key(id, name);
desc tea4;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id | int(4) | NO | PRI | NULL | | #成功設定主鍵
| name | varchar(8) | NO | PRI | NULL | | #成功設定主鍵
+-------+------------+------+-----+---------+-------+
欄位的auto_increment屬性 只能一個欄位且是主鍵才能使用,複合主鍵也只能一個欄位使用
外來鍵
-
語法
alter table 庫名.表名 add constraint 外來鍵名 foreign key(需加外來鍵的欄位名) references 關聯表名(關聯欄位)
alter table gz add constraint gz_id_wj foreign key(gz_id) references yg(yg_id) on 操作名 cascade
#建立員工表 主鍵為員工id 自增 資料庫引擎為innodb
create table yg(
yg_id int primary key auto_increment,
name char(16)
)engine=innodb; #設定資料庫引擎為innodb 還有MyISAM
在MySQL 5.1之前的版本中,預設的搜尋引擎是MyISAM,從MySQL 5.5之後的版本中,預設的搜尋引擎變更為InnoDB
-
MyISAM
它是基於傳統的ISAM型別,ISAM是Indexed Sequential Access Method (有索引的 順序訪問方法) 的縮寫,它是儲存記錄和檔案的標準方法.與其他儲存引擎比較,MyISAM具有檢查和修復表格的大多數工具. MyISAM表格可以被壓縮,而且它們支援全文搜尋.它們不是事務安全的,而且也不支援外來鍵。如果事物回滾將造成不完全回滾,不具有原子性。如果執行大量的SELECT,MyISAM是更好的選擇。
MyISAM儲存引擎的特點是:表級鎖、不支援事務和全文索引,適合一些CMS內容管理系統作為後臺資料庫使用,但是使用大併發、重負荷生產系統上,表鎖結構的特性就顯得力不從心;
-
InnoDB
這種型別是事務安全的.它與BDB型別具有相同的特性,它們還支援外來鍵.InnoDB表格速度很快.具有比BDB還豐富的特性,因此如果需要一個事務安全的儲存引擎,建議使用它.如果你的資料執行大量的INSERT或UPDATE,出於效能方面的考慮,應該使用InnoDB表,
對於支援事物的InnoDB型別的表,影響速度的主要原因是AUTOCOMMIT預設設定是開啟的,而且程式沒有顯式呼叫BEGIN開始事務,導致每插入一條都自動Commit,嚴重影響了速度。可以在執行sql前呼叫begin,多條sql形成一個事物(即使autocommit開啟也可以),將大大提高效能。
InnoDB儲存引擎的特點是:行級鎖、事務安全(ACID相容)、支援外來鍵、不支援FULLTEXT型別的索引(5.6.4以後版本開始支援FULLTEXT型別的索引)。InnoDB儲存引擎提供了具有提交、回滾和崩潰恢復能力的事務安全儲存引擎。InnoDB是為處理巨大量時擁有最大效能而設計的。它的CPU效率可能是任何其他基於磁碟的關係資料庫引擎所不能匹敵的。
-
注意
InnoDB表的行鎖也不是絕對的,假如在執行一個SQL語句時MySQL不能確定要掃描的範圍,InnoDB表同樣會鎖全表,例如
update table set num=1 where name like "a%"
兩種型別最主要的差別就是InnoDB支援事務處理與外來鍵和行級鎖。而MyISAM不支援。所以MyISAM往往就容易被人認為只適合在小專案中使用。
#建立工資表
create table gz(
gz_id int,
name char(16),
gz float(7,2),
foreign key(gz_id) references yg(yg_id) #建立外來鍵
on update cascade on delete cascade #同步更新update、同步刪除delete
)engine=innodb;
#插入員工資料
insert into yg(name) values('Jerry'),('Tom');
insert into gz(gz_id,name,gz) values(1,'Jerry',12000),(2,'Tom',8000);
select * from gz;
+-------+-------+----------+
| gz_id | name | gz |
+-------+-------+----------+
| 1 | Jerry | 12000.00 |
| 2 | Tom | 8000.00 |
+-------+-------+----------+
#修改員工表中的id 檢視同步更新功能
update yg set yg_id=1234 where name=Jerry;
select * from gz;
+-------+-------+----------+
| gz_id | name | gz |
+-------+-------+----------+
| 1234 | Jerry | 12000.00 | #工資表中的id也被修改了
| 2 | Tom | 8000.00 |
+-------+-------+----------+
#刪除Jerry 檢視同步刪除功能
delete from yg where name='Jerry';
select * from gz;
+-------+------+---------+
| gz_id | name | gz |
+-------+------+---------+
| 2 | Tom | 8000.00 | #工資表中Jerry行也沒了
+-------+------+---------+
#這裡因為工資表沒有設定主鍵 所以有幾個問題
insert into gz(gz_id,name,gz) values(2,'Jorry',10000.0);
insert into gz(gz_id,name,gz) values(2,'Jorry',10000.0);
insert into gz(gz_id,name,gz) values(null,'Jorry',5000.0);
select * from gz;
+-------+-------+----------+
| gz_id | name | gz |
+-------+-------+----------+
| 2 | Tom | 8000.00 |
| 2 | Jorry | 10000.00 |
| 2 | Jorry | 10000.00 |
| NULL | Jorry | 10000.00 | #多條重複記錄 還有空值 不合理
+-------+-------+----------+
#設定主鍵
delete from gz where name='Jorry'; #先刪除不合規的記錄
Query OK, 3 rows affected (0.00 sec)
alter table gz modify gz_id int not null primary key; #非空 主鍵
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
insert into gz(gz_id,name,gz) values(null,'Jorry',5000);
ERROR 1048 (23000): Column 'gz_id' cannot be null #空值無法插入
insert into gz(gz_id,name,gz) values(2,'Jorry',1090);
ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY' #主鍵不能重複
#刪除外來鍵
show create table gz\G; #檢視工資表的外來鍵名字
Table: gz
Create Table: CREATE TABLE `gz` (
`gz_id` int(11) NOT NULL,
`name` char(16) DEFAULT NULL,
`gz` float(7,2) DEFAULT NULL,
PRIMARY KEY (`gz_id`),
CONSTRAINT `gz_ibfk_1` FOREIGN KEY (`gz_id`) REFERENCES `yg` (`yg_id`) ON DELETE CASCADE ON UPDATE CASCADE #外來鍵名為'gz_ibfk_1'
) ENGINE=InnoDB DEFAULT CHARSET=latin1
alter table gz drop foreign key 'gz_ibfk_1'; #刪除外來鍵
檔案匯入匯出
secure_file_priv引數
- 預設為NULL ,表示mysqld不允許匯入匯出
- secure_file_priv的值為/tmp/時,表示只允許在/tmp/目錄下匯入匯出
- secure_file_priv的值沒有具體值時,表示不限制mysqld的匯入匯出
匯入匯出命令語法
-
匯入
load data infile ‘檔案路徑’ into table 表名 fields terminated by ‘欄位分隔符’ lines terminated by ‘記錄分隔符’;
-
匯出
select * from 表名 into outfile ‘匯出檔案路徑’ fields terminated by ‘欄位分隔符’ lines terminated by '記錄分隔符’
mkdir /myload
chown mysql /myload #修改檔案所有者 防止許可權問題
vim /etc/my.cnf
=========================
[mysqld]
secure_file_priv='/myload'
==============================
systemctl restart mysqld
mysql -uroot -p
show variables like 'secure_file_priv';
+------------------+----------+
| Variable_name | Value |
+------------------+----------+
| secure_file_priv | /myload/ | #有了
+------------------+----------+
#拿/etc/password做測試
cp /etc/passwd /myload #將要匯入的檔案放入允許匯入匯出的/myload/目錄下
mysql -uroot -p
create database db3;
create table db3.user( #符合/etc/passwd的內容 七列
name char(50),
password char(1),
uid int,
gid int,
comment char(150),
homedir char(50),
shell char(50)
);
#匯入命令
load data infile '/myload/passwd' into table db3.user fields terminated by ':' lines terminated by '\n';
#匯入檔案為/myload/passwd 欄位分隔為: 記錄分隔為換行符
#匯出命令
select * from db3.user into outfile '/myload/user1.txt' fields terminated by '||' lines terminated by '\n';