常見數據庫
關係型數據庫
常見的關係型數據庫有 MySQL、Oracle、SQL Server、JDBC、DB2 等;主要是用來描述實體與實體之間的關係,實實在在存在的事物。例如:男生和女生、學生和班級、員工和部門。
非關係型數據庫
常見的非關係型數據庫有 Redis、MongoDB、NoSQL 等;非關係型數據庫嚴格上不是一種數據庫,應該是一種數據結構化存儲方法的集合,可以是文檔或者鍵值對等。
數據庫與服務器
數據庫
數據庫管理軟件。通常一個應用對應一個數據庫。
服務器
服務器就是一臺電腦,這臺安裝相關的服務器軟件,這些軟件監聽不同的端口號,根據用戶訪問的端口號,提供不同的服務。
MySQL 的 SQL 語句
SQL:Structure Query Languages (結構化查詢語言)
數據定義語言(DDL)
定義數據庫,數據表的結構:create(創建)、drop(刪除)、alter(修改)。
數據操縱語言(DML)
主要是用來操作數據:insert(插入)、update(修改)、delete(刪除)。
數據控制語言(DCL)
定義訪問權限,取消訪問權限,安全設置 grant。
數據查詢語言(DQL)
select(查詢) from 子句 where 子句。
數據庫的 CRUD 的操作
前置知識
-
登錄數據庫:mysql –uroot –proot
-
退出數據庫:exit、quit、\q、Ctrl+c
-
退出當前命令行:\c
-
複製命令行的內容:標記->選擇內容->回車,不用Ctrl+C
-
導出數據庫文件:
- 進入 MySQL 的安裝目錄的 bin 目錄,如:D:\Program Files (x86)\MySQL\MySQLServer5.0\bin
- 用 cmd 打開
- 輸入命令:mysqldump –h localhost –u root –p 數據庫名字>導出路徑
mysqldump –h localhost –u root –p worker>e:worker.sql
- 啓動MySQL服務:net start mysql
- 關閉MySQL服務:net stop mysql
創建數據庫
create database 數據庫名字;
create database test;
- 創建數據庫的時候,指定字符集
- create database 數據庫的名字 character set 字符集;
create database test character set utf8;
create database 數據庫的名字 character set 字符集 collate 校對規則;
create database test character utf8 collate utf8_bin;
查看數據庫
show create database 數據庫名字;
查看所有數據庫
show databases;
注意:三個文件不可刪
information_schema 相關信息約束
performance_schema 相關表現約束
mysql
修改數據庫的操作
修改數據庫的字符集
alter database 數據庫的名字 character set 字符集
alter database test character set gbk;
刪除數據庫
drop database 數據庫名字;
切換數據庫(選中數據庫)
use 數據庫名字;
查看當前正在使用的數據庫
select database ();
表的 CRUD 操作
創建表
create database 數據庫名字
create table 表名(
列名 列的類型(長度) 約束,
列名2 列的類型(長度) 約束
);
列的類型
- 列的約束
主鍵約束:primary key
唯一約束:unique
非空約束:not null
create table student(
sid int primary key,
sname varchar(10),
sex int,
age int
);
查看錶
查看所有的表
show tables;
查看錶的創建過程
show create table 表名;
show create table student;
查看錶的結構
desc student;
修改表
添加(add),修改列(modify),修改列名(change),刪除列(drop),修改表名(rename),修改表的字符集
- 添加列(add)
alter table 表名 add 列名 列的類型 列的約束
alter table student add score int not null;
- 修改列(modify)
alter table student modify sex varchar(2);
- 修改列名(change)
alter table student change sex gender varchar(2);
- 刪除列(drop)
alter table student drop score;
- 修改表名(rename)
rename table student to students;
- 修改表的字符集
alter table student character set gbk;
刪除表
drop table students;
移動列的順序
alter table 表名 modify 字段名 字段類型 after 字段
alter table student modify sex int(11) after sname;(移動到sname後面)
alter table student modify sex int(11) first;(移動到最前面)
SQL 表中的 CRUD 的操作
插入數據
insert into 表名(列名1,列名2,列名3) values(值1,值2,值3);
insert into student(sid,sname,sex,age) values(1,'zhangsan',1,22);
- 簡單寫法(插入部分列列名不可省略)
insert into student values(2, 'zhangsan',1,22);
- 批量插入
insert into student values
(3, 'zhangsan',1,22),
(4, 'zhangsan',1,22),
(5, 'zhangsan',1,22);
查看錶中數據
select * from student;
解決表中插入數據中文亂碼的問題
1、 設置數據庫的表字符編碼爲 jbk;
2、 停止 MySQL 服務(net stop mysql);
3、 找到 MySQL 的安裝路徑,找到 my.ini 文件,把 default-character-set=utf8 修改爲 default-character-set=gbk;
4、 啓動 MySQL 服務(net start mysql),重新登錄數據庫。
刪除記錄
delete from 表名 [where 條件]
delete from student where sid=5;
把表中數據全部刪除
delete from student;
問題:
delete 刪除數據和 truncate 刪除數據有什麼差別?
delete:DML 一條一條刪除表中的數據
truncate:DDL 先刪除表再重建表
關於哪條執行效率高,具體要看錶中的數據
如果數據比較少,delete 比較高效
如果數據比較多,truncate 比較高效
更新表記錄
update 表名 set 列名=列的值,列名2=列名2的值 [where 條件]
如果參數是字符串、日期要加上單引號
update student set sname= '張三' where sid=5;
update student set sname= '李四' ,sex='1';
查詢記錄
select [distinct] [ * ] [列名,列名2] from 表名 [where 條件]
說明:
distinct:去除重複的數據
select:選擇顯示哪些列的內容
簡單查詢
查詢所有
select * from 表名
查詢姓名和性別
select sname,sex from student;
別名查詢
as 的關鍵字,as 關鍵字可以省略
表別名
select s.sname,s.sex from student as s;(主要用在多表查詢)
列別名
select sname as 姓名,age as 年齡 from student;
去掉重複的值
select age from student;
select distinct age from student;
說明:
select: 運算查詢:僅在查詢結果上做了運算
select * ,age*2 from student;
select * ,age*2 as 兩倍年齡 from student;
條件查詢[where關鍵字]
查詢年齡大於 20 的學生
select * from student where age > 20;
where 後的條件寫法
說明:
關係運算符:> >= < <= != <>
<> 不等於 標準SQL語法
!= 不等於 非標準SQL語法
查詢學生年齡不等於 20 的所有學生
select * from student where age <> 20;
select * from student where age != 20;
查詢年齡在 20 到 30 之間
select * from student where age > 20 and age < 30;
使用 between… and… 查詢
select * from student where age between 20 and 30;
邏輯運算:and , or , not
查詢年齡小於 15 或者年齡大於 20
select * from student where age < 15 or age > 20;
模糊查詢
like:
_ :代表的是一個字符
% :代表的是多個字符
- 查詢姓名中帶有 張 的所有學生 ‘%張%’
select * from student where sname like '%張%';
- 查詢第二名字是三的所有學生 ‘_張%’
select * from student where sname like '_張%';
in:在某個範圍獲得值
查詢年齡在 20,21,22 裏面的所有學生
select * from student where age in (20,21,22);
- 排序查詢
order by 關鍵字
asc :ascend 升序(默認的排序方式)
desc:descend 降序
查詢所有學生的年齡,按照年齡進行排序
select * from student order by age;
查詢所有學生的年齡,按照年齡進行降序排序
select * from student order by age desc;
查詢學生姓名有“張”的學生,按年齡排序
查詢學生姓名有“張”的所有學生
select * from student where sname like '%張%';
進行排序得出結果
select * from student where sname like '%張%' order by age asc;
複雜查詢
聚合函數
sum(): 求和
avg(): 求平均值
count(): 統計數據
max(): 最大值
min(): 最小值
獲得所有商品價格的總和
select sum(價格名稱) from 表名;
select sum(price) from product;
獲得所商品的平均價格
select avg(price) from product;
獲得所有商品的個數
select count(*) from product;
注意:where 條件後面不能接聚合函數
查出商品價格大於平均的所有商品
- 查出所有商品
select from product;
- 大於平均價格
select avg(price) from product;
如平均價格爲 100
select * from product where price > 100;
或者(子查詢)
select * from product where price > (select avg(price) from product);
分組
group by
根據 cno 字段分組,分組後統計商品的個數
select cno,count(*) from product group by cno;
根據 cno 分組,分組統計每組商品的平均價格,並且商品平均價格 > 60
select cno,avg(price)
from product group by cno
having avg(price) > 60;
說明:
having 關鍵字 可以接聚合函數 出現在分組之後
where 關鍵字 它是不可以接聚合函數 出現在在分組之前
編寫順序
S…F…W…G…H…O
select..from..where..group by..having..order by
執行順序
F…W…G…H…S…O
from..where..group by..having..select..order by
SQL 多表操作
需求:
分類表和商品表之間是不是有關係?如果有關係,在數據庫中如何表示這種關係?
create table category(
cid int primary key auto_increment,
cname varchar(10),
cdesc varchar(31)
);
insert into category values(null,'手機數碼','電子產品,');
insert into category values(null,'鞋靴箱包','江南皮鞋廠傾情打造');
insert into category values(null,'香菸酒水','黃鶴樓,茅臺,二鍋頭');
insert into category values(null,'酸奶餅乾','娃哈哈,蒙牛酸酸乳');
insert into category values(null,'饞嘴零食','瓜子花生,八寶粥,辣條');
select * from category;
select cname,cdesc from category;
所有商品
1.商品ID
2.商品名稱
3.商品的價格
4.生產日期
5.商品分類ID
商品和商品分類:所屬關係
create table product(
pid int primary key auto_increment,
pname varchar(10),
price double,
pdate timestamp,
cno int
);
insert into product values(null,'小米mix4',998,null,1);
insert into product values(null,'錘子',2888,null,1);
insert into product values(null,'阿迪王',99,null,2);
insert into product values(null,'老村長',88,null,3);
insert into product values(null,'勁酒',35,null,3);
insert into product values(null,'小熊餅乾',1,null,4);
insert into product values(null,'衛龍辣條',1,null,5);
insert into product values(null,'旺旺大餅',1,null,5);
多表之間的關係如何維護
外鍵約束:foreign key
給 product 中的這個 cno 添加一個外鍵約束
alter table product add foreign key(cno) references category(cid);
刪除的時候,先刪除外鍵關聯的所有數據,再才能刪除分類的數據
建數據庫原則
通常情況下,一個項目/應用建一個數據庫
建表原則
一對一:常用於拆表操作。
建表原則:
1、將兩張表合併成一張表。
2、將兩張表的主鍵建立起關係。
3、將一對一的關係當作一對多的關係去處理。
一對多:
建表原則:在多的一方增加一個外鍵,指向一的一方。
多對多:
建表原則:將多對多轉成一對多的關係,創建一張中間表。
主鍵約束:
1、默認就是不能爲空,唯一 。
2、外鍵都是指向另外一張表的主鍵。
3、主鍵一張表只能有一個。
唯一約束
列面的內容,必須是唯一,不能出現重複情況,爲空;唯一約束不可以作爲其它表的外鍵 ,可以有多個唯一約束。
一對一建表原則:合併一張表,將主鍵建立關係,將它當作一對多的情況來處理。
一對多建表原則:在多的一方添加一個外鍵,指向一的一方。
多對多建表原則:拆成一對多,創建一張中間表,至少要有兩個外鍵,指向原來的表。
網上商城表實例(複雜查詢)
用戶購物流程(用戶表、訂單表、商品表、商品分類表)
用戶表 (用戶的ID,用戶名,密碼,手機)
create table user(
uid int primary key auto_increment,
username varchar(31),
password varchar(31),
phone varchar(11)
);
插入數據
insert into user values(1,'zhangsan','123','13811118888');
訂單表 (訂單編號,總價,訂單時間 ,地址,外鍵用戶的ID)
create table orders(
oid int primary key auto_increment,
sum int not null,
otime timestamp,
address varchar(100),
uno int,
foreign key(uno) references user(uid)
);
批量插入數據
insert into orders values(1,200,null,'廣州',1);
insert into orders values(2,250,null,'深圳',1);
商品表 (商品ID, 商品名稱,商品價格,外鍵cno)
create table product(
pid int primary key auto_increment,
pname varchar(10),
price double,
cno int,
foreign key(cno) references category(cid)
);
批量插入數據
insert into product values(null,'小米mix4',998,1);
insert into product values(null,'錘子',2888,1);
insert into product values(null,'阿迪王',99,2);
insert into product values(null,'老村長',88,3);
insert into product values(null,'勁酒',35,3);
insert into product values(null,'小熊餅乾',1,4);
insert into product values(null,'衛龍辣條',1,5);
insert into product values(null,'旺旺大餅',1,5);
訂單項: 中間表(訂單ID,商品ID,商品數量,訂單項總價)
create table orderitem(
ono int,
pno int,
foreign key(ono) references orders(oid),
foreign key(pno) references product(pid),
ocount int,
subsum double
);
給1號訂單添加商品 200 塊錢的商品
insert into orderitem values(1,7,100,100);
insert into orderitem values(1,8,101,100);
給2號訂單添加商品 250 塊錢的商品
insert into orderitem values(2,5,1,35);
insert into orderitem values(2,3,3,99);
商品分類表(分類ID,分類名稱,分類描述)
create table category(
cid int primary key auto_increment,
cname varchar(15),
cdesc varchar(100)
);
批量插入數據
insert into category values(null,'手機數碼','電子產品,黑馬生產');
insert into category values(null,'鞋靴箱包','江南皮鞋廠傾情打造');
insert into category values(null,'香菸酒水','黃鶴樓,茅臺,二鍋頭');
insert into category values(null,'酸奶餅乾','娃哈哈,蒙牛酸酸乳');
insert into category values(null,'饞嘴零食','瓜子花生,八寶粥,辣條');
交叉連接查詢(笛卡爾積)
SELECT * FROM product;
SELECT * FROM category;
笛卡爾積,查出來是兩張表的乘積,查出來的結果沒有意義。
SELECT * FROM product,category;
過濾出有意義的數據
SELECT * FROM product,category WHERE cno=cid;
SELECT * FROM product AS p,category AS c WHERE p.cno=c.cid;
SELECT * FROM product p,category c WHERE p.cno=c.cid;
數據準備
INSERT INTO product VALUES(NULL,'耐克帝',10,NULL);
內連接查詢
隱式內鏈接
SELECT * FROM product p,category c WHERE p.cno=c.cid;
顯示內鏈接
SELECT * FROM product p INNER JOIN category c ON p.cno=c.cid;
- 區別:
- 隱式內鏈接:在查詢出結果的基礎上去做的 WHERE 條件過濾。
- 顯示內鏈接:帶着條件去查詢結果, 執行效率要高。
左外連接
左外連接,會將左表中的所有數據都查詢出來,如果右表中沒有對應的數據,用 NULL 代替。
SELECT * FROM product p LEFT OUTER JOIN category c ON p.cno=c.cid;
準備工作
INSERT INTO category VALUES(100,'電腦辦公','電腦叉叉差');
右外連接:會將右表所有數據都查詢出來,如果左表沒有對應數據的話,用 NULL 代替。
SELECT * FROM product p RIGHT OUTER JOIN category c ON p.cno=c.cid;
分頁查詢
每頁數據數據3
起始索引從0
第1頁: 0
第2頁: 3
起始索引: index 代表顯示第幾頁 頁數從1開始
每頁顯示3條數據
startIndex = (index-1)*3
第一個參數是索引,第二個參數是顯示的個數。
select * from product limit 0,3;
select * from product limit 3,3;
子查詢
1、查詢出(商品名稱,商品分類名稱)信息
2、查詢分類名稱爲手機數碼的所有商品
查詢分類名爲手機數碼的 ID
select * from category where cname ='手機數碼';
得出ID爲1的結果
SELECT * FROM product WHERE cno = (SELECT cid FROM category WHERE cname='手機數碼');
查詢出(商品名稱,商品分類名稱)信息
左連接
SELECT p.pname,c.cname FROM product p LEFT OUTER JOIN category c ON p.cno = c.cid;
子查詢
SELECT pname ,(SELECT cname FROM category c WHERE p.cno=c.cid ) AS 商品分類名稱 FROM product p;