安裝與配置
- 安裝xampp(為了使用mysql數(shù)據(jù)庫(kù)):點(diǎn)擊MySQL的start以啟動(dòng)mysql
- 配置環(huán)境變量(將安裝目錄下的bin目錄加入path)
- dos窗口輸入mysql -u root -p 回車(chē),表示以root用戶運(yùn)行朋腋,密碼為空
- 輸入\s;查看使用的字符編碼
- 現(xiàn)在是latinl撼嗓,然后我們修改/bin目錄下的my.ini,搜索utf8(注意這里沒(méi)有-)建峭,將其改為如下所示
使用
注意:sql語(yǔ)句不區(qū)分大小寫(xiě)
在windows的dos窗口下:
- show databases:查看使用的數(shù)據(jù)庫(kù)(分號(hào)表示一條語(yǔ)句)
- creat database db_student_sms; 創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)囤耳,名字叫db_student_sms
- show create database db_student_sms;查看編碼格式
- use db_student_sms;切換到我們要使用的數(shù)據(jù)庫(kù)捏顺,然后可以發(fā)現(xiàn)前面方括號(hào)內(nèi)的None變成了我們的數(shù)據(jù)庫(kù)名
- 查看數(shù)據(jù)庫(kù)中的表(數(shù)據(jù)庫(kù)是由表組成的):show tables;當(dāng)然,我們目前的表是空的椿浓,所以顯示empty set(意為空集合)
可以使用desc+表名太援,查看該表的信息
-
dos中退出mysql的方法
- quit
- exit
- ctrl+c
navicat對(duì)數(shù)據(jù)庫(kù)的簡(jiǎn)單操作
- 首先要已經(jīng)在xampp中啟動(dòng)mysql
- 打開(kāi)navicat,文件/新建連接/【連接名隨便取扳碍,主機(jī)名提岔、端口、用戶名皆默認(rèn)笋敞,密碼為空】/連接測(cè)試
- 如果顯示連接成功碱蒙,就表明mysql已經(jīng)可用,點(diǎn)擊確定即可
- 回到主界面后,在左邊已經(jīng)建立的連接名上右擊赛惩、新建數(shù)據(jù)庫(kù)哀墓,輸入數(shù)據(jù)庫(kù)的名稱,字符集我們選擇utf8(倒數(shù)第二個(gè)就可以了)喷兼,排序規(guī)則選第一個(gè)篮绰,點(diǎn)擊確定后我們就可以看到左邊的連接下多了一項(xiàng)我們剛才建立的數(shù)據(jù)庫(kù)
新建數(shù)據(jù)庫(kù)
字符編碼選擇
排序規(guī)則選擇
我們新建的數(shù)據(jù)庫(kù)
- 雙擊我們新建的數(shù)據(jù)庫(kù),右擊“表”季惯、新建表吠各,然后界面如下
- 新建字段
7. 保存該表
數(shù)據(jù)類(lèi)型與約束
當(dāng)我們定義一個(gè)表的時(shí)候,有兩個(gè)東西需要我們?nèi)タ紤]勉抓。
- 是數(shù)據(jù)的類(lèi)型
- 是其他的約束
通過(guò)類(lèi)型和約束可以保證數(shù)據(jù)的完整性
數(shù)據(jù)類(lèi)型
常用的數(shù)據(jù)類(lèi)型
- 整數(shù):int走孽、tinyint(通常用0來(lái)表示false,非0表示true)
- 小數(shù):decimal琳状、double。decimal表示浮點(diǎn)型盒齿,decimal(5,2)表示共存5位念逞,小數(shù)占2位
- 字符串:char(字符串長(zhǎng)度不可變)、varchar(字符串長(zhǎng)度可變边翁,通常使用這個(gè))翎承。
- 日期時(shí)間:date、time符匾、datetime
通常叨咖,數(shù)據(jù)庫(kù)中通常不存儲(chǔ)媒體文件(視頻、音頻啊胶、圖片等)甸各,媒體文件常存儲(chǔ)在物理磁盤(pán)上,數(shù)據(jù)庫(kù)中存儲(chǔ)的是他們的路徑
約束
- 主鍵:priamry key:物理存儲(chǔ)的順序
- 非空:not null:此字段不允許填寫(xiě)空值
- 唯一:unique:此字段的值不允許重復(fù)
- 默認(rèn):default:當(dāng)不填寫(xiě)此值時(shí)會(huì)使用默認(rèn)值
- 外鍵:foreign key:如果一張表中的某個(gè)非主鍵字段是另一張表中的主鍵焰坪,那么就把該字段稱為外鍵趣倾。對(duì)關(guān)系字符進(jìn)行約束,當(dāng)為關(guān)系字段填寫(xiě)值時(shí)某饰,會(huì)到關(guān)聯(lián)的表中查詢此值是否存在儒恋,如果存儲(chǔ)則填寫(xiě)成功,是否失敗并拋出異常
- 說(shuō)明:雖然外鍵約束可以保證數(shù)據(jù)的有效性黔漂,但是在進(jìn)行數(shù)據(jù)的CRUD(增加诫尽、修改、刪除炬守、查詢)時(shí)牧嫉,都會(huì)降低數(shù)據(jù)庫(kù)的性能,所以不推薦使用劳较。那么數(shù)據(jù)的有效性如何保證呢?答:可以在邏輯層進(jìn)行控制
用sql語(yǔ)句操縱數(shù)據(jù)庫(kù)
點(diǎn)擊navicat中的查詢、新建查詢排苍,即可在navicat中使用sql語(yǔ)句操縱數(shù)據(jù)庫(kù)(當(dāng)然纳胧,也可以新建一個(gè)后綴為sql的文件,然后把語(yǔ)句寫(xiě)在文件中郊丛,直接把文件拿來(lái)執(zhí)行)
注意:
- sql中用
--
表示注釋?zhuān)琫g:--這里是注釋?zhuān)?/li> - 判斷是否相等用"="號(hào),而不是"=="
- sql中null與任何值(包括自己)做相等比較,都是false坊夫,為此,sql使用了is nulll 和 is not null來(lái)對(duì)null進(jìn)行判斷
數(shù)據(jù)庫(kù)及數(shù)據(jù)表的相關(guān)語(yǔ)句
create databases + 數(shù)據(jù)庫(kù)名:創(chuàng)建數(shù)據(jù)庫(kù)
查看創(chuàng)建數(shù)據(jù)庫(kù)的語(yǔ)句:show create database撤卢,可以查看數(shù)據(jù)庫(kù)的編碼
使用制定編碼創(chuàng)建數(shù)據(jù)庫(kù):create database + 數(shù)據(jù)庫(kù)名 + charset=utf8;
刪除數(shù)據(jù)庫(kù):drop database + 數(shù)據(jù)庫(kù)名; 注意:如果要?jiǎng)h除的數(shù)據(jù)庫(kù)名稱比較特殊环凿,比如包含
-
號(hào),用``將其包起來(lái)查看當(dāng)前所有的數(shù)據(jù)庫(kù):show databases;
使用數(shù)據(jù)庫(kù):use + 數(shù)據(jù)庫(kù)名;
查看當(dāng)前數(shù)據(jù)庫(kù)中所有的表:show tables;
創(chuàng)建數(shù)據(jù)表:create table + 數(shù)據(jù)表名字 (字段 類(lèi)型 約束[放吩,字段 類(lèi)型 約束])智听。eg:
create table xxxx(id int, name varchar(30))
,表示創(chuàng)建一個(gè)叫做xxxx的數(shù)據(jù)表渡紫,其中有一個(gè)id字段到推,該字段為int類(lèi)型,還有個(gè)name字段惕澎,類(lèi)型為varchar莉测,且長(zhǎng)度最長(zhǎng)為30字符desc+表的名字:查看表的結(jié)構(gòu)
新建數(shù)據(jù)表時(shí)給表加約束:
create table xxxx(id int unsigned primary key not full auto_increment, name varchar(30))
,表明我們使用id作為主鍵唧喉,int類(lèi)型捣卤,只能為正,且其不能為空八孝,自增注意:1董朝、一條sql語(yǔ)句可以換行寫(xiě);2干跛、創(chuàng)建表時(shí)益涧,如果含有多個(gè)字段,最后一個(gè)字段后面不能加逗號(hào)驯鳖;3闲询、約束的順序沒(méi)有要求
數(shù)據(jù)的插入:insert into 數(shù)據(jù)表的名字 values(字段1的數(shù)據(jù),字段2的數(shù)據(jù)浅辙,....)
查看表中的所有數(shù)據(jù):select * from + 表的名字;
-
數(shù)據(jù)表的增刪查改:
- 修改表-修改表的名稱:rename table 舊的表名 to 新的表名
- 修改表-添加字段:alter table + 表的名字 add 列名 類(lèi)型
- 修改表-修改約束:alter table 表的名字 modify 列名 類(lèi)型及約束
- 修改表-修改列的名字(及約束和類(lèi)型):alter table 表名change 原名 新名 類(lèi)型及約束
- 修改表-刪除列:alter table 表的名字 drop 列的名字
- ps:數(shù)據(jù)庫(kù)盡量少刪多加
- 刪除表:drop table 表名
- 查看表的創(chuàng)建語(yǔ)句:show ceate table 表的名字
- 查看當(dāng)前使用數(shù)據(jù)庫(kù)的名字:select database();
數(shù)據(jù)表中數(shù)據(jù)的增刪查改
基本查詢
- 給一個(gè)表用insert into 表的名字 values(要插入的數(shù)據(jù)) 插入數(shù)據(jù)時(shí)扭弧,如果不專(zhuān)門(mén)指定,默認(rèn)全部插入记舆,即要插入的數(shù)據(jù)的項(xiàng)數(shù)鸽捻,必須和字段數(shù)對(duì)應(yīng),類(lèi)型也必須對(duì)應(yīng)。要插入的數(shù)據(jù)中御蒲,除非特別字段衣赶,否則也可以寫(xiě)null和default
- 只插入部分字段:insert into 表的名字 (字段1的名字,字段2的名字) values(字段1的值厚满, 字段2的值)府瞄,注意,此種方法碘箍,不寫(xiě)的字段必須是允許為空的
- 同時(shí)插入多個(gè)數(shù)據(jù)項(xiàng):insert into 表的名字 (字段1的名字遵馆,字段2的名字...) values(字段1的值,字段2的值...),(字段1的值丰榴,字段2的值)货邓;使用此法,在插入全部字段時(shí)(即不用指定字段四濒,一次性插入所有字段的數(shù)據(jù))也可以换况,eg:insert into 表的名字 values(字段1的數(shù)據(jù),字段2的數(shù)據(jù)盗蟆,字段3的數(shù)據(jù)...)
- 數(shù)據(jù)的修改:update 表的名字 set 列1的名字=要設(shè)置的列1的值复隆,列2的名字=要設(shè)置的列2的值
- 條件語(yǔ)句:where 條件,eg:
update students set gender = 1 where id=3;
將id為3的記錄中的性別設(shè)置為1(如果不寫(xiě)where語(yǔ)句姆涩,將把gender字段的所有值都修改為1) - *代表所有的東西,eg:
select * from students惭每,
表示查看students表中的所有數(shù)據(jù) - 查詢指定字段:select 字段1骨饿,字段2 from 表的名字 (也可以加判斷語(yǔ)句);
- 使用name為列或者表指定別名(as 可省)以增強(qiáng)可讀性:eg,
select name as "姓名", gender as “性別” from students;
- 物理刪除某些記錄:delete from 表名 where 條件;
- 物理刪除整個(gè)數(shù)據(jù)表:delete from 表名;
- 邏輯刪除:使用一個(gè)字段來(lái)表示這條信息已經(jīng)不再使用了
- 給表起別名:
select t1.name, t1.age from students as t1;
表示查詢students表中的name字段和age字段台腥。注意一旦給表起了別名宏赘,前面就不能再使用原來(lái)的名字了 - 對(duì)查詢的結(jié)果去重(即:如果查詢出來(lái)的結(jié)果有相同的項(xiàng),只顯示一次):
select distinct gender from students
,查詢students表中的所有性別(如果students中男女都有的話黎侈,查詢結(jié)果只會(huì)顯示兩個(gè):男 女)
條件查詢
與where結(jié)合使用察署,eg:xxxx where age > 18;
比較運(yùn)算符
- 比較運(yùn)算符:>、<峻汉、=贴汪、>=、<=休吠、!=或者<>
邏輯運(yùn)算符
優(yōu)先級(jí):not > and > all
- and扳埂,eg:
select * from students where age>18 and age <28
- or 和and的用法一樣
- not:
select * from students where not (age>18 and gender =2);
表示年齡不在18以上,且性別也不為2的
模糊查詢
注意:模糊查詢的效率較低
-
like的使用:查詢姓名中以“小”開(kāi)頭的名字:
select name from students where name like "小%";
- %:替換一個(gè)或多個(gè)
- _:替換一個(gè)
-
rlike:正則表達(dá)式
- eg:查詢姓名以“周”開(kāi)頭的瘤礁,以“倫”結(jié)尾的,
select name from students where name rlike "^周.*倫$";
- eg:查詢姓名以“周”開(kāi)頭的瘤礁,以“倫”結(jié)尾的,
范圍查詢
對(duì)于非連續(xù):
- in:eg:查詢年齡為18或20或23的阳懂。
select name,age from students where age in (18, 20, 23);
- not in
對(duì)于連續(xù):
- between...and...:eg:查詢id在2-7的:
select name,id from hero where id between 2 and 7;
- not between...and...:注意,not between是一個(gè)整體,而不是說(shuō)對(duì)后面的between...and取反岩调,即:不能對(duì)between...and加括號(hào)巷燥,比如以下兩句,效果一樣号枕,但是語(yǔ)法不同
select * from students where age not between 18 and 22;
select * from students where not age between 18 and 22;
排序
-
order by 字段缰揪,加在語(yǔ)句的最后即可,eg:
select name,id,age from hero where id BETWEEN 2 and 6 order by age desc;
按年齡降序排列所查找的數(shù)據(jù)- asc:升序堕澄,默認(rèn)
- dex:降序
order by 多個(gè)字段:如果第一個(gè)字段相同邀跃,按照第二個(gè)字段,依次類(lèi)推蛙紫。格式:
查詢語(yǔ)句 order by 第一個(gè)字段, 第二個(gè)字段 desc
拍屑,按照第一個(gè)字段的升序排列,如果第一個(gè)字段相同坑傅,按照第二個(gè)字段的降序排列
聚合函數(shù)
什么叫函數(shù)僵驰,就是帶括號(hào)的那種,只能得出一個(gè)結(jié)論
-
計(jì)算總數(shù):sum
-
select count(*) as 男性人數(shù) from students where gender=1
:統(tǒng)計(jì)有多少gender=1的人唁毒,為什么是對(duì)*加函數(shù)蒜茴?因?yàn)?是查詢出來(lái)的數(shù)據(jù),而那正是我們所要統(tǒng)計(jì)的浆西,此處粉私,我們還對(duì)其起了別名
-
最大值:max,注意:對(duì)于max近零、min和avg诺核,必須要跟統(tǒng)計(jì)的字段名或表達(dá)式為參數(shù),不能以*為參數(shù)久信,eg:
select avg(age) 平均年齡 from xxxx
最小值:min
平均值:avg
四舍五入:round(avg(age), 2):求年齡的平均值窖杀,并保留兩位小數(shù)
分組
主要是結(jié)合聚合函數(shù)使用
- group by:eg:
select xxx from students group by yyy
,按照yyy字段分組裙士,注意入客,此時(shí),xxx必須是能夠標(biāo)記每個(gè)組的東西腿椎,比如:如果是按照性別分組桌硫,xxx就不能為姓名。分組的特點(diǎn):先將原來(lái)的數(shù)據(jù)分組啃炸,然后再根據(jù)前面的條件中組中取數(shù)據(jù)鞍泉,實(shí)例:select is_delete 刪除標(biāo)識(shí),count(*) 數(shù)量 from hero group by is_delete;
,按照是否被邏輯刪除分組肮帐,并分別統(tǒng)計(jì)其數(shù)量咖驮,即:此時(shí)的聚合函數(shù)是對(duì)分組里面的計(jì)算個(gè)數(shù)边器,而不是原表 - group_concat:案例;
select is_delete 刪除標(biāo)識(shí),count(*) 數(shù)量,GROUP_CONCAT(name, "-", age) 年齡 from hero group by is_delete;
按照是否被邏輯刪除分組,計(jì)算每個(gè)組的人數(shù)托修,并列出每個(gè)組里面的姓名和年齡忘巧,并將姓名和年齡用-拼接。ps:group-concat基本上是寫(xiě)什么有什么
- having:對(duì)分組進(jìn)行過(guò)濾睦刃,eg:
select gender, group_concat(name) from students group by gender having count(*) > 2
:查詢每種性別中的人數(shù)多于2個(gè)的信息
ps:where和having的區(qū)別:
- where是對(duì)原始表中的數(shù)據(jù)進(jìn)行判斷砚嘴,而having是對(duì)查出來(lái)的結(jié)果進(jìn)行條件判斷`
分頁(yè)
limit (start) count
注意:如果使用limit語(yǔ)句,它必須放在語(yǔ)句的最后
- 用法1:限制查詢出來(lái)的數(shù)據(jù)個(gè)數(shù):
xxxx limit 2;
:對(duì)用xxxx進(jìn)行查詢的結(jié)果分頁(yè)顯示涩拙,每頁(yè)只顯示2個(gè) - 用法2:
xxxx limit 2,5;
:對(duì)用xxxx進(jìn)行查詢的結(jié)果分頁(yè)顯示际长,從結(jié)果中序號(hào)為2的開(kāi)始,顯示5個(gè)兴泥,注意:序號(hào)的0表示第一個(gè)
連接查詢
連接查詢主要想表達(dá)的意思就是多個(gè)表的關(guān)聯(lián)查詢
內(nèi)連接查詢:inner join( ... on):查詢的結(jié)果是兩個(gè)表匹配到的數(shù)據(jù)工育。用法:select * from students inner join score
,但是inner join主要是配合on才有意義
- 對(duì)于inner join搓彻,是取兩個(gè)表中所有記錄的交叉匹配如绸,要兩個(gè)表中都有(on中的判斷內(nèi)容)的才顯示
- inner join常和on配合使用,此時(shí)是用on進(jìn)行篩選旭贬,比如:
SELECT * from students INNER JOIN score on hero.id = score.id;
怔接,將兩個(gè)表中的數(shù)據(jù)交叉匹配,但是只顯示id相同的(注意:此時(shí)id有兩列) - 用inner join時(shí)稀轨,也常用as(可识笃辍)給表取別名,然后用
表名.字段名
取出某個(gè)字段奋刽⊥呶辏可用此法對(duì)于某個(gè)表只取出某個(gè)特定字段以消除2中所說(shuō)的id重復(fù)顯示的問(wèn)題。如:SELECT h.*, s.成績(jī) from hero as h INNER JOIN score as s on h.id = s.id;
右連接查詢:right join:查詢的結(jié)果為兩個(gè)表匹配到的數(shù)據(jù)杨名,右表特有的數(shù)據(jù),對(duì)于左表中不存在的數(shù)據(jù)使用null填充猖毫,一般不用台谍,在左連接中對(duì)換兩個(gè)表的名字即可達(dá)到相同效果
左連接查詢:left join:查詢的結(jié)果為兩個(gè)表匹配到的數(shù)據(jù),左表特有的數(shù)據(jù)吁断,對(duì)于右表中不存在的數(shù)據(jù)使用null填充
自關(guān)聯(lián)
一個(gè)表中某個(gè)字段的值依賴于這個(gè)表中另一個(gè)字段的值(通常將很多數(shù)據(jù)放到一張表中)
通常趁蕊,在類(lèi)似行政級(jí)別中會(huì)常用到自關(guān)聯(lián)
自關(guān)聯(lián)的查詢技巧:對(duì)于自關(guān)聯(lián)的數(shù)據(jù),我們?cè)诓樵儠r(shí)仔役,可以將一張表取不同的別名以“當(dāng)作”不同的表來(lái)使用
子查詢
在一個(gè)select語(yǔ)句中又嵌套了另外一個(gè)select語(yǔ)句掷伙,將來(lái)在使用的時(shí)候,會(huì)先執(zhí)行子語(yǔ)句又兵,然后將子語(yǔ)句的結(jié)論當(dāng)作父語(yǔ)句的條件去進(jìn)行查詢
示例:select name,price from goods where price > (select avg(price) from goods);
任柜,選擇出價(jià)格大于平均價(jià)格的商品
經(jīng)典案例
對(duì)于有如下內(nèi)容的goods表格卒废,查找出每一類(lèi)中最貴的產(chǎn)品的詳細(xì)信息(注意:cate_name是產(chǎn)品類(lèi)別的名字)
insert into goods values(0, 'r510vc 15.6英寸筆記本', '筆記本', '華碩', '3309', default, default);
insert into goods values(0, 'y400n 14.0英寸筆記本', '筆記本', '聯(lián)想', '4999', default, default);
insert into goods values(0, 'g150th 15.6英寸筆記本', '游戲本', '雷神', '8499', default, default);
insert into goods values(0, 'x550cc 15.6英寸筆記本', '筆記本', '華碩', '2799', default, default);
insert into goods values(0, 'x240 超級(jí)本', '超級(jí)本', '聯(lián)想', '4880', default, default);
insert into goods values(0, 'u330p 13.3英寸超級(jí)本', '超級(jí)本', '聯(lián)想', '4299', default, default);
insert into goods values(0, 'svp1326scb 觸控超級(jí)本', '超級(jí)本', '索尼', '7999', default, default);
insert into goods values(0, 'ipad mini 7.9英寸平板電腦', '平板電腦', '蘋(píng)果', '1998', default, default);
insert into goods values(0, 'ipad air 9.7英寸平板電腦', '平板電腦', '蘋(píng)果', '3388', default, default);
insert into goods values(0, 'ipad mini 配備 retina 顯示屏', '平板電腦', '蘋(píng)果', '2788', default, default);
insert into goods values(0, 'ideacentre c340 20英寸一體電腦', '臺(tái)式機(jī)', '聯(lián)想', '3499', default, default);
insert into goods values(0, 'vostro 3800-r1206 臺(tái)式電腦', '臺(tái)式機(jī)', '戴爾', '2899', default, default);
insert into goods values(0, 'imac me086ch/a 21.5 英寸一體電腦', '臺(tái)式機(jī)', '蘋(píng)果', '9188', default, default);
insert into goods values(0, 'at7-7414lp 臺(tái)式電腦 linux', '臺(tái)式機(jī)', '宏基', '3699', default, default);
insert into goods values(0, 'z220sff f4f06pa工作站', '服務(wù)器/工作站', '惠普', '4288', default, default);
insert into goods values(0, 'poweredge ii服務(wù)器', '服務(wù)器/工作站', '戴爾', '5388', default, default);
insert into goods values(0, 'mac pro專(zhuān)業(yè)級(jí)臺(tái)式電腦', '服務(wù)器/工作站', '蘋(píng)果', '28888', default, default);
insert into goods values(0, 'hmz-t3w 頭戴顯示設(shè)備', '筆記本電腦配件', '索尼', '6999', default, default);
insert into goods values(0, '商務(wù)雙肩包', '筆記本配件', '索尼', '99', default, default);
insert into goods values(0, 'x3250 m4機(jī)架式服務(wù)器', '服務(wù)器/工作站', 'ibnm', '6888', default, default);
insert into goods values(0, '商務(wù)雙肩包', '筆記本配件', '索尼', '99', default, default);
查詢語(yǔ)句:
select * from goods inner join
(select cate_name, max(price) as max_price from goods group by cate_name) as t2 on
(goods.cate_name = t2.cate_name and(goods.price = t2.max_price));
結(jié)果如下:
數(shù)據(jù)庫(kù)的設(shè)計(jì)
三范式
范式:經(jīng)過(guò)研究和對(duì)使用中問(wèn)題的總結(jié),對(duì)于設(shè)計(jì)數(shù)據(jù)提出了一些規(guī)范宙地,這些規(guī)范被稱為范式(Normal Form)
-
第一范式(1NF)
強(qiáng)調(diào)的是列的原子性摔认,即列不能夠再分成其他幾列
-
第二范式(2NF)
首先是1NF,另外包含兩部分內(nèi)容宅粥,一是表必須有一個(gè)主鍵参袱;二是表沒(méi)有包含在主鍵中的列必須完全依賴于主鍵,而不能只依賴于主鍵的一部分
-
第三范式(3NF)
首先是2NF秽梅,另外非主鍵列必須直接依賴于主鍵抹蚀,不能存在傳遞依賴,即不能存在:非主鍵列A依賴于非主鍵列B企垦,非主鍵列B依賴與主鍵的情況
關(guān)系型數(shù)據(jù)庫(kù):“一言不合就拆表”——解耦
E-R模型
- E表示entity(實(shí)體)环壤,設(shè)計(jì)實(shí)體就像定義一個(gè)類(lèi)一樣,指定從哪些方面描述對(duì)象竹观,一個(gè)實(shí)體轉(zhuǎn)換為數(shù)據(jù)庫(kù)中的一個(gè)表
- R表示relationship(關(guān)系)镐捧,關(guān)系描述兩個(gè)實(shí)體之間的對(duì)應(yīng)規(guī)則,關(guān)系的類(lèi)型包括一對(duì)一臭增、一對(duì)多(多對(duì)一時(shí)懂酱,需要在多的表中新建一個(gè)字段)、多對(duì)多(多對(duì)多時(shí)誊抛,必須新建一個(gè)表列牺,這個(gè)表稱為聚合表)
- 關(guān)系也是一種數(shù)據(jù),需要通過(guò)一個(gè)字段存儲(chǔ)在表中
- 實(shí)體A對(duì)實(shí)體B為1對(duì)1拗窃,則在表A或表B中創(chuàng)建一個(gè)字段瞎领,存儲(chǔ)另一個(gè)表的主鍵值
表的拆分
ps:真正的數(shù)據(jù)庫(kù)是先設(shè)計(jì),再有數(shù)據(jù)随夸,而不是有了數(shù)據(jù)九默,再來(lái)拆分
將上面的googds表拆分為多個(gè)表
創(chuàng)建商品分類(lèi)表
利用一張表的數(shù)據(jù)創(chuàng)建另外一張表
create table if not exists goods_cates(
-- 如果不存在goods_cates,則創(chuàng)建
id int unsigned primary key auto_increment,
name varchar(40) not null
);
查詢goods表中商品分類(lèi)
select cate_name from goods group by cate_name;
將分組結(jié)果寫(xiě)入到goods_cates表中
用group by 或者distinct去重
name后不能寫(xiě)values
-- 將后面查詢的數(shù)據(jù)直接插入name字段
insert into goods_cates (name) select cate_name from goods group by cate_name;
同步表數(shù)據(jù)
通過(guò)goods_cates數(shù)據(jù)來(lái)更新goods表
update goods as g inner join goods_cates as c on g.cate_name set g.cate_name = c.id;
創(chuàng)建商品品牌表
通過(guò)create...select來(lái)創(chuàng)建數(shù)據(jù)表并且同時(shí)寫(xiě)入記錄宾毒,一步到位(使用另一張表的數(shù)據(jù)創(chuàng)建表)
-- select brand_name from goods group by brand_name;
-- 在創(chuàng)建數(shù)據(jù)表的時(shí)候一起插入數(shù)據(jù)
-- 注意:需要對(duì)brand_name 用as起別名驼修,否則c_name字段就沒(méi)有值
create table goods_brands(
id int unsigned primary key auto_increment,
c_name varchar(40) not null) select brand_name as c_name from goods group by brand_name;
-- 最后一行中的兩個(gè)c_name是必須一樣
同步數(shù)據(jù)
通過(guò)goods_brands數(shù)據(jù)表來(lái)更新goods數(shù)據(jù)表
update goods g inner join goods_brands b on g.brand_name = b.c_name set g.brand_name = b.id;
修改表結(jié)構(gòu)
查看goods中的cate_name和brand_name,會(huì)發(fā)現(xiàn)cate_name和brand_name對(duì)應(yīng)的類(lèi)型為varchar诈铛,但是存儲(chǔ)的卻是數(shù)字
desc goods
通過(guò)alter table語(yǔ)句來(lái)修改表的結(jié)構(gòu)(可以同時(shí)操作多個(gè)字段)
alter table goods
change cate_name cate_id int unsigned not null,
change brand_name brand_id int unsigned not null;
外鍵
分別在goods_cates和goods_brands表中插入記錄
insert into goods_cates(c_name) values('路由器'),('交換機(jī)'),('網(wǎng)卡');
insert into goods_brands(c_name) values('海爾'),('清華同方'),('神州');
在goods數(shù)據(jù)表中寫(xiě)入任意記錄
insert into goods (name,cate_id,brand_id,price)
values('LaserJet Pro P1606dn黑白激光打印機(jī)', 12, 4, '1849');
查詢所有商品的詳細(xì)信息(通過(guò)內(nèi)連接)
select g.id, g.name, c.c_name, b.c_name,g.price from goods as g
inner join goods_cates as c on g.cate_id = c.id
inner join goods_brands as b on g.brand_id = b.id;
發(fā)現(xiàn)在查詢結(jié)果中出現(xiàn)了cate_id為12的項(xiàng)乙各,但是在goods_cates表中并沒(méi)有該項(xiàng)。這是因?yàn)榇藭r(shí)兩個(gè)表還沒(méi)有關(guān)聯(lián)幢竹,如何讓他們有關(guān)聯(lián)耳峦?——將goods.cate_id設(shè)為外鍵
ps:只有innodb數(shù)據(jù)庫(kù)引擎支持外鍵約束
-- 給brand_id添加外鍵成功
alter table goods add foreign key (brand_id) references goods_brands(id);
-- 給brand_id添加外鍵約束,失敗焕毫,因?yàn)橐呀?jīng)添加了一個(gè)不存在的cate_id
alter table goods add foreign key (cate_id) references goods_cates(id);
外鍵的作用:保證數(shù)據(jù)的合法性
如何在創(chuàng)建表的時(shí)候就設(shè)置外鍵
create table goods(
...
foreign key(cate_id) references goods_cates(id),
...
)
但是在實(shí)際中是很少用到外鍵的蹲坷,因?yàn)闀?huì)降低效率
如何取消外鍵
-- 首先要獲取外鍵約束名稱驶乾,該名稱系統(tǒng)會(huì)自動(dòng)生成,可以通過(guò)查看表創(chuàng)建語(yǔ)句來(lái)獲取名稱
show create table goods;
-- 獲取名稱之后就可以根據(jù)名稱來(lái)刪除外鍵約束
alter table goods drop foreign key 外鍵名稱;