一、數據庫概述
什么是數據庫
數據庫就是存儲數據的倉庫,其本質是一個文件系統,數據按照特定的格式將數據存儲起來,用戶可以對數據庫中的數據進行增加,修改,刪除及查詢操作。什么是數據庫管理系統
數據庫管理系統(DataBase Management System,DBMS):指一種操作和管理數據庫的大型軟件,用于建立、使用和維護數據庫,對數據庫進行統一管理和控制,以保證數據庫的安全性和完整性。用戶通過數據庫管理系統訪問數據庫中表內的數據。常見的數據庫管理系統
MYSQL :開源免費的數據庫,小型的數據庫.已經被Oracle收購了.MySQL6.x版本也開始收費。
Oracle :收費的大型數據庫,Oracle公司的產品。Oracle收購SUN公司,收購MYSQL。
DB2 :IBM公司的數據庫產品,收費的。常應用在銀行系統中.
SQLServer:MicroSoft 公司收費的中型的數據庫。C#、.net等語言常使用。
SyBase :已經淡出歷史舞臺。提供了一個非常專業數據建模的工具PowerDesigner。
SQLite : 嵌入式的小型數據庫,應用在手機端。
Java相關的數據庫:MYSQL,Oracle
.
這里使用MySQL數據庫。MySQL中可以有多個數據庫,數據庫是真正存儲數據的地方。
數據庫與數據庫管理系統的關系
- 數據庫表
數據庫中以表為組織單位存儲數據。
表類似我們的Java類,每個字段都有對應的數據類型。
那么用我們熟悉的java程序來與關系型數據對比,就會發現以下對應關系:
類----------表
類中屬性----------表中字段
對象----------記錄
-
表數據
根據表字段所規定的數據類型,我們可以向其中填入一條條的數據,而表中的每條數據類似類的實例對象。表中的一行一行的信息我們稱之為記錄。
表數據.png
表記錄與java類對象的對應關系:
二、數據庫的安裝登錄
1. 安裝
安裝完成后,需要開啟對應的數據庫服務才能使用。
開啟和關閉服務的操作:右鍵點擊我的電腦→管理→服務→可以找到MySQL服務或Oracle服務開啟或停止。
-
打開MySQL服務
MySql服務開啟或停止 -
而Oracle需要開啟OracleOraDb11g_home1TNSListener和OracleServiceORCL這兩個服務才能使用:
Oracle服務開啟或停止
OracleService<SID>:數據庫實例服務
OracleOraDb11g_hom1TNSListener :數據庫監聽服務
每次進到服務里面去打開相關服務很麻煩,所以我們可以寫個bat腳本:
Oracle服務腳本
net start OracleOraDb11g_home1TNSListener
net start OracleServiceORCL
pause
MySQL服務腳本
net start mysql
把文本的后綴改成bat就可以了。
在dos窗口也可以使用腳本里的命令運行:
2. 登錄
2.1 MySQL的登錄
MySQL是一個需要賬戶名密碼登錄的數據庫,登陸后使用,它提供了一個默認的root賬號,使用安裝時設置的密碼即可登錄。
格式1:cmd> mysql –u用戶名 –p密碼
例如:mysql -uroot –proot
注意:-p后無空格
格式2:cmd> mysql --host=ip地址 --user=用戶名 --password=密碼
例如:mysql --host=127.0.0.1 --user=root --password=root
三、 SQL語法
數據庫是不認識JAVA語言的,但是我們同樣要與數據庫交互,這時需要使用到數據庫認識的語言SQL語句,它是數據庫的代碼。
結構化查詢語言(Structured Query Language)簡稱SQL,是一種數據庫查詢和程序設計語言,用于存取數據以及查詢、更新和管理關系數據庫系統。
創建數據庫、創建數據表、向數據表中添加一條條數據信息均需要使用SQL語句。
SQL語句分類:
- 數據定義語言:簡稱
DDL(Data Definition Language)
,用來定義數據庫對象:數據庫,表,列等。關鍵字:create,alter,drop
等 - 數據操作語言:簡稱
DML(Data Manipulation Language)
,用來對數據庫中表的記錄進行更新。關鍵字:insert,delete,update
等 - 數據控制語言:簡稱
DCL(Data Control Language)
,用來定義數據庫的訪問權限和安全級別,及創建用戶。關鍵字:grant revoke drop
等。 - 數據查詢語言:簡稱
DQL(Data Query Language)
,用來查詢數據庫中表的記錄。關鍵字:select,from,where
等。
SQL語法規則:
- SQL語句可以單行或多行書寫,以分號結尾
- 可使用空格和縮進來增強語句的可讀性
- MySQL和Oracle數據庫的SQL語句都不區分大小寫,建議使用大寫,例如:SELECT * FROM user。
- 同樣可以使用/**/的方式完成注釋
MySQL中的我們常使用的數據類型:
Oracle中常用數據類型:
1. 數據定義語言-DDL
1.1 DDL-數據庫操作
- 創建數據庫:
create database 數據庫名;
create database 數據庫名 character set 字符集;
例如:
#創建數據庫 數據庫中數據的編碼采用的是安裝數據庫時指定的默認編碼 utf8
CREATE DATABASE day21_1;
#創建數據庫 并指定數據庫中數據的編碼
CREATE DATABASE day21_2 CHARACTER SET utf8;
- 查看數據庫
查看數據庫MySQL服務器中的所有的數據庫:
show databases;
查看某個數據庫的定義的信息:
show create database 數據庫名;
例如:
show create database day21_1;
- 刪除數據庫
drop database 數據庫名稱;
例如:
drop database day21_2;
- 切換數據庫:
use 數據庫名;
例如:
use day21_1;
- 查看正在使用的數據庫:
select database();
1.2 DDL-表結構相關語句
- 創建表
create table 表名(
字段名 類型(長度) 約束,
字段名 類型(長度) 約束
);
例如:
#創建分類表
CREATE TABLE sort (
sid INT, #分類ID
sname VARCHAR(100) #分類名稱
);
- 主鍵約束
主鍵是用于標識當前記錄的字段。它的特點是非空,唯一。在開發中一般情況下主鍵是不具備任何含義,只是用于標識當前記錄。
格式:- 在創建表時創建主鍵,在字段后面加上 primary key.
create table tablename(
id int primary key,
.......
) - 在創建表時創建主鍵,在表創建的最后來指定主鍵
create table tablename(
id int,
.......,
primary key(id)
) - 刪除主鍵:alter table 表名 drop primary key;
alter table sort drop primary key; - 主鍵自動增長:一般主鍵是自增長的字段,不需要指定。
實現添加自增長語句,主鍵字段后加auto_increment(只適用MySQL)
- 在創建表時創建主鍵,在字段后面加上 primary key.
例如:
###創建分類表
CREATE TABLE sort (
sid INT PRIMARY KEY auto_increment, #分類ID
sname VARCHAR(100) #分類名稱
);
其他約束:其他約束還有如外鍵、唯一、非空等。
唯一約束:unique
非空約束:not null
- 查看表
查看數據庫中的所有表:
格式:show tables;
查看表結構:
格式:desc 表名;
例如:desc sort;
- 刪除表
格式:drop table 表名;
例如:drop table sort;
- 修改表結構格式:
alter table 表名 add 列名 類型(長度) 約束;
作用:修改表添加列.
例如:
#1,為分類表添加一個新的字段為 分類描述 varchar(20)
ALTER TABLE sort ADD sdesc VARCHAR(20);
alter table 表名 modify 列名 類型(長度) 約束;
作用:修改表修改列的類型長度及約束.
例如:
#2, 為分類表的分類名稱字段進行修改,類型varchar(50) 添加約束 not null
ALTER TABLE sort MODIFY sname VARCHAR(50) NOT NULL;
alter table 表名 change 舊列名 新列名 類型(長度) 約束;
作用:修改表修改列名.
例如:
#3, 為分類表的分類名稱字段進行更換 更換為 snamesname varchar(30)
ALTER TABLE sort CHANGE sname snamename VARCHAR(30);
alter table 表名 drop 列名;
作用:修改表刪除列.
例如:
#4, 刪除分類表中snamename這列
ALTER TABLE sort DROP snamename;
rename table 表名 to 新表名;
作用:修改表名
例如:
#5, 為分類表sort 改名成 category
RENAME TABLE sort TO category;
alter table 表名 character set 字符集;
作用:修改表的字符集
例如:
#6, 為分類表 category 的編碼表進行修改,修改成 gbk
ALTER TABLE category CHARACTER SET gbk;
2.數據操作語言-DML
- 插入表記錄:
insert into 表 (列名1,列名2,列名3..) values (值1,值2,值3..); -- 向表中插入某些列
insert into 表 values (值1,值2,值3..); --向表中插入所有列
注意:
- 插入的數據應與字段的數據類型相同
- 數據的大小應該在列的長度范圍內
- 在values中列出的數據位置必須與被加入列的排列位置相對應。
- 除了數值類型外,其它的字段類型的值必須使用引號引起。
- 如果要插入空值,可以不寫字段,或者插入 null。
- 對于自動增長的列在操作時,直接插入null值即可。
例如:
INSERT INTO sort(sid,sname) VALUES('s001', '電器');
INSERT INTO sort(sid,sname) VALUES('s002', '服飾');
INSERT INTO sort VALUES('s003', '化妝品');
INSERT INTO sort VALUES('s004','書籍');
-
更新表記錄:
用來修改指定條件的數據,將滿足條件的記錄指定列修改為指定值
語法:
update 表名 set 字段名=值,字段名=值;
update 表名 set 字段名=值,字段名=值 where 條件;
注意:
- 列名的類型與修改的值要一致.
- 修改值得時候不能超過最大長度.
- 值如果是字符串或者日期需要加’’.
例如:
#1,將指定的sname字段中的值 修改成 日用品
UPDATE sort SET sname='日用品';
#2, 將sid為s002的記錄中的sname改成 日用品
UPDATE sort SET sname='日用品' WHERE sid='s002';
UPDATE sort SET sname='日用品' WHERE sid='s003';
-
刪除記錄:delete
語法:
delete from 表名 [where 條件];
或者
truncate table 表名;
面試題:
刪除表中所有記錄使用delete from 表名,還是用truncate table 表名?
刪除方式:
delete
一條一條刪除,不清空auto_increment記錄數。
truncate
直接將表刪除,重新建表,auto_increment將置為零,從新開始。
例如:
DELETE FROM sort WHERE sname='日用品';
#表數據清空
DELETE FROM sort;
-
DOS操作數據亂碼解決
我們在dos命令行操作中文時,可能會報錯:
insert into user(username,password) values(‘張三’,’123’);
ERROR 1366 (HY000): Incorrect string value: '\xD5\xC5\xC8\xFD' for column 'username' at row 1
原因:因為mysql的客戶端編碼的問題我們的是utf8,而系統的cmd窗口編碼是gbk
解決方案(臨時解決方案):修改mysql客戶端編碼。
查看所有mysql的編碼:show variables like 'character%';
查看所有mysql的編碼.png 在圖中與客戶端有關的編碼設置:
client connetion result 三個和客戶端相關
database server system 三個和服務器端相關將客戶端編碼修改為gbk
set character_set_results=gbk; / set names gbk;
以上操作,只針對當前窗口有效果,如果關閉了服務器便失效。如果想要永久修改,通過以下方式:
- 在mysql安裝目錄下有my.ini文件
default-character-set=gbk 客戶端編碼設置
character-set-server=utf8 服務器端編碼設置
注意:修改完成配置文件,重啟服務。
3.數據庫查詢語言-DQL
查詢語句,在開發中使用的次數最多,此處使用“zhangwu” 賬務表。
創建賬務表:
CREATE TABLE zhangwu (
id INT PRIMARY KEY AUTO_INCREMENT, -- 賬務ID
name VARCHAR(200), -- 賬務名稱
money DOUBLE, -- 金額
);
插入表記錄:
INSERT INTO zhangwu(id,name,money) VALUES (1,'吃飯支出',247);
INSERT INTO zhangwu(id,name,money) VALUES (2,'工資收入',12345);
INSERT INTO zhangwu(id,name,money) VALUES (3,'服裝支出',1000);
INSERT INTO zhangwu(id,name,money) VALUES (4,'吃飯支出',325);
INSERT INTO zhangwu(id,name,money) VALUES (5,'股票收入',8000);
INSERT INTO zhangwu(id,name,money) VALUES (6,打麻將支出,8000);
INSERT INTO zhangwu(id,name,money) VALUES (7,null,5000);
查詢指定字段信息
select 字段1,字段2,...from 表名;
例如:
select id,name from zhangwu;查詢表中所有字段
select * from 表名;
例如:
select * from zhangwu;
注意:使用"*"在練習、學習過程中可以使用,在實際開發中,不推薦使用。原因,要查詢的字段信息不明確,若字段數量很多,會導致查詢速度很慢。distinct用于去除重復記錄
select distinct 字段 from 表名;
例如:
select distinct money from zhangwu;-
別名查詢,使用的as關鍵字,as可以省略的.
別名可以給表中的字段,表設置別名。
當查詢語句復雜時,使用別名可以極大的簡便操作。- 表別名格式:
select * from 表名 as 別名;
或
select * from 表名 別名;
2.列別名格式:
select 字段名 as 別名 from 表名;
或
select 字段名 別名 from 表名;
- 表別名格式:
例如
表別名:
select * from zhangwu as zw;
列別名:
select money as m from zhangwu;
或
select money m from zhangwu;
我們在sql語句的操作中,可以直接對列進行運算。
例如:將所有賬務的金額+10000元進行顯示.
select pname,price+10000 from product;-
條件查詢
where語句表條件過濾。滿足條件操作,不滿足不操作,多用于數據的查詢與修改。
格式 :select 字段 from 表名 where 條件;
where條件的種類如下:
where條件
例如:
查詢所有吃飯支出記錄
SELECT * FROM zhangwu WHERE name = '吃飯支出';
查詢出金額大于1000的信息
SELECT * FROM zhangwu WHERE money >1000;
查詢出金額在2000-5000之間的賬務信息
SELECT * FROM zhangwu WHERE money >=2000 AND money <=5000;
或
SELECT * FROM zhangwu WHERE money BETWEEN 2000 AND 5000;
查詢出金額是1000或5000或3500的商品信息
SELECT * FROM zhangwu WHERE money =1000 OR money =5000 OR money =3500;
或
SELECT * FROM zhangwu WHERE money IN(1000,5000,3500);
查詢出賬務名稱包含”支出”的賬務信息。
SELECT * FROM zhangwu WHERE name LIKE "%支出%";
查詢出賬務名稱中是無五個字的賬務信息
SELECT * FROM gjp_ledger WHERE ldesc LIKE "_____"; -- 五個下劃線_
查詢出賬務名稱不為null賬務信息
SELECT * FROM zhangwu WHERE name IS NOT NULL;
SELECT * FROM zhangwu WHERE NOT (name IS NULL);
-
排序
通過order by語句,可以將查詢出的結果進行排序。放置在select語句的最后。
格式:
SELECT * FROM 表名 ORDER BY 字段 ASC;
ASC 升序 (默認)
DESC 降序
例如:
查詢所有的商品,按金額進行排序.(asc-升序,desc-降序)
select * from zhangwu order by money;查詢名稱包含“支出”的賬務信息,并按金額降序排序.
select * from zhangwu where name like '%支出%' order by money desc;
-
聚合
之前我們做的查詢都是橫向查詢,它們都是根據條件一行一行的進行判斷,而使用聚合函數查詢是縱向查詢,它是對一列的值進行計算,然后返回一個單一的值;另外聚合函數會忽略空值。
今天我們學習如下五個聚合函數:
count
:統計指定列不為NULL的記錄行數;
sum
:計算指定列的數值和,如果指定列類型不是數值類型,那么計算結果為0;
max
:計算指定列的最大值,如果指定列是字符串類型,那么使用字符串排序運算;
min
:計算指定列的最小值,如果指定列是字符串類型,那么使用字符串排序運算;
avg
:計算指定列的平均值,如果指定列類型不是數值類型,那么計算結果為0;
例如:
統計賬務表中共有多少條記錄
SELECT COUNT(*) FROM zhangwu;統計賬務表中金額大于3000的有多少條記錄
SELECT COUNT(*) FROM zhangwu WHERE money>3000;統計有多少收入的賬務信息
SELECT SUM(money) FROM zhangwu WHERE name like '%收入%';統計出記錄中支出的平均值
SELECT AVG(money) FROM zhangwu where name like '%支出%';統計出商品表中收入的最大與最小值
SELECT MAX(money),MIN(money) FROM zhangwu;
- 分組
分組查詢是指使用group by
字句對查詢信息進行分組,例如:我們要統計出zhanguw表中所有分類賬務的總數量,這時就需要使用group by 來對zhangwu表中的賬務信息根據parent進行分組操作。
格式:
SELECT 字段1,字段2… FROM 表名 GROUP BY 字段 HAVING 條件;
分組操作中的having子語句,是用于在分組后對數據進行過濾的,作用類似于where條件。
having與where的區別:
having是在分組后對數據進行過濾.
where是在分組前對數據進行過濾having后面可以使用分組函數(統計函數)
where后面不可以使用分組函數。
例如:
對賬務分種類統計,求出每個種類的賬務總金額
SELECT parent,SUM(money) FROM zhangwu GROUP BY parent;對賬務分種類統計,求出每個種類的賬務總金額,金額要大于500才顯示
SELECT parent,SUM(money) FROM zhangwu GROUP BY parent HAVING SUM(money)>500;
-
分頁查詢
-
Oracle的分頁查詢:
先介紹兩個概念- rowid
- rowid在記錄創建時生成,而且是不變,直接指向硬件上的存儲位置
- 用rowid直接訪問是最快的,但也是人力所無法做到的
- 只要記錄沒被搬動過,rowid是不變的
- rownum
- rownum是個偽列,查詢的時候除非特別指定,否則不會顯示。
- 其主要的用處是控制查詢返回的行數
- 只能使用:<,<=
- 當rownum和order by一起使用時,會首先選出符合rownum條件的記錄,然后再進行排序,這會給我們的查詢帶來難度。
示例:
image.png
- rowid
分頁模板1
SELECT * FROM (SELECT ROWNUM RN, T.* FROM (SELECT * FROM 表名 [ WHERE 條件 ] [ ORDER BY ]) T WHERE ROWNUM <= A) WHERE RN > B
在實際開發中,前臺只會發送一個要查詢的頁碼 而后再就是每頁顯示多少條
頁碼 :currentPage;
每頁顯示多少條 : pageSize;
頁碼 currentPage pageSize A B
1 1 5 5 0
2 2 5 10 5
3 3 5 15 10
以上: A=currentPagepageSize
B=(currentPage-1)pageSize分頁模板2
SELECT * FROM (SELECT ROWNUM RN, T.* FROM (SELECT * FROM 表名 [ WHERE 條件 ] [ ORDER BY ]) T) WHERE RN BETWEEN A AND B
頁碼 :currentPage;
每頁顯示多少條 : pageSize;
頁碼 currentPage pageSize A B
1 1 5 1 5
2 2 5 6 10
3 3 5 11 15
以上 A=(currentPage-1)pageSize+1
B=currentPagepageSize
-
以上的兩種主法哪一種好?
模板1的速度快,隨著頁碼越來越從,速度將接近于模板2
模板2的速度慢,因為是第二個子查詢把所有數據都查詢出來
分頁實例:分頁按照薪水高低顯示數據,每頁5條數據,顯示第2頁數據。
--1,按薪水高低排序
SELECT * FROM EMP ORDER BY SAL DESC
--2,以上的查詢結果為基礎 再查詢出前10條數據
SELECT ROWNUM RN,T.* FROM (SELECT * FROM EMP ORDER BY SAL DESC) T WHERE ROWNUM<=10;
--3,以上的的查詢結果上再套一層,查詢RN>5的數據
SELECT *
FROM (SELECT ROWNUM RN, T.*
FROM (SELECT * FROM EMP ORDER BY SAL DESC) T
WHERE ROWNUM <= 10)
WHERE RN > 5;
--4,第二種寫法
SELECT *
FROM (SELECT ROWNUM RN, T.* FROM (SELECT * FROM EMP ORDER BY SAL DESC) T)
WHERE RN BETWEEN 1 AND 5;
-
MySQL的分頁查詢:
語法
SELECT * FROM EMP LIMIT A,B;
第一頁
SELECT * FROM EMP LIMIT 0,5;
第二頁
select * from emp limit 5,10;
CURRENTPAGE:當前頁
A=(CURRENTPAGE-1)*PAGESIZE
B=PAGESIZE
4. 數據控制語言-DCL
因為MySQL和Oracle存儲方式有較大區別,所以它們管理用戶和權限的方式也有很大不同。
4.1 MySql的用戶權限管理
Mysql中的用戶,存儲在系統數據庫mysql中的user表中,表初始內容只有localhost-----root用戶。
MySql的用戶管理
創建用戶:
Create user ‘用戶名’@‘允許登錄的地址/服務器’indentified by ‘密碼’;
允許登錄的地址/服務器:允許該設定的位置,來使用設定的用戶名和密碼登錄,其他位置不可以。
如:
Create user ‘user1’@‘localhost’ indentifiedby ‘000’;
(只有本地用戶可以使用用戶名和密碼登錄)
Create user ‘user2’@‘192.168.40.37’ indentified by ‘000’;
(只有該地址192.168.40.37的用戶可以使用用戶名和密碼登錄)刪除用戶:
Drop user ‘用戶名’@‘允許登錄的地址/服務器’;
修改用戶密碼:
修改自己的密碼:set password=password('密碼');
修改他人的密碼(有權限的情況下):set password for '用戶名'@'允許登錄的地址/服務器'=password('密碼');
MySql的權限管理:
權限:mysql數據庫將其中所能做的所有操作都進行分類,分配到不同的權限(30多個),其中每個權限都用一個單詞表示。
如:select 表示查詢,delete表示刪除等,all表示所有權限
- 授予權限:
形式:
grant 權限列表 on 某庫.某個對象 to '用戶名'@'允許登錄的地址/服務器'
indentifiedby '密碼';
說明:
1.權限列表:就是多個權限的名詞,相互之間用逗號隔開。
2.某庫.某對象:表示給指定的某個數據庫的某個下級單位(表名、視圖名、存儲過程名,存儲函數名)授權;
特殊情況:
*.*
:代表所有數據中的所有下級單位
某庫.*
:代表指定的該庫中的所有下級單位
3.indentified by '密碼':可省略,表示授權的同時也可修改密碼。如果該用戶不存在,表示創建一個新用戶。
如:
Grant select on php39.* to ’user1‘@’localhost’;
- 剝奪權限:
形式:
revoke 權限列表 on 某庫.某個對象 from '用戶名'@'允許登錄的地址/服務器';
4.2 Oracle中的用戶權限管理
安裝完Oracle之后系統為開發者提供了一些用戶如SCOTT SYSTE SYS等用戶,但是這都是系統給的,能不能自己創建用戶呢?顯然是可以的。
Oarcle的數據是存在放到目錄下的oraldata目錄下的DBF文件里面,那么可以不可以創建自己的存放數據庫的DBF文件呢?顯然是可以。
Oracle的表空間管理
Oracle的權限控制主要是對表空間的權限控制,即將表賦給某個用戶。所以我們先學習如何創建Oracle的表空間
1,創建臨時表空間
create temporary tablespace erp_temp
tempfile 'D:\oracledata\erp_temp.dbf' DBF文件的位置自定義
size 50m 初始大小
autoextend on 大小自動增加
next 50m maxsize 20480m 每次增加的大小和最大空間
extent management local[本地管理]/dictionary[數據字典管理];
2,創建表空間
create tablespace erp_data
datafile 'D:\oracledata\erp_data.dbf'
size 50m
autoextend on
next 50m maxsize 20480m ;
3,修改表空間
語法: alter tablespace 舊名稱 rename to 新名稱;
alter tablespace newspace rename to myspace;
4,刪除表空間,并把包含的數據和約束刪除
語法:drop tablespace 表空間名 [including contents and datafiles];
drop tablespace ERP_TEMP including CONTENTS AND DATAFILES;
5,查看表空間
select * from v$tablespace;
Oracle的用戶管理
創建用戶
create user erp identified by erp 創建一個用戶名為erp密碼為erp的用戶
default tablespace erp_data 默認的數據存放的表空間
temporary tablespace erp_temp; 臨時的數據存放表空間刪除用戶
drop user erp;
Oracle的權限管理
添加權限
grant connect,resource,dba to erp;
取消權限
revoke connect,resource,dba from erp;
關于權限
權限指執行特定類型SQL 命令或訪問其他對象的權利
角色是具有名稱的一組權限的組合
常用系統預定義角色:
1.CONNECT:臨時用戶
2.RESOURCE:更為可靠和正式的用戶
3.DBA:數據庫管理員角色,擁有管理數據庫的最高權限開發中的注意點
在開發中,系統集成開發會用到其它系統要能查詢當前系統的表的功能,這時候一般是創建一個新的用戶給新用戶查詢的權限,而不會把當前系統的用戶給別人.
grant select any table to test(用戶名需要查詢表的用戶);
使用用戶test去訪問別的用戶下(如test2)的T表的時候
select * from test2.T(表名);
四、創建多表及多表關系
【外鍵約束】
多個表之間是有關系的,那么關系靠誰來維護?
多表約束:外鍵約束.
alter table product add foreign key (cno) references category(cid);
【多表的關系】
- 一對多關系:
客戶和訂單,分類和商品,部門和員工.
一對多建表原則:在多的一方創建一個字段,字段作為外鍵指向一的一方的主鍵. - 多對多關系:
學生和課程:
多對多關系建表原則:需要創建第三張表,中間表中至少兩個字段,這兩個字段分別作為外鍵指向各自一方的主鍵. - 一對一關系:
在實際的開發中應用不多.因為一對一可以創建成一張表.
兩種建表原則:
唯一外鍵對應:假設一對一是一個一對多的關系,在多的一方創建一個外鍵指向一的一方的主鍵,將外鍵設置為unique.
主鍵對應:讓一對一的雙方的主鍵進行建立關系.
1. 網上商城案例實體抽取和表關系建立
一對多的實現
###創建分類表(已存在)
create table category(
cid varchar(32) PRIMARY KEY ,
cname varchar(100) #分類名稱
);
# 商品表(已存在,刪除,重新創建)
CREATE TABLE `products` (
`pid` varchar(32) PRIMARY KEY ,
`name` VARCHAR(40) ,
`price` DOUBLE
);
#添加外鍵字段
alter table products add column category_id varchar(32);
#添加約束
alter table products add constraint product_fk foreign key (category_id) references category (cid);
多對多的實現
### 訂單表
create table `orders`(
`oid` varchar(32) PRIMARY KEY ,
`totalprice` double #總計
);
### 訂單項表
create table orderitem(
oid varchar(50),-- 訂單id
pid varchar(50)-- 商品id
);
### 聯合主鍵(可省略)
alter table `orderitem` add primary key (oid,pid);
###---- 訂單表和訂單項表的主外鍵關系
alter table `orderitem` add constraint orderitem_orders_fk foreign key (oid) references orders(oid);
###---- 商品表和訂單項表的主外鍵關系
alter table `orderitem` add constraint orderitem_product_fk foreign key (pid) references products(pid);
初始化數據
-- 給商品表初始化數據
insert into products(pid,name,price,category_id) values('p001','聯想',5000,'c001');
insert into products(pid,name,price,category_id) values('p002','海爾',3000,'c001');
insert into products(pid,name,price,category_id) values('p003','雷神',5000,'c001');
insert into products(pid,name,price,category_id) values('p004','JACK JONES',800,'c002');
insert into products(pid,name,price,category_id) values('p005','真維斯',200,'c002');
insert into products(pid,name,price,category_id) values('p006','花花公子',440,'c002');
insert into products(pid,name,price,category_id) values('p007','勁霸',2000,'c002');
insert into products(pid,name,price,category_id) values('p008','香奈兒',800,'c003');
insert into products(pid,name,price,category_id) values('p009','相宜本草',200,'c003');
insert into products(pid,name,price,category_id) values('p010','梅明子',200,null);
-- 給分類表初始化數據
insert into category values('c001','電器');
insert into category values('c002','服飾');
insert into category values('c003','化妝品');
insert into category values('c004','書籍');
2. 使用商城表關系完成多表的查詢
【多表查詢】
交叉連接查詢(基本不會使用-得到的是兩個表的乘積)
語法:
select * from A,B;-
內連接查詢(使用的關鍵字 inner join -- inner可以省略)
- 隱式內連接:
select * from A,B where 條件; - 顯示內連接:
select * from A inner join B on 條件;
- 隱式內連接:
-
外連接查詢(使用的關鍵字 outer join -- outer可以省略)
- 左外連接:left join
select * from A left join B on 條件; - 右外連接:right join
select * from A right join B on 條件;
- 左外連接:left join
我們以一對多為例來練習一下
初始化數據:
-- 用戶表(user)
create table `user` (
`id` int auto_increment primary key,
`username` varchar(50) -- 用戶姓名
);
-- 訂單表(orders)
create table `orders` (
`id` int auto_increment primary key,
`price` double,
`user_id` int
);
-- 給訂單表添加外鍵約束
alter table orders add constraint user_fk foreign key (user_id) references user(id);
-- 向user表中添加數據
insert into user values(3,'張三');
insert into user values(4,'李四');
insert into user values(5,'王五');
insert into user values(6,'趙六');
-- 向orders 表中插入數據
insert into orders values(1,1314,3);
insert into orders values(2,1314,3);
insert into orders values(3,15,4);
insert into orders values(4,315,5);
insert into orders values(5,1014,null);
【子查詢】
在sql語言中,當一個查詢是另一個查詢的條件時,稱之為子查詢
【分頁查詢】
分頁查詢每個數據庫的語句是不通用的.
MYSQL:使用limit的關鍵字.
select * from product limit a,b;
--a:從哪開始,b:查詢多少條.
Oracle:使用SQL語句嵌套.
SQLServer:使用top的關鍵字.