一. MySQL密碼的恢復方法之一
如果忘記了MySQL的root密碼,可以用以下方法重新設置:
1. KILL掉系統里的MySQL進程;
killall -TERM mysqld
2. 用以下命令啟動MySQL,以不檢查權限的方式啟動;
safe_mysqld --skip-grant-tables &
3. 然后用空密碼方式使用root用戶登錄 MySQL;
mysql -u root
4. 修改root用戶的密碼;
mysql> update mysql.user set password=PASSWORD('新密碼') where User='root';
mysql> flush privileges;
mysql> quit
重新啟動MySQL,就可以使用新密碼登錄了。
CREATE DATABASE test2
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
多表鏈接
g
創建以下兩張表
select * from emp;
+------+-------+------+---------+------+
| id | name | sal | qq | d_id |
+------+-------+------+---------+------+
| 1 | zorro | 5000 | 123456 | 110 |
| 2 | tom | 3000 | 234567 | 120 |
| 3 | jerry | 4000 | 345678 | 100 |
| 4 | blues | 4500 | 456789 | 110 |
| 5 | shrek | 6000 | 156789 | 100 |
| 6 | seker | 8000 | 256789 | 120 |
| 7 | eric | 6000 | 4567890 | 120 |
| 8 | robin | 5000 | 765432 | 110 |
+------+-------+------+---------+------+
select * from dpt;
+------+--------+
| d_id | d_name |
+------+--------+
| 100 | hr |
| 110 | yw |
| 120 | kf |
+------+--------+
等值聯接或者內部聯接 (沒有條件出現笛卡爾集)(類似于{a,b}{1,2,3})
select id,name,sal,d_name from emp,dpt;
+------+-------+------+--------+
| id | name | sal | d_name |
+------+-------+------+--------+
| 1 | zorro | 5000 | hr |
| 1 | zorro | 5000 | yw |
| 1 | zorro | 5000 | kf |
| 2 | tom | 3000 | hr |
| 2 | tom | 3000 | yw |
| 2 | tom | 3000 | kf |
| 3 | jerry | 4000 | hr |
| 3 | jerry | 4000 | yw |
| 3 | jerry | 4000 | kf |
| 4 | blues | 4500 | hr |
| 4 | blues | 4500 | yw |
| 4 | blues | 4500 | kf |
| 5 | shrek | 6000 | hr |
| 5 | shrek | 6000 | yw |
| 5 | shrek | 6000 | kf |
| 6 | seker | 8000 | hr |
| 6 | seker | 8000 | yw |
| 6 | seker | 8000 | kf |
| 7 | eric | 6000 | hr |
| 7 | eric | 6000 | yw |
| 7 | eric | 6000 | kf |
| 8 | robin | 5000 | hr |
| 8 | robin | 5000 | yw |
| 8 | robin | 5000 | kf |
+------+-------+------+--------+
去掉笛卡爾集
select id,name,sal,d_name from emp,dpt where emp.d_id=dpt.d_id;
+------+-------+------+--------+
| id | name | sal | d_name |
+------+-------+------+--------+
| 1 | zorro | 5000 | yw |
| 2 | tom | 3000 | kf |
| 3 | jerry | 4000 | hr |
| 4 | blues | 4500 | yw |
| 5 | shrek | 6000 | hr |
| 6 | seker | 8000 | kf |
| 7 | eric | 6000 | kf |
| 8 | robin | 5000 | yw |
+------+-------+------+--------+
另外一種寫法
select id,name,sal,d_name from emp inner join dpt on emp.d_id=dpt.d_id;
+------+-------+------+--------+
| id | name | sal | d_name |
+------+-------+------+--------+
| 1 | zorro | 5000 | yw |
| 2 | tom | 3000 | kf |
| 3 | jerry | 4000 | hr |
| 4 | blues | 4500 | yw |
| 5 | shrek | 6000 | hr |
| 6 | seker | 8000 | kf |
| 7 | eric | 6000 | kf |
| 8 | robin | 5000 | yw |
+------+-------+------+--------+
自連接
select * from emp;
+------+-------+------+---------+------+
| id | name | sal | qq | d_id |
+------+-------+------+---------+------+
| 1 | zorro | 5000 | 123456 | 110 |
| 2 | tom | 3000 | 234567 | 120 |
| 3 | jerry | 4000 | 345678 | 100 |
| 4 | blues | 4500 | 456789 | 110 |
| 5 | shrek | 6000 | 156789 | 100 |
| 6 | seker | 8000 | 256789 | 120 |
| 7 | eric | 6000 | 4567890 | 120 |
| 8 | robin | 5000 | 765432 | 110 |
+------+-------+------+---------+------+
查詢每個部門最高薪水的員工
select emp.id,emp.name,a.msal,emp.d_id from emp,(select d_id,max(sal) as msal from emp group by d_id) a where emp.d_id=a.d_id and emp.sal=a.msal;
顯示部門名稱
select emp.id,emp.name,a.msal,emp.d_id,a.d_name from emp,(select emp.d_id,d_name,max(sal) as msal from emp,dpt where emp.d_id=dpt.d_id group by emp.d_id) a where emp.d_id=a.d_id and emp.sal=a.msal;
+------+-------+------+------+--------+
| id | name | msal | d_id | d_name |
+------+-------+------+------+--------+
| 1 | zorro | 5000 | 110 | yw |
| 5 | shrek | 6000 | 100 | hr |
| 6 | seker | 8000 | 120 | kf |
| 8 | robin | 5000 | 110 | yw |
+------+-------+------+------+--------+
外部聯接
在dpt表里添加以行 130 cw 做一下實驗
select * from dpt;
+------+--------+
| d_id | d_name |
+------+--------+
| 100 | hr |
| 110 | yw |
| 120 | kf |
| 130 | cw |
+------+--------+
select id,name,sal,d_name from emp right outer join dpt on emp.d_id=dpt.d_id;
+------+-------+------+--------+
| id | name | sal | d_name |
+------+-------+------+--------+
| 3 | jerry | 4000 | hr |
| 5 | shrek | 6000 | hr |
| 1 | zorro | 5000 | yw |
| 4 | blues | 4500 | yw |
| 8 | robin | 5000 | yw |
| 2 | tom | 3000 | kf |
| 6 | seker | 8000 | kf |
| 7 | eric | 6000 | kf |
+------+-------+------+--------+
select id,name,sal,d_name from emp left outer join dpt on emp.d_id=dpt.d_id;
+------+-------+------+--------+
| id | name | sal | d_name |
+------+-------+------+--------+
| 3 | jerry | 4000 | hr |
| 5 | shrek | 6000 | hr |
| 1 | zorro | 5000 | yw |
| 4 | blues | 4500 | yw |
| 8 | robin | 5000 | yw |
| 2 | tom | 3000 | kf |
| 6 | seker | 8000 | kf |
| 7 | eric | 6000 | kf |
| NULL | NULL | NULL | cw |
+------+-------+------+--------+
搜索存儲引擎
mysql視圖
單表視圖
create view new_emp as select * from emp;
create view new_emp1 as select uid,name,money from emp;
修改視圖=修改源表
多表視圖
create table tt1(id int,name char(10),did int);
create table tt2(did int,dname char(10));
多表查詢
select tt1.id,tt1.name,tt2.did,tt2.dname from tt1,tt2 where tt1.did=tt2.did;
create view kk as select tt1.id,tt1.name,tt2.did,tt2.dname from tt1,tt2 where tt1.did=tt2.did;
create view kkk as select tt1.name,tt2.dname from tt1,tt2 where tt1.did=tt2.did;
視圖對引擎沒有要求,可以修改刪除,不可以添加,只有表結構*.frm文件。視圖相當于存儲那條 創建視圖的語句
存儲引擎是什么?
MySQL中的數據用各種不同的技術存儲在文件(或者內存)中。這些技術中的每一種技術都使用不同的存儲機制、索引技巧、鎖定水平并且最終提供廣泛的不同的功能和能力。通過選擇不同的技術,你能夠獲得額外的速度或者功能,從而改善你的應用的整體功能。
例如,如果你在研究大量的臨時數據,你也許需要使用內存存儲引擎。內存存儲引擎能夠在內存中存儲所有的表格數據
MYISAM引擎:有 .frm表結構,.MYD數據,*.MYI索引數據
MRG_MYISAM
MEMORY(內存引擎)只有表結構 .frm,數據存儲在內存中,重啟會丟失。用于把數據存于內存中,快速讀寫運算。
創建MYISAM引擎表:不支持外鍵、行級鎖、事物,如:update一行數據時,整個表都會鎖定。
InnoDB引擎:支持事物、外鍵、行級鎖,粒度更小,修改一行時,就鎖定一行。
事物:把語句分到一組,一組語句同時執行或者同時不執行,然后提交或者事物回滾commit||rollback。
mysql> create table t4(id int,name char(10)) engine=myisam;
創建MEMORY引擎表
mysql> create table t3(id int,name char(10)) engine=memory;
創建MRG_MYISAM引擎表
create table t10(id int,name char(10)) engine=myisam;
create table t20(id int,name char(10)) engine=myisam;
create table t30(id int,name char(10)) union=(t10,t20)engine=mrg_myisam;
create table t40(id int,name char(10)) union=(t10,t20) INSERT_METHOD=first|no|last engine=mrg_myisam;
MyISAM
MyISAM是默認存儲引擎。它基于更老的ISAM代碼,但有很多有用的擴展。(注意MySQL 5.1不支持ISAM)。
每個MyISAM在磁盤上存儲成三個文件。第一個文件的名字以表的名字開始,擴展名指出文件類型。.frm文件存儲表定義。數據文件的擴展名 為.MYD (MYData)。索引文件的擴展名是.MYI (MYIndex)。 MyISAM文件的格式是平臺無關的,這意味著你可以將數據和索引文件從一個intel服務器上拷貝到一臺PowerPC或者Sun SPARC上,而不會出任何問題。
主要區別:
MyISAM是非事務安全型的,而InnoDB是事務安全型的。
MyISAM鎖的粒度是表級,而InnoDB支持行級鎖定。
MyISAM支持全文類型索引,而InnoDB不支持全文索引。
MyISAM相對簡單,所以在效率上要優于InnoDB,小型應用可以考慮使用MyISAM。
MyISAM表是保存成文件的形式,在跨平臺的數據轉移中使用MyISAM存儲會省去不少的麻煩。
InnoDB表比MyISAM表更安全,可以在保證數據不會丟失的情況下,切換非事務表到事務表(alter table tablename type=innodb)。
mysql的配置文件:/etc/my.cnf /usr/my.cnf /usr/local/mysql/my.cnf
獨占表空間和共享表空間
innodb_file_per_table=1 獨立
innodb_file_per_table=0 共享
1.外鍵索引
外鍵myisam引擎不支持只能用innodb引擎
create table dpmnt(id int not null,name char(10) not null,primary key(id)) type = INNODB;
desc dpmnt;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | char(10) | NO | | NULL | |
+-------+----------+------+-----+---------+-------+
建立外鍵
create table emp (id int not null, name char(10) not null,fk_dpmnt int not null ,primary key(id),index (fk_dpmnt),foreign key (fk_dpmnt) references dpmnt(id)) type=innodb;
desc emp;
+----------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+----------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | char(10) | NO | | NULL | |
| fk_dpmnt | int(11) | NO | MUL | NULL | |
+----------+----------+------+-----+---------+-------+
insert into dpmnt values(1,hr);
insert into dpmnt values(2,'yw');
insert into emp values(10,'zhb',3);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (db
.emp
, CONSTRAINT emp_ibfk_1
FOREIGN KEY (fk_dpmnt
) REFERENCES dpmnt
(id
))
fk_dpmnt字段的數據必須得是dpmnt表里有的不然報錯...
即使表存在外鍵約束,MySQL還允許我們刪除表,并且不會產生錯誤。這是刪除外鍵的方法。
alter table emp drop foreign key emp_ibfk_1;
刪除外鍵
添加外鍵
alter table emp add CONSTRAINT fk_1 foreign key(did) references dpt(did);
create table dpt(did int primary key,dname char(10))
create table emp(id int,name char(10),did int,foreign key (did) references dpt(did) );
insert into emp values(1,'robin',10);
insert into emp values(2,'zorro',30);
alter table emp drop foreign key emp_ibfk_1;
alter table emp add foreign key (did) references dpt(did);
alter table emp add CONSTRAINT emp_dpt_fk foreign key (did) references dpt(did);
級聯刪除,級聯更新
mysql> create table emp(id int,name char(10),did int,foreign key (did) references dpt(did) ON DELETE CASCADE on update cascade);
2.表級鎖和行級鎖
行級鎖:對正在被修改的行進行鎖定,其它的用戶可以訪問被鎖定的行以外的行。表級鎖:鎖定整個表,限其他用戶對表的訪問
3.事物的支持
事務處理是一種機制,用來管理成批執行的sql語句,以保證數據庫不包含不完整的操作結果,他們或者為整體執行完成,或者完全不執行(如果沒有錯誤發生整組語句提交到數據庫,如果發生錯誤,則進行回退,以保證數據的安全)
事務 transaction 指定一組sql語句
回退 rollback 撤銷指定的sql語句(只能回退insert delete update語句)
提交 commit 提交未存儲的sql語句
保留點 savepoint 事務處理中設置的臨時占位符 你可以對它發布回退(與整個事務回退不同)
create table t11(id int,name char(10)) engine=innodb;
start transaction;
delete from t11;
select * from t11;
Empty set (0.00 sec)
rollback;
select * from t11;
+------+-------+
| id | name |
+------+-------+
| 1 | zorro |
| 2 | zorro |
| 2 | zorro |
+------+-------+
提交
start transaction;
insert into t11 values(3,'tom');
select * from t11;
commit;
保留點
start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t11 values(5,'haha');
Query OK, 1 row affected (0.01 sec)
mysql> savepoint insert1;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from t11;
+------+-------+
| id | name |
+------+-------+
| 1 | tom |
| 2 | jerry |
| 3 | zorro |
| 4 | seker |
| 5 | haha |
+------+-------+
5 rows in set (0.00 sec)
mysql> delete from t11 where id=4;
Query OK, 1 row affected (0.00 sec)
mysql> savepoint delete1;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from t11;
+------+-------+
| id | name |
+------+-------+
| 1 | tom |
| 2 | jerry |
| 3 | zorro |
| 5 | haha |
+------+-------+
4 rows in set (0.00 sec)
mysql> delete from t11 where id=1;
Query OK, 1 row affected (0.00 sec)
mysql> savepoint delete2;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from t11;
+------+-------+
| id | name |
+------+-------+
| 2 | jerry |
| 3 | zorro |
| 5 | haha |
+------+-------+
3 rows in set (0.01 sec)
mysql> rollback to delete1;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from t11;
+------+-------+
| id | name |
+------+-------+
| 1 | tom |
| 2 | jerry |
| 3 | zorro |
| 5 | haha |
+------+-------+
4 rows in set (0.00 sec)
create table t5 (id int,name char(10)) union=(t3,t4) INSERT_METHOD=first engine=mrg_myisam;
create table dpt(did int primary key,dname char(10)) engine=innodb;
create table emp(id int primary key,name char(30),did int,foreign key(did) references dpt(did)) engine=innodb;
alter table emp drop foreign key emp_ibfk_1;
刪除外鍵
添加外鍵
alter table emp add CONSTRAINT fk_1 foreign key(did) references dpt(did);
用戶權限
創建用戶并設置密碼
create user zorro identified by '123';
create user zorro@localhost identified by '123';
create user zorro@'%' identified by '123';
查詢
select user from mysql.user;
修改用戶名
rename user zorro to robin;
select user from mysql.user;
刪除
drop user robin;
修改用戶密碼
set password for 'zorro'@'%'= password('123'); password()函數加密
set password = password('123');修改當前用戶
root密碼丟失
重置root口令
shell> mysqld_safe --skip-grant-tables --skip-networking &
mysql>update mysql.user set password=password('123') where host='localhost' and user='root'
查詢用戶權限
show grants for zorro \G
*************************** 1. row ***************************
Grants for zorro@%: GRANT USAGE ON . TO 'zorro'@'%' IDENTIFIED BY PASSWORD '*23AE809DDACAF96AF0FD78ED04B6A265E05AA257'
USAGE表示沒有任何權限
連接測試
mysql -u zorro -p123
ERROR 1045 (28000): Access denied for user 'zorro'@'localhost' (using password: YES)
失敗
權限
MySQL存取控制包含2個階段:
階段1:服務器檢查是否允許你連接。
階段2:假定你能連接,服務器檢查你發出的每個請求。看你是否有足夠的權限實施它。例如,如果你從數據庫表中選擇(select)行或從數據庫刪除表,服務器確定你對表有SELECT權限或對數據庫有DROP權限。
授權grant
命令格式
grant 權限 on 庫.表 to 用戶@主機 [密碼]
//遠程所有權
GRANT ALL PRIVILEGES ON . TO 'root'@'%' IDENTIFIED BY '111111' WITH GRANT OPTION;
grant select on hr.* to zorro@'localhost';
show grants for zorro \G
*************************** 1. row ***************************
Grants for zorro@%: GRANT USAGE ON . TO 'zorro'@'%' IDENTIFIED BY PASSWORD '*23AE809DDACAF96AF0FD78ED04B6A265E05AA257'
*************************** 2. row ***************************
Grants for zorro@%: GRANT SELECT ON hr
.* TO 'zorro'@'%'
移除權限revoke
命令格式
revoke 權限 on 庫.表 from 用戶@主機;
revoke select on hr.* from zorro'localhost';
遠程主機授權
grant all on hr.* to zorro@'192.168.1.129' identified by '123';
grant all on hr.* to zorro@'%' identified by '123';
grant和revoke可在幾個層次上控制訪問權限
整個服務器 grant all 和 revoke all
整個數據庫 on databases.*
grant select,insert on hr.* to robin@'localhost' identified by '123';
特定的表 on database.table;
grant select,insert on hr.tt to tom@'localhost' identified by '123';
其他方法:
mysql> INSERT INTO user (Host,User,Password) VALUES('localhost','dummy',password());
mysql> FLUSH PRIVILEGES;
練習:
1.創建帳號zorro 允許從本機和任意位置登錄
create user zorro@'%';
create user zorro@'%' identified by '123';
create user zorro@'localhost' identified by '123';
2.修改zorro名字為king
rename user zorro@'%' to king@'%';
rename user zorro@'localhost' to king@'localhost';
3.設置king用戶的密碼位123
set password for king@'localhost'=password('123');
set password for king@'%'=password('123');
4.以king帳號登錄到mysql數據庫 設置密碼位abc
set password=password('123');
重置root密碼
1.停止mysql(pkill mysql)
2./usr/local/mysql/bin/mysqld_safe --user=mysql --skip-grant-tables &
3.update mysql.user set password=password('123') where user='root' and host='localhost';
4.停止mysql (pkill mysql)
5./usr/local/mysql/bin/mysqld_safe --user=mysql &
6.正常登錄
跳過授權
vim /etc/my.cnf
[mysqld]
skip-grant-tables
用戶信息mysql.user存儲所有用戶信息,權限信息分布不同的表中
abc1 abc2 abc3 abc4
grant all on . to abc1@localhost identified by '123';
abc1 權限保存在 mysql.user
grant all on db.* to abc2@localhost identified by '123';
abc2 權限保存在 mysql.db
grant all on db.test20 to abc3@localhost identified by '123';
abc3 權限保存在 mysql.tables_priv
grant select(name) on db.test20 to abc4@localhost identified by '123';
abc4 權限保存在 mysql.columns_priv
create user robin; 添加帳號
set password for robin=password('123'); 設置密碼
create user zorro identified by '123'; 創建帳號同時設置密碼
rename user zorro to newzorro; 修改帳號名字
drop user newzorro; 刪除帳號
set password=password('123'); 設置當前帳號密碼
root密碼丟失
實驗環境
刪除數據目錄
重新
管理密碼為空(直接登錄)
重置root密碼
/usr/local/mysql/bin/mysqld_safe --user=mysql --skip-grant-tables &
--skip-grant-tables 跳過授權表不進行驗證.
mysql> update mysql.user set password=password('123') where user='root' and host='localhost'; 更新密碼
pkill mysql
service mysqldd restart
授權
1.是否能連接數據庫 localhost %
2.驗證帳號密碼
1.能否連接數據庫
第一部分 本地來源
第二部分 遠程來源
create user zorro@'%' identified by '123';
select user,password,host from mysql.user;
create user zorro@'localhost' identified by '123';
2,授權
grant all on db.* to zorro@'localhost'; db庫所有表具有所有權限
grant select,insert on db.t5 to robin@'localhost' identified by '123'; 授權同時創建帳號
回收權限revoke all on db.* from zorro@'localhost';
. mysql.user
db.* mysql.db
db.t5 mysql.tables_priv
db.t5(id) mysql.columns_priv
grant all on . to abc1@localhost identified by '123';
abc1 權限保存在 mysql.user
grant all on db.* to abc2@localhost identified by '123';
abc2 權限保存在 mysql.db
grant all on db.test20 to abc3@localhost identified by '123';
abc3 權限保存在 mysql.tables_priv
grant select(name) on db.test20 to abc4@localhost identified by '123';
abc4 權限保存在 mysql.columns_priv
筆記補充:
數據遷移:1,跨平臺 linux到 Windows --- myisam引擎 2 跨不同數據庫
InnoDB引擎不支持 MRG_MYISAM, *.ibd有兩種表空間:共享表空間和獨立表空間
共享表空間:把整個數據庫中的所有innodb引擎的表對應數據都放到一個文件中 ibddata1。獨立磁盤,日志分離。但是每個表不可以獨立備份(物理備份),不能空間壓縮(有些空間被釋放但是不可以再利用)。
獨立表空間:有獨立空間,每個表獨立的表空間文件。獨立備份,空間收縮
vim /etc/my.cnf
[mysqld] 給進程mysql
innodb-file-per-table = 0 共享 1獨立()默認
以前的不變