1.解決中文亂碼問題
1.1查看MySQL數(shù)據(jù)庫編碼
在命令行中輸入:SHOW VARIABLES LIKE 'CHAR%'; 回車可看到如下內(nèi)容:
1.2編碼解釋
- character_set_client: mysql使用該編碼來解讀客戶端發(fā)送過來的數(shù)據(jù),例如該編碼為utf惜颇,那么如果客戶端發(fā)送過來的數(shù)據(jù)不是utf慨菱,就會出現(xiàn)亂碼屿储。
- character_set_results:mysql會把數(shù)據(jù)轉(zhuǎn)換成該編碼后,再發(fā)送給客戶端紊浩,例如該編碼為utf,那么如果客戶端不使用utf來解讀,那么就會出現(xiàn)亂碼宏怔,其它編碼只要支持中文即可。
除了這兩個編碼格式外我們還需要考慮一個工具(用于編寫sql語句的工具)的編碼格式畴椰,即控制臺(用命令行寫sql語句)或者用于寫sql語句的可視化工具臊诊,為什么要用”或”呢,因為二者就是一體斜脂,修改一個即一起修改了兩個的編碼格式抓艳。下面1.3節(jié)我在分析亂碼原因后會告訴你如何保持client、results以及控制臺與可視化工具這四者編碼格式的一致帚戳,以解決中文亂碼問題玷或。
1.3控制臺亂碼問題
windows系統(tǒng)中:
- 插入或修改時出現(xiàn)亂碼:因為控制臺默認使用gbk儡首,而character_set_client不是gbk的原因。
- 查詢出的數(shù)據(jù)為亂碼偏友,因為character_set_results不是gbk而控制臺默認使用gbk蔬胯。
- 解決方法:通過在命令行中輸入代碼set character_set_client=gbk;和set character_set_results=gbk;來設置編碼。
通過將client和results的編碼格式改成gbk后使得它們二者和控制臺的編碼格式一致位他,這樣便可以實現(xiàn)中文亂碼問題解決了編碼的問題氛濒。
注意:通過上述方式我們將client、results鹅髓、控制臺這三者編碼方式設置一致舞竿,設置編碼只對當前連接有效,當退出mysql后再次登陸mysql時又回到utf了窿冯。解決方法:找到my.ini配置文件骗奖,在配置文件中設置set default_character=gbk即可。
或是保持client和results的編碼格式繼續(xù)為utf-8醒串,然后將控制臺默認的的gbk編碼方式改為utf-8格式重归,這種方法我沒試過,畢竟我用的是mac厦凤,估計也是在控制臺的my.ini配置文件中進行設置鼻吮。
而對于我的mac系統(tǒng):由于mac的控制臺默認編碼不是gbk(我也不知道m(xù)ac系統(tǒng)默認是什么編碼格式),我為什么知道它的默認編碼不是gbk呢较鼓,因為我修改了client和results的編碼格式為gbk后椎木,在控制臺中輸入中文仍顯示亂碼,所以我才知道它的默認編碼格式不是gbk博烂。針對mac用戶我也提供如下兩種方法:
1.在命令行中輸入set character_set_client=gbk;和set character_set_results=gbk;來設置client和results的編碼格式為gbk香椎,然后再修改控制臺的編碼格式為gbk。那么如何修改控制臺的編碼格式呢?mac的控制臺編碼格式是與編寫sql語句的可視化工具連在一起的禽篱,修改可視化工具的編碼格式便可以修改控制臺的編碼格式畜伐。而我用的可視化工具為MySQL Workbench,所以我在MySQL Workbench中創(chuàng)建數(shù)據(jù)庫時指定創(chuàng)建數(shù)據(jù)庫的編碼格式為gbk并在創(chuàng)建表時也設置表的編碼格式為gbk,這樣便保持了它們編碼格式的一致躺率,成功解決中文亂碼問題玛界。
2.保持client和results的編碼格式繼續(xù)為utf-8,然后修改可視化工具創(chuàng)建數(shù)據(jù)庫時的編碼格式為utf-8并在創(chuàng)建表時也指定表的編碼格式為utf-8,通過這種方式也保持了它們?nèi)呔幋a格式的一致,成功解決編碼亂碼的問題悼吱。
2.備份數(shù)據(jù)庫與恢復數(shù)據(jù)庫
2.1備份數(shù)據(jù)庫
備份就是將數(shù)據(jù)庫導出為sql腳本慎框。在命令行中輸入:mysqldump -u用戶名 -p密碼 數(shù)據(jù)庫名>導出文件路徑
注意:1.末尾不要打分號。2.執(zhí)行此語句前應該先退出mysql客戶端后添。3.導出的內(nèi)容不包括創(chuàng)建數(shù)據(jù)庫的語句只包含數(shù)據(jù)庫里面的內(nèi)容笨枯。
2.2恢復數(shù)據(jù)庫
就是將導出的sql腳本插入到數(shù)據(jù)庫中。有如下兩種實現(xiàn)方式:
- 第一種方式:1.登錄mysql:mysql -u用戶名 -p密碼。2.創(chuàng)建數(shù)據(jù)庫:create database 數(shù)據(jù)庫名馅精。3.輸入命令:mysql -uroot -p密碼 數(shù)據(jù)庫名<備份的數(shù)據(jù)路徑并回車严嗜。
- 第二種方式:1.刪除數(shù)據(jù)庫:drop database 數(shù)據(jù)庫名。2.重新創(chuàng)建數(shù)據(jù)庫:create database 數(shù)據(jù)庫名洲敢。3.切換到數(shù)據(jù)庫:use 數(shù)據(jù)庫名阻问。4.輸入命令:source sql腳本路徑并回車。
3.約束
約束是添加在列上用來約束列的沦疾。
3.1主鍵約束(primary key)
特點:1.非空称近。2.唯一。3.可被引用哮塞。當表的某一列被指定為主鍵后刨秆,該列的值就不能為空,也不能有重復值出現(xiàn)忆畅。
- 創(chuàng)建表時指定主鍵的兩種方式:
1.create table emp(
empno int primary key,
ename varchar(50)
);
2.create table emp(
empno int,
ename varchar(50),
primary key(empno)
);
- 修改表時指定主鍵的方式:
alter table emp
and primary key;
- 修改表時刪除主鍵的方式:
alter table emp
drop primary key;
3.2主鍵自增長(auto_increment)
create table student(
id int primary key auto_increment,
name varchar(50)
);
注意:auto_increment必須添加在int類型后衡未,指定主鍵自增長后,插入數(shù)據(jù)時便可以給該主鍵設置null值家凯。
限制:主鍵自增長在群集環(huán)境下不好使缓醋,所以大部分情況下我們使用UUID來作主鍵。
3.3非空約束(not null)
因為某些列不能設置為null值绊诲,所以可以對列添加非空約束送粱。
create table student(
id int primary key auto_increment,
name varchar(50) not null
);
3.4唯一約束(unique)
create table student(
id int primary key auto_increment,
name varchar(50) not null unique
);
3.5概念模型
在java中表現(xiàn)為對象模型:在java中是domain。例如:User掂之、Student抗俄。
在數(shù)據(jù)庫中表現(xiàn)為關系模型:在數(shù)據(jù)庫中表現(xiàn)為 表。
當我們要完成一個軟件系統(tǒng)時世舰,需要把系統(tǒng)中的實體抽取出來动雹,形成概念模型。例如部門跟压、員工都是系統(tǒng)中的實體胰蝠。概念模型中的實體最終會成為java中的類、數(shù)據(jù)庫中的表震蒋。實體之間還存在著關系茸塞,關系有三種:1對多:例如員工和部門的關系
1對1:例如老公和老婆的關系
多對1:例如老師與學生的關系
對象模型:可以雙向關聯(lián),而且引用的是對象喷好,而不是一個主鍵翔横。
關系模型:只能多方引用一方读跷,而且引用的是主鍵梗搅,而不是一整行記錄。
3.6外鍵約束
- 1.外鍵必須是另一表(或自己表)的主鍵的值(即外鍵要引用主鍵的值)。
- 2.外鍵可以為空无切。
- 3.外鍵可重復荡短。
- 4.一張表可以有多個外鍵。
create table dept(
deptno int primary key auto_increment,
name varchar(50)
);
create table emp(
empno int primary key auto_increment,
name varchar(50),
dno int,
constraint fk_emp_dept foreign key(dno) references dept (deptno)
);
最后一行就是給emp表添加外鍵約束哆键,添加外鍵約束后掘托,在emp表中對dno列進行賦值時就應該考慮外鍵約束的三個條件了。(上圖創(chuàng)建的兩張表演示的也是數(shù)據(jù)庫中1對多的關系籍嘹。)
3.7數(shù)據(jù)庫中1對1的關系
create table husband (
hid int primary key auto_increment,
hname varchar(50)
);
insert into husband values(null,’劉備’);
insert into husband values(null,’張飛’);
insert into husband values(null,’關羽’);
create table wife(
wid int primary key auto_increment,
wname varchar(50),
constraint fk_wife_husband foreign key (wid) references husband(hid)
);
特點:外鍵引用自身表的主鍵闪盔。
3.8數(shù)據(jù)庫中多對多的關系
在表中建立多對多關系需要使用中間表(關聯(lián)表),即需要三張表辱士,在中間表中使用兩個外鍵泪掀,分別引用其它兩個表的主鍵。
create table student(
sid int primary key auto_increment,
sname varchar(50)
);
create table teacher (
tid int primary key auto_increment,
name varchar(50)
);
create table stu_tea(
sid int,
tid int,
constraint fk_student foreign key(sid) references student(sid),
constraint fk_teacher foreign key(tid) references student(tid)
);
insert into student values(null,’劉德華’);
insert into student values(null,’梁朝偉);
insert into student values(null,’黃日華’);
insert into student values(null,’苗僑偉’);
insert into student values(null,’湯鎮(zhèn)業(yè)’);
insert into teacher values(null,’崔老師’);
insert into teacher values(null,’劉老師’);
insert into teacher values(null,’石老師’);
insert into stu_tea values(1,1);
insert into stu_tea values(2,1);
insert into stu_tea values(3,1);
insert into stu_tea values(4,1);
insert into stu_tea values(5,1);
insert into stu_tea values(1,2);
insert into stu_tea values(2,2);
insert into stu_tea values(3,2);
insert into stu_tea values(3,3);
insert into stu_tea values(4,3);
insert into stu_tea values(5,3);
select * from stu_tea;
4.多表查詢
4.1分類
- 合并結果集(了解)
- 連接查詢
- 子查詢
4.2合并結果集
要求兩個結果集(注意這里強調(diào)的是結果集颂碘,而不是兩張表)的列數(shù)异赫、列類型完全相同。關鍵字union:去除重復行;關鍵字union all:不去除重復行头岔。
create table ab(
a int,
b,varchar(50)
);
insert into ab values(1,’1’);
insert into ab values(2,’2’);
insert into ab values(3,’3’);
create table cd(
c int,
d varchar(50)
);
insert into cd values (3,’3’);
insert into cd values (5,’5’);
insert into cd values (5,’5’);
合并操作為:
select * from ab
union (all)
select * from cd;
4.3連接查詢
特點:外連接有一主一次塔拳。
左外連接左表為主,那么左表中所有的記錄無論滿足不滿足條件峡竣,都打印出來靠抑。不滿足條件的值用null填補。語法為:select * from emp left outer join dept on emp.deptno=dept.deptno;
右外連接右表為主适掰,那么右表中所有的記錄無論滿足不滿足條件孕荠,都打印出來。不滿足條件的值用null填補攻谁。語法為::select * from amp right outer join dept on emp.deptno=dept.deptno;
全外連接:左右表都為主稚伍,左表和右表中的記錄都要打印出來,不滿足條件的值用null填補戚宦。使用union將左外連接和右外連接的結果集合并起來就是全外連接个曙。
4.4子查詢
子查詢通俗來講,就是查詢中有查詢受楼。
見例子:
/*查詢本公司工資最高的員工的詳細信息*/
select *
from amp
where sal=max(sal);
此種寫法錯誤垦搬,因為where條件中不能有聚合函數(shù)。所以想到要用子查詢艳汽。
思路:首先查出最高工資:select max(sal) from amp;然后查詢該工資的員工:select * from amp where sal=剛剛的查詢結果猴贰。所以合并起來為:select * from amp where sal=(select max(sal) from amp);
4.4.1子查詢能出現(xiàn)的位置
- where后作為條件(上述例子)
- from后作為二次查詢(下面例子)select e.empno,e.ename from (select * from amp where deptno=30) as e where 條件;
4.4.2子查詢的結果集
單行單列:select * from 表1 where 列1 [=、>河狐、<米绕、>=瑟捣、<=、!=] (select 列 from 表2 where 條件);
多行單列::select * from 表1 where 列1 [=栅干、>迈套、<、>=碱鳞、<=桑李、!=] [any、all窿给、in](select 列 from 表2 where 條件;
單行多列:select * from 表1 where (列1贵白,列2) in (select 列1,列2 from 表2 where 條件);
多行多列:該結果集用在from后作為二次查詢崩泡。select * from 表1,(select …) 別名 where 條件;